2023-01-03 Swarm使用

305 阅读9分钟

Swarm概述

Swarm是什么

官方解释:

当前版本的 Docker 包括用于本机管理集群的 swarm 模式 的 Docker 引擎称为。使用 Docker CLI 创建群,部署 向群提供应用程序服务,并管理群行为。Docker Swarm 模式内置于 Docker 引擎中。

如果把docker比作物理机的话,Swarm就是Openstack,可以控制管理多个节点上的docker服务,同时不会影响各个节点上的docker使用,同时能够使用Swarm方便的在各个docker节点上编排分布式的、非中心化、可扩展性的应用,方便用户跨多个节点使用docker的场景。如果只是单台docker环境,docker-compose会是更好的选择。

Swarm亮点(摘自官网)

  • 与 Docker 引擎集成的集群管理: 使用 Docker 引擎 CLI 以创建一组 Docker 引擎,您可以在其中部署应用程序 服务业。您无需额外的编排软件即可创建或管理 一群人。
  • 分散式设计: 而不是处理节点之间的区别 在部署时的角色,Docker 引擎处理任何专用化 运行。您可以部署两种类型的节点(管理器和工作器),使用 码头工人引擎。这意味着您可以从单个磁盘构建整个群 图像。
  • 声明式服务模型: Docker 引擎使用声明性方法来 允许您定义应用程序中各种服务的所需状态 叠。例如,您可以描述由 Web 前端组成的应用程序 具有消息队列服务和数据库后端的结束服务。
  • 缩放: 对于每个服务,您可以声明所需的任务数 跑。当您扩展或缩减时,群管理器会自动适应 添加或删除任务以保持所需状态。
  • 所需的状态协调: 群管理器节点持续监控 群集状态,并协调实际状态与实际状态之间的任何差异 表示所需状态。例如,如果将服务设置为运行 10 容器的副本,以及托管其中两个副本的工作计算机 崩溃时,管理器创建两个新副本来替换 坠毁。群管理器将新副本分配给工作线程: 正在运行且可用。
  • 多主机网络: 您可以为您的 服务业。群管理器自动为容器分配地址 在覆盖网络上初始化或更新应用程序时。
  • 服务发现: 群管理器节点为群中的每个服务分配 唯一的 DNS 名称和负载均衡正在运行的容器。您可以查询每个 容器通过嵌入在群中的 DNS 服务器在群中运行。
  • 负载均衡: 您可以将服务的端口公开给 外部负载均衡器。在内部,群允许您指定如何分发 节点之间的服务容器。
  • 默认安全: 群中的每个节点都强制执行 TLS 相互 身份验证和加密,以保护自身与所有人之间的通信 其他节点。您可以选择使用自签名根证书或 来自自定义根 CA 的证书。
  • 滚动更新: 在推出时,可以将服务更新应用于节点 增量。群管理器可让您控制服务之间的延迟 部署到不同的节点集。如果出现任何问题,您可以 回滚到服务的先前版本。

为什么选择Swarm

搭建大数据集群,严重依赖zk,kafka,redis等分布式集群组件,使用docker安装,可以在未来软件版本升级,后期环境迁移,其他环境部署提供很大便利。使用docker-compose只能控制单台节点的docker环境,不符合分布式集群部署的初衷,使用k8s会产生很大的维护和使用成本,所以在这里使用swarm来完成容器组件的部署

Swarm常用命令

docker集群的创建

# 集群初始化
# MANAGER-IP 只可以填ip地址,不能填主机名
docker swarm init --advertise-addr <MANAGER-IP>

image.png

# 查看集群信息
docker info

image.png

# 查看集群节点(以添加work节点)
docker node ls

image.png

docker节点加入

查看加入集群的命令(在完成集群初始化的节点操作)

docker swarm join-token worker

image.png

在需要加入集群的节点上执行命令

docker swarm join --token SWMTKN-1-0ktjfqedqx1q2u7sq1e0k3jrtvjbn9a3cbeyini07dy3qzom0s-cbrljhf78dxz0ja1fenijmi9n 192.168.20.101:2377

image.png

如果加入集群失败,需要检查网络问题和防火墙问题

集群管理

查看集群节点

docker node ls

检查单个节点

# docker node inspect <NODE-ID> --pretty
# --pretty 为可选参数,不带则以json方式输出

