被遗忘的 Docker Swarm

836 阅读5分钟

公众号名片 作者名片

Docker Swarm 简介

Docker Swarm 是 Docker 官方推出的基于 Go 语言实现的容器集群管理平台,极大方便了我们管理 Docker 主机、网络、存储。 一个 Swarm 群包括一个或多个 Docker 主机,这里的 Docker 主机可以是物理机、虚拟机、云主机等其他运行 Docker 环境的操作系统。

核心概念

Init

在 Docker 安装的时候已经集成了 Swarm 集群能力,我们只需要一行命令开启它

docker swarm init

Node

Node 表示的是 Swarm 集群中的一个节点,是一个大的调度单元,由集群管理者统一管理,在 Swarm 集群中我们可以执行以下命令查看节点信息

docker node ls

Manager

Swarm 集群的管理者角色,一个集群中至少有一个 manager 它负责集群资源分配、任务调度,它也可以被自己获取其他 manager 调度,一个节点被加入集群的时候我们可以指定 它的身份,可以通过以下命令查看加入集群 manager 角色的命令 \

Worker

Swarm 集群中只能被调度的工作节点,worker 节点仅负责运行任务,可以通过以下命令查看加入集群 worker 角色的命令 \

Service

Service 服务是 Swarm 集群中的最小执行单元,它具有资源限制、弹性伸缩、滚动升级和简单会滚的能力,我们的应用均以 service 定义并运行在集群中

Config

config 配置管理,用于定义存储我们的配置,例如应用启动需要的配置,可以使用以下命令创建我们的配置

echo "application.name=demo" | docker application.properties -

Secret

secret 密钥管理,考虑到配置安全,一些明感信息我们可以选择密钥存储,类似于 config 的使用方式

echo "123456" | docker mysql.password -

docker-compose

了解的 swarm 集群的基本概念,下面我们将学习如何使用 docker-compose 语法来编写我们的应用。这里仅做学习使用,redis、mysql 等存储监控组件均已单机版运行。

version: "3.2" #compose版本号
services:
  redis: #服务名称
    image: redis #镜像地址
    logging: # 日志设置
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    command: --requirepass 123456 # 服务启动时执行的命令
    deploy:
      mode: global #指定服务模式为集群唯一
      placement:
        constraints: [node.labels.node == manager] #指定运行节点为 manager
  nacos:
    image: nacos/nacos-server
    depends_on: #指定服务启动顺序,nacos依赖 mysql
      - mysql 
    environment: #环境变量
      - MODE=standalone
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_PORT=3306
      - MYSQL_SERVICE_DB_NAME=nacos_config
      - MYSQL_SERVICE_USER=root
      - MYSQL_SERVICE_PASSWORD=123456
    deploy:
      mode: global
      placement:
        constraints: [node.labels.node == manager]
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    ports:
      - "8848:8848"
  sentinel:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/sentinel
    deploy:
      mode: global
      placement:
        constraints: [node.labels.node == manager] 
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    ports:
      - "8858:8858"
  mysql:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/mysql:2021-04-10
    environment:
      - MYSQL_ROOT_PASSWORD=123456
    volumes:
      - mysql:/var/lib/mysql
    command:
      --default-time_zone='+8:00'
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
    deploy:
      mode: global
      placement:
        constraints: [node.labels.node == manager]
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
  order-center:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/order-center:2020-12-04-18-09-19
    restart: always
    depends_on:
      - mysql
      - nacos
      - redis
    deploy:
      replicas: 2 #运行实例数量
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    environment:
      - SERVER_PORT=80
      - MYSQL_SERVER=jdbc:mysql://mysql:3306/order_center?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      - MYSQL_USER_NAME=root
      - MYSQL_ROOT_PASSWORD=123456
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=123456
      - NACOS_SERVER=nacos:8848
      - LOG_LEVEL=INFO
    healthcheck: #监控检查
      test: ["CMD","curl","-f", "http://127.0.0.1/doc.html"] #检查命令
      interval: 5s #检查周期
      timeout: 5s #单次检查超时时间
      retries: 100 #最大检查次数
  user-center:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/user-center:2020-12-04-18-09-19
    restart: always
    environment:
      - SERVER_PORT=80
      - MYSQL_SERVER=jdbc:mysql://mysql:3306/user_center?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      - MYSQL_USER_NAME=root
      - MYSQL_ROOT_PASSWORD=123456
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=123456
      - NACOS_SERVER=nacos:8848
      - LOG_LEVEL=INFO
    depends_on:
      - mysql
      - nacos
      - redis
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    healthcheck:
      test: ["CMD","curl","-f", "http://127.0.0.1/doc.html"]
      interval: 5s
      timeout: 5s
      retries: 100
  api-gateway:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/api-gateway:2020-12-04-18-09-19
    restart: always
    environment:
      - SERVER_PORT=80
      - USER_CENTER_SERVER=lb://user-center
      - ORDER_CENTER_SERVER=lb://order-center
      - NACOS_SERVER=nacos:8848
      - SENTINEL_SERVER=sentinel:8858
      - LOG_LEVEL=INFO
    depends_on:
      - user-center
      - order-center
      - nacos
      - sentinel
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    healthcheck:
      test: ["CMD","curl","-f", "http://127.0.0.1/doc.html"]
      interval: 5s
      timeout: 5s
      retries: 100
  nginx:
    image: registry.cn-hangzhou.aliyuncs.com/yaochengzhu/nginx:api-gateway
    restart: always
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - api-gateway
    logging:
      driver: "json-file"
      options:
        max-size: "100m"
        max-file: "3"
    healthcheck:
      test: ["CMD","curl","-f", "http://127.0.0.1/doc.html"]
      interval: 5s
      timeout: 5s
      retries: 100
