Docker Swarm 集群操作实践
本文的在线结构图原件:https://www.processon.com/view/link/67d256069f5ea80eed0e2238?cid=67cfe66db9334c1c9a12a087
-
docker swarm
解决多主机多个容器调度部署问题
-
主要特点
- docker的集群化管理
- 使用Docker Engine CLI 创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务
- 去中心化设计
- Swarm角色分为Manager和Worker节点,Manager节点故障不影响应用使用。
- 扩容缩容
- 可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态。
- 多主机网络
- 可以为服务指定overlay网络。但初始化或更新应用程序时,Swarm manager会自动为overlay网络上的容器分配IP地址。
- 服务发现
- Swarm manager节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过Swarm内置的DNS服务器查询集群中每个运行的容器。
- 负载均衡
- 实现服务副本负载均衡,提供入口访问。
- 安全传输
- Swarm中的每个节点使用TLS相互验证和加密,确保安全的其他节点通信
- 滚动更新
- 升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到向前版本。
- docker的集群化管理
-
节点
-
管理节点
(建议标记污点,不调度容器)
- manage1
- manage2
- manage3
-
工作节点
- worker1
- worker2
- worker3
-
-
安装部署
- 前提条件
- 所有管理节点和工作节点全部安装完成docker版本1.12+
- 集群节点之间保证端口开放:
1、TCP 2377 (集群管理端口)
2、TCP/UDP 7946 (节点间通信端口)
3、UDP 4789 (Overlay网络端口) - # 如果是配置防火墙来放开2377/tcp,7946/udp,4789/udp端口,可以参考下面命令:
$ firewall-cmd --zone=public --add-port=2377/tcp --permanent
$ firewall-cmd --zone=public --add-port=7946/tcp --permanent
$ firewall-cmd --zone=public --add-port=7946/udp --permanent
$ firewall-cmd --zone=public --add-port=4789/udp --permanent
# 重新加载生效
$ firewall-cmd --reload
# 查看
$ firewall-cmd --list-ports - 必须要确保各个节点时间同步,否则可能会出现相关错误,时间同步建议提前为服务器配置好 chrony 或 ntp 。
- 集群部署
- 初始化集群
- 初始化 swarm 集群,进行初始化的这台机器,就是集群的第一个管理节点。
- docker swarm init --advertise-addr 192.168.99.107
- 参数 --advertise-addr 选项表示管理节点公布它的IP是多少,其它节点必须能通过这个IP找到管理节点。
- 命令执行后输出的内容是其他节点加入swarm 集群的命令。
- 添加节点加入集群
- 查看加入工作节点的命令
- docker swarm join-token worker
- 添加工作节点
- docker swarm join --token SWMTKN-1-4oogo9qziq768dma0uh3j0z0m5twlm10iynvz7ixza96k6jh9p-ajkb6w7qd06y1e33yrgko64sk 192.168.99.107:2377
- 这里的token是命令是初始化集群时候输出的,后面的IP地址是管理节点的IP地址,使用命令 docker swarm join-token worker 获取加入命令后整体复制在普通节点上执行即可。
- 查看加入管理节点的命令
- docker swarm join-token manager
- 添加管理节点
- 加入管理节点和加入工作节点的命令格式是一样的,区别是Token不同,请 docker swarm join-token manager 查看加入管理节点的命令Token。
- 查看加入工作节点的命令
- 查看当前集群信息
- docker info
- 输出的内容查看 Swarm 短的信息,观察 Active 状态和节点数量等信息。
- 初始化集群
- 前提条件
-
节点管理
-
查看节点信息
- docker node ls
- 1、输出的 nodeId 旁边显示 * 号的表示你当前连接到的节点
2、自动使用宿主机的主机名作为节点名 - AVAILABILITY 的三种状态:
1、Active:调度器能够安排任务到该节点
2、Pause:调度器不能够安排任务到该节点,但是已经存在的任务会继续运行
3、Drain:调度器不能够安排任务到该节点,而且会停止已存在的任务,并将这些任务分配到其他 Active 状态的节点 - MANAGER STATUS 的三种状态:
1、Leader:为群体做出所有群管理和编排决策的主要管理者节点
2、Reachable:如果 Leader 节点变为不可用,该节点有资格被选举为新的 Leader
3、Unavailable:该节点不能和其他 Manager 节点产生任何联系,这种情况下,应该添加一个新的 Manager 节点到集群,或者将一个 Worker 节点提升为 Manager 节点
- 1、输出的 nodeId 旁边显示 * 号的表示你当前连接到的节点
- docker node ls
-
为节点设置label
- 通过节点的标签,可以对节点进行分组。用于在部署service的时候,可以定向调度到具有某个或某些标签的node上。
- 在管理节点上操作,为节点添加label
- 语法:
docker node update --label-add = - 示例:
docker node update --label-add env=dev node-04
- 语法:
- 在管理节点上操作,为节点删除label
- 语法:
docker node update --label-rm - 示例:
docker node update --label-rm env node-04
- 语法:
- 查看节点的label
- 示例:
docker node inspect node-04 --format ‘{{ .Spec.Labels }}’
- 示例:
-
节点的升级和降级
- 将工作节点升级为管理节点
- docker node promote node1
- 将管理节点降级为工作节点
- docker node demote node1
- 将工作节点升级为管理节点
-
改变节点的可用性
(节点的上下线)
- 停止某个节点接收新的任务
- docker node update --availability drain worker1
- swarm 的节点状态设置为 Drain。不会影响到集群的服务,只是设定的节点不再接收新的任务。
- 重新激活节点可以接收任务
- docker node update --availability active worker1
- 上下线节点后查看确认节点状态
- docker node ls
- 停止某个节点接收新的任务
-
-
服务管理
docker service
- 创建部署服务
- 默认调度部署
- docker service create --replicas=1 --name=dev-portainer --publish=80:80 traefik/whoami:latest
- 其中 traefik/whoami 是一个可以返回服务的hostname和基本网络信息的轻镜像,用来测试使用。
参数 --replicas:表示期望1个服务实例
参数 --name:表示创建服务的名称
参数 --publish:表示映射的端口,–publish=80:80 可以简写为 -p 80:80
- 基于节点label的定向部署
- 通过参数 --constraint 设置目标节点
- docker service create --name test_service --constraint ‘node.labels.env == dev’ my-test-image:latest
- 默认调度部署
- 查看服务部署情况
- 查看指定服务部署的具体信息
- docker service inspect --pretty helloword
- 参数 --pretty:表示以 yaml 格式显示,不加此参数将以 json 格式显示
- 查看指定服务运行在哪个节点上
- docker service ps helloworld
- 查看指定服务部署的具体信息
- 扩展集群服务
- docker service scale helloworld=2
- 将 helloworld 服务扩展到俩个实例,也可以减少,只需要修改实例数字即可。
- 注意:如果实例数减少,swarm只是会停止多余的示例容器,而不会将停止的容器从所在主机上删除。
- 更新服务
- 对已存在服务新增暴露端口:
docker service update --publish-add published=8080,target=80 mynginx - 查看端口暴露情况:
docker service inspect --format=“{{json .Endpoint.Spec.Ports}}” dev-nginx
[{“Protocol”:“tcp”,“TargetPort”:80,“PublishedPort”:8080,“PublishMode”:“ingress”}]
- 对已存在服务新增暴露端口:
- 删除服务
- docker service rm helloworld
- 查看服务的日志
- docker service logs helloworld
- 滚动升级服务
- docker service update --image redis:3.0.7 redis
- 调度器 scheduler 依照以下步骤来滚动更新:
1、停止第一个任务
2、对停止的任务进行更新
3、对更新的任务进行启动
4、如果更新的任务返回RUNNING,等待特定间隔后启动下一个任务
5、如果在任何更新的时间,任务返回了FAILED,则停止更新 - 可以指定相应参数来制定滚动更新策略:
1、参数 --update-delay:配置更新服务的时间间隔,可以指定时间T为秒是Ts,分是Tm,或时是Th,所以10m30s就是10分30秒的延迟
2、默认的调度器 scheduler 一次更新一个任务,使用参数 --update-parallelism 来配置调度器同时更新的最大任务数量
3、默认情况下,当一个更新任务返回RUNNING状态后,调度器才调度另一个更新任务,直到所有任务都更新了。如果更新过程中任何任务返回了FAILED,调度器就会停止更新。可以在创建服务时给 docker service create 命令或者创建服务后给命令 docker service update 添加参数配置 --update-failure-action,来设置这个行为 - 更新指令后,不会删除升级之前版本的服务,而是停止它,并且新创建一个新的版本的服务
- 回滚服务
- docker service update --rollback redis
- 注意:滚动回滚的原理和滚动更新类似,并不会删除回滚前的服务,它只是停止服务,也不会重启升级之前版本的服务,而是直接再创建一个回滚版本的服务
- 创建部署服务
-
(END)