更改节点可用性

# usability-tag 包含 Active,Pause,Drain
# 
docker node update --availability <NODE-AVAILABILITY> <NODE-ID>

给节点添加标签(需要自行了解标签作用,脱离文章范围)

`docker node update --label-add``--label-add``<key>``<key>=<value>` <NODE-ID>

节点升降级

# 升级一个或一组节点
docker node promote <NODE-ID> <NODE-ID> ...
# 降级一个或一组节点
docker node demote <NODE-ID> <NODE-ID> ...

节点移除

# 需要登录到要移除的节点
docker swarm leave
# 节点离开后,从节点列表进行移除
docker node rm <NODE-ID>

overlay网络管理

docker network create --driver overlay my-network

服务管理

创建服务

docker service create ...
参数作用备注
--name服务名称
--env配置环境变量MYVAR=myvalue
--workdir容器的工作目录
--user指定用户名或UID
--replicas指定副本数与mode模式二选一
--modeglobal 每个节点运行一个容器,新增节点,自动创建与replicas二选一
--publish指定映射的端口published=8080,target=80
--network指定运行的overlay网络需要提前创建
--mount指定挂在的数据卷查看docker数据卷部分,不在范围内
--reserve-memory内存限制,不足任务挂起
--reserve-cpucpu限制,不足任务挂起
--constraint放置约束,只在包含标签的节点运行,可以设置多个--contraint node.labels.region==esat --containt node.labels.type!=devel
--placement-pref指定首选项,可以设置多个需要学习
--update-delay服务滚动更新时的延迟,单位T Ts Tm Th
--update-parallelism默认更新一次更新一个,此参数配置最大数量的任务同时更新
--update-failure-action默认当任务更新过程失败后会停止,通过配置continue,失败继续
--update-max-failure-ratio标志任务更新期间,如何判定任务失败--update-max-failure-ratio 0.1 --update-failure-action pause 表示10%的更新失败,则更新任务会暂停
--rollback-delay回滚任务后等待的时间,然后回滚下一个任务
--rollback-failure-action回滚失败后的操作pause,continue
--rollback-max-failure-ratio回滚期间允许的失败率,指定为0到1之间的浮点数
--rollback-monitor每个任务回滚后用于监视失败的持续时间。如果任务在此时间段之前停止,则认为回滚失败。
--rollback-parallelism要并行回滚的最大任务数

go模板占位符

占 位 符描述
.Service.ID 服务编号
.Service.Name服务名称
.Service.Labels服务标签
.Node.ID节点标识
.Node.Hostname节点主机名
.Task.Name任务名称
.Task.Slot任务槽
docker service create --name hosttempl \
                        --hostname="{{.Node.ID}}-{{.Service.Name}}"\
                         busybox top

更新服务

docker service update ...
参数作用备注
--args更新用户运行的命令--args ""
--publish-add添加开放的端口
--network-add将现有服务连接到overlay网络需要提前创建overlay网络
--network-rm将服务从overlay网络断开
--placement-pref-add添加首选项
--palcement-pref-rm移除首选项
--rollback任务回滚可以与--update-delay 一起使用

删除服务

docker service remove ...

查看服务

docker service ls

Swarm stack

常用命令

## 查看当前的服务
docker stack ls
## 删除
docker stack rm zookeeper-cluster
## 创建
docker stack deploy -c zookeeper-stack.yml zookeeper-cluster

Swarm应用

创建kafka集群

version: '3.1'

services:
  kafka1:
    image: bitnami/kafka:latest
    networks:
      - dep-network
    hostname: kafka1
    ports:
      - '9092:9092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zoo1:2181,zoo2:2181,zoo3:2181/kafka_cluster1
      - ALLOW_PLAINTEXT_LISTENER=yes
    volumes:
      - "kafka1data:/bitnami/kafka"

  kafka2:
    image: bitnami/kafka:latest
    networks:
      - dep-network
    hostname: kafka2
    ports:
      - '9093:9093'
    environment:
      - KAFKA_BROKER_ID=2
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9093
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9093
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zoo1:2181,zoo2:2181,zoo3:2181/kafka_cluster1
      - ALLOW_PLAINTEXT_LISTENER=yes
    volumes:
      - "kafka2data:/bitnami/kafka"

  kafka3:
    image: bitnami/kafka:latest
    networks:
      - dep-network
    hostname: kafka3
    ports:
      - '9094:9094'
    environment:
      - KAFKA_BROKER_ID=3
      - KAFKA_CFG_LISTENERS=PLAINTEXT://:9094
      - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9094
      - KAFKA_CFG_ZOOKEEPER_CONNECT=zoo1:2181,zoo2:2181,zoo3:2181/kafka_cluster1
      - ALLOW_PLAINTEXT_LISTENER=yes
    volumes:
      - "kafka3data:/bitnami/kafka"