volumes: #创建数据卷
  mysql:

将上述文件保存为 docker-compose.yaml 在文件所在目录执行 docker-compose up 即可启动服务。但在实际使用中,我们可能会有多个环境,为了更加便于管理 我们通常使用 docker stack 来隔离我们的服务。

docker stack deploy --compose-file=demo-compose.yaml demo #在demo环境运行我们的服务

查看我们的服务 \

Portainer可视化管理

通过前面对 swarm 集群的了解以后,我们需要更加方便的管理集群,这里我为大家推荐 portainer 容器管理工具,此后我们所有的操作基本上都会在 portainer 提供的 UI 界面上完成。

安装 portainer

在 swarm 集群中安装

version: '3.2'
services:
  agent:
    image: portainer/agent:2.11.1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
    networks:
      - agent_network
    deploy:
      mode: global
      placement:
        constraints: [node.platform.os == linux]

  portainer:
    image: portainer/portainer-ce:2.11.1
    command: -H tcp://tasks.agent:9001 --tlsskipverify
    ports:
      - "9443:9443"
      - "9000:9000"
      - "8000:8000"
    volumes:
      - portainer_data:/data
    networks:
      - agent_network
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]

networks:
  agent_network:
    driver: overlay #跨主机网络
    attachable: true
volumes:
  portainer_data:

执行安装命令

docker stack deploy --compose-file=portainer.yaml portainer_demo

等待安装成功以后,浏览器ip:9000访问 portainer 初始化界面并设置密码 \

登录进去以后呢就是这样子 \

针对常用的几个功能我标注了一下,大家有兴趣可以深入了解下。 \

我们看下前面运行的 demo 效果 \

添加域名解析访问接口地址 \

总结

到这里相信大家对 docker swarm 有了一定的了解,相对于 k8s 集群 swarm 显得瘦小了许多,swarm 集群适合企业规模不大、应用不是很复杂的场景。 阿里云在 2019 年 12 月 31 日下线了 swarm 集群,从此 swarm 跌落云端,k8s 日渐火爆起来。我们在选择技术的时候不仅仅是需要考虑技术本身的优越性 也需要考虑适用性,毕竟最合适的才是最好的,也许你可以试试 swarm + portainer 或者 swarm + rancher。

参考资料

[1] docker: www.docker.com/

[2] swarm: docs.docker.com/engine/refe…

[3] portainer: www.portainer.io/

更多精彩请关注我们的公众号「百瓶技术」,有不定期福利呦!