volumes:
  kafka1data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/kafka/kafka1/data"
  kafka2data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/kafka/kafka2/data"
  kafka3data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/kafka/kafka3/data"

networks:
  dep-network:
    external: true

创建zookeeper集群

zookeeper-stack.yml

version: '3.1'

services:
  zoo1:
    image: zookeeper:latest
    networks:
      - dep-network
    hostname: zoo1
    ports:
      - 2181:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - "zoo1conf:/conf"
      - "zoo1data:/data"
      - "zoo1datalog:/datalog"
    deploy:
      mode: replicated
      replicas: 1

  zoo2:
    image: zookeeper:latest
    networks:
      - dep-network
    hostname: zoo2
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - "zoo2conf:/conf"
      - "zoo2data:/data"
      - "zoo2datalog:/datalog"
    deploy:
      mode: replicated
      replicas: 1

  zoo3:
    image: zookeeper:latest
    networks:
      - dep-network
    hostname: zoo3
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
    volumes:
      - "zoo3conf:/conf"
      - "zoo3data:/data"
      - "zoo3datalog:/datalog"
    deploy:
      mode: replicated
      replicas: 1

volumes:
  zoo1conf:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo1/conf"
  zoo1data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo1/data"
  zoo1datalog:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo1/datalog"
  zoo2conf:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo2/conf"
  zoo2data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo2/data"
  zoo2datalog:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo2/datalog"
  zoo3conf:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo3/conf"
  zoo3data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo3/data"
  zoo3datalog:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/zk/zoo3/datalog"

networks:
  dep-network:
    external: true

需要在nfs上创建出需要用到的卷路径

docker stack deploy -c zookeeper-stack.yml zookeeper-cluster

创建redis

version: '3.1'

services:
  redis:
    image: redis:4.0.1
    hostname: redis
    networks:
      - dep-network
    ports:
      - '6379:6379'
    volumes:
      - reidsdata:/data
      - redislog:/logs

volumes:
  reidsdata:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/redis/datadir"
  redisconf:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/redis/conf"
  redislog:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/redis/logs"

networks:
  dep-network:
    external: true

Mysql

version: '3.1'

services:
  mysql:
    image: mysql:5.7
    networks:
      - dep-network
    ports:
      - '3306:3306'
    hostname: mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - "mysqldata:/var/lib/mysql"

volumes:
  mysqldata:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/mysql/data"

networks:
  dep-network:
    external: true

es

version: '3.1'

services:
  elasticsearch01:
    image: elasticsearch:7.8.0
    hostname: elasticsearch
    environment:
      - node.name=elasticsearch
      - cluster.name=es-cluster
      - discovery.seed_hosts=elasticsearch,elasticsearch_02
      - cluster.initial_master_nodes=elasticsearch,elasticsearch_02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nproc: 65535
    volumes:
      - es01data:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - dep-network

  elasticsearch02:
    image: elasticsearch:7.8.0
    hostname: elasticsearch_02
    environment:
      - node.name=elasticsearch_02
      - cluster.name=es-cluster
      - discovery.seed_hosts=elasticsearch,elasticsearch_02
      - cluster.initial_master_nodes=elasticsearch,elasticsearch_02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nproc: 65535
    volumes:
      - es02data:/usr/share/elasticsearch/data
    networks:
      - dep-network


volumes:
  es01data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/es_cluster/es01/data"
  es02data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.20.103,rw,nfsvers=4,async"
      device: ":/nfs-storage/docker-cluster/es_cluster/es02/data"

networks:
  dep-network:
    external: true

QA

1、service创建失败查看原因

docker service ps --no-trunc <service-name>

2、nfs客户端也需要安装nfs-utils