主要内容
简介
swarm mode是Docker的集群模式。集群模式的好处是多台主机提供相同的服务,它们看起来像是一个整体,Docker对用户的网络请求自动分发到合适的节点上面,最大的好处是故障转义,负载均衡。
在Docker 1.12.0之前,swarm是一个独立的组件,但之后被集成到Docker中,无需另外安装。
swarm mode有以下好处:
- 集中管理 swarm mode包括manager节点和worker节点,所有的worker节点由manager节点统一管理,manager节点同时也是一个特殊的worker节点。
- 弹性伸缩 swarm mode可以根据集群的负载情况动态调整节点数量,合理利用资源
- 故障转义 某个节点出现故障,Docker会自动选择某个合适的节点启动新的服务
- 负载均衡 swarm默认自动分发流量,但也可以提供外部负载均衡方案
- 服务发现 swarm为每个服务提供一个唯一的DNS名称,可以通过这个名称访问容器
- 滚动更新 允许我们在不停止服务的情况下更新容器
相关概念
- Manager Node
manager node即管理节点,用于管理其他worker节点,一个swarm集群中可以有多个管理节点,多个管理节点会自动选举一个leader。
-
Worker Node
普通节点,不能在普通节点上执行相关的swarm管理命令
-
Service
一个service就是一个容器,service由manager node创建,运行于worker node上面
搭建swarm环境
创建manager节点
manager节点的创建非常简单,只需要一条命令
1 2 3 4 5 6 7 8 9 |
[root@centos7-server ~]# docker swarm init --advertise-addr 192.168.0.202 Swarm initialized: current node (w3z9p6tazlm1rs2vqdr6gkjlu) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-39yx4wmcq3rk8vglffhaukwjzq3w363kht6d1b19x0s8qm43k2-836hshp4t697mq4pfdikz6l37 192.168.0.202:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. |
命令执行完毕,显示当前节点是一个管理节点,且会提示应该如何添加worker节点:
1 2 |
docker swarm join --token SWMTKN-1-39yx4wmcq3rk8vglffhaukwjzq3w363kht6d1b19x0s8qm43k2-836hshp4t697mq4pfdikz6l37 192.168.0.202:2377 |
只要把这条命令复制到要加入到集群中的主机执行。如果以后忘记了这条命令,可以使用以下命令查询
1 2 3 4 5 |
[root@centos7-server ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-39yx4wmcq3rk8vglffhaukwjzq3w363kht6d1b19x0s8qm43k2-836hshp4t697mq4pfdikz6l37 192.168.0.222:2377 |
查看节点信息
使用docker node ls
命令检查节点状态
1 2 3 4 |
[root@centos7-server ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION w3z9p6tazlm1rs2vqdr6gkjlu * centos7-server Ready Active Leader 18.06.1-ce |
目前只有一个管理节点。
加入worker节点
在创建manager节点的时候,已经提示了如何加入worker节点,在剩下的主机中运行下面的命令
1 2 3 |
root@nas-share:~# docker swarm join --token SWMTKN-1-39yx4wmcq3rk8vglffhaukwjzq3w363kht6d1b19x0s8qm43k2-836hshp4t697mq4pfdikz6l37 192.168.0.202:2377 This node joined a swarm as a worker. |
再次检查节点信息
1 2 3 4 5 6 |
[root@centos7-server ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION u2iowk28ppo2m0k6in5kd3qmx * centos7-server Ready Active Leader 18.06.1-ce mb24ea1omq0n0gfae2f2jh9o1 centos74vm Ready Active 18.06.1-ce jxiii029kf5rc790dlctq7dgn nas-share Ready Active 18.06.1-ce |
所有的节点准备就绪
创建service
创建service就是创建容器,不同的是所有worker中的service都由manager节点负责管理。
使用docker service create创建service
1 2 3 4 5 6 7 |
[root@centos7-server ~]# docker service create --name webapp nginx tksphnexqyd3m4zdmvfzbxkcf overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged |
查看集群中的所有服务
1 2 3 4 |
[root@centos7-server ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS tksphnexqyd3 webapp replicated 1/1 nginx:latest |
查看服务的状态
1 2 3 4 |
[root@centos7-server ~]# docker service ps webapp ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS m296ri4ivrsn webapp.1 nginx:latest centos7-server Running Running about a minute ago |
集群管理
集群管理主要是对service的管理,包括service间的互相通讯、数据保存、故障转移等。
弹性伸缩
我们可以根据服务器的负载对service的数量进行调整,当service创建的时候,它默认只有一个副本,即REPLICAS等于1。
添加副本
使用service scale
命令添加和减少副本,只需要为service设置一个数字。
1 2 3 4 5 6 7 8 |
[root@centos7-server ~]# docker service scale webapp=3 webapp scaled to 3 overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged |
完成后查看service状态
1 2 3 4 5 6 7 8 9 |
[root@centos7-server ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS tksphnexqyd3 webapp replicated 3/3 nginx:latest [root@centos7-server ~]# docker service ps webapp ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS m296ri4ivrsn webapp.1 nginx:latest centos7-server Running Running 21 minutes ago k2v3xcdigpkx webapp.2 nginx:latest centos74vm Running Running 19 seconds ago otxllb94lhe6 webapp.3 nginx:latest nas-share Running Running 25 seconds ago |
REPLICAS现在等于3,三个service分布在不同的服务器上面,manager节点也是一个worker节点,因此它也会被安排运行service。如果希望排除某个节点,可以使用下面的命令
1 2 3 |
[root@centos7-server ~]# docker node update --availability drain centos7-server centos7-server |
那么问题来了,当节点被排除之后,它上面的service会如何处理呢?使用docker service ps查看一下:
1 2 3 4 5 6 7 |
[root@centos7-server ~]# docker service ps webapp ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS krj6uevtfo9u webapp.1 nginx:latest nas-share Running Running 21 seconds ago m296ri4ivrsn \_ webapp.1 nginx:latest centos7-server Shutdown Shutdown 22 seconds ago k2v3xcdigpkx webapp.2 nginx:latest centos74vm Running Running 4 minutes ago otxllb94lhe6 webapp.3 nginx:latest nas-share Running Running 4 minutes ago |
很明显,节点上原本的service被shutdown,迁移到其他节点上面运行,例子中的service被迁移到nas-share节点上面。
减少副本
当负载不高的情况下,我们决定减少service的数量,只需要设置一个比原先小的数目即可。
1 2 3 4 5 6 7 |
[root@centos7-server ~]# docker service scale webapp=2 webapp scaled to 2 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged |
再次检查service状态
1 2 3 4 5 6 |
[root@centos7-server ~]# docker service ps webapp ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS krj6uevtfo9u webapp.1 nginx:latest nas-share Running Running 4 minutes ago m296ri4ivrsn \_ webapp.1 nginx:latest centos7-server Shutdown Shutdown 4 minutes ago k2v3xcdigpkx webapp.2 nginx:latest centos74vm Running Running 8 minutes ago |
其中一个节点上的service被移除了。
使用update进行弹性伸缩
它们的原理一样,只不过使用的是不一样的命令
1 2 3 4 5 6 7 8 9 |
[root@centos7-server ~]# docker service update --replicas 1 webapp webapp overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged [root@centos7-server ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS tksphnexqyd3 webapp replicated 1/1 nginx:latest |
故障转移
swarm内置了故障转移策略,一般不需要人工干预。现在我们关闭其中一个节点观察转移的过程
1 2 |
[root@centos74vm ~]# ip link set enp2s0 down |
查看service情况
1 2 3 4 5 6 7 |
[root@centos7-server ~]# docker service ps webapp ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS krj6uevtfo9u webapp.1 nginx:latest nas-share Running Running 12 minutes ago m296ri4ivrsn \_ webapp.1 nginx:latest centos7-server Shutdown Shutdown 12 minutes ago lm6yi4pcn6uo webapp.2 nginx:latest nas-share Running Running 1 second ago k2v3xcdigpkx \_ webapp.2 nginx:latest centos74vm Shutdown Running 15 minutes ago |
原先centos74vm上的webapp.2标记为shutdown。由于我们关闭了centos74vm节点,centos7-server被我们drain掉,所以service只能迁移到nas-share这个唯一可用的节点上面。
滚动更新
滚动更新保证我们在更新期间可以继续对外提供服务。滚动更新的原理是分批更新,更新期间由等待更新的service继续提供服务。同样地,swarm的滚动更新无需人工干预,但我们可以设置更新参数。
先移除原先的service,重新部署5个副本的webserver。
1 2 3 |
[root@centos7-server ~]# docker service rm webapp [root@centos7-server ~]# docker service create --name webserver --replicas 5 nginx:1.14 |
检查它们的状态
1 2 3 4 5 6 7 8 |
[root@centos7-server ~]# docker service ps webserver ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 2z5on51sv8kg webserver.1 nginx:1.14 centos74vm Running Running 48 seconds ago etzehkdmddzw webserver.2 nginx:1.14 centos74vm Running Running 42 seconds ago kw0dru2z808d webserver.3 nginx:1.14 nas-share Running Running 59 seconds ago uk1vg1d7hxxj webserver.4 nginx:1.14 centos74vm Running Running 48 seconds ago qcmyahmbmont webserver.5 nginx:1.14 nas-share Running Running 59 seconds ago |
使用docker service update
命令,把service的镜像更新到1.15版本
1 2 |
[root@centos7-server ~]# docker service update --image nginx:1.15 webserver |
在service更新的过程中,我们可以新开一个终端观察它们的情况
1 2 3 4 5 6 7 8 9 |
[root@centos7-server ~]# docker service ps webserver ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS q8p6nd2bmvdn webserver.1 nginx:1.14 nas-share Running Running about a minute ago 8m20x05wzk4o webserver.2 nginx:1.14 centos74vm Running Running about a minute ago l3um8oze9tmc webserver.3 nginx:1.14 nas-share Running Running about a minute ago 7egdrhpvion3 webserver.4 nginx:1.15 nas-share Running Starting less than a second ago cueraywezqlg \_ webserver.4 nginx:1.14 centos74vm Shutdown Shutdown less than a second ago p5pjrzy2mqpg webserver.5 nginx:1.14 centos74vm Running Running about a minute ago |
可以清晰见到它们并不是同时更新,而是一个个进行更新,因此等待中的service可以继续对外提供服务。
Swarm 将按照如下步骤执行滚动更新:
- 停止第一个准备更新的副本。
- 根据负载情况选择 worker node。
- 在选择的worker 上用新的镜像启动副本。
- 如果副本(容器)运行成功,继续更新下一个副本;如果失败,暂停整个更新过程。
默认情况下,swarm每次更新一个副本,且副本间的更新时间间隔为0,即更新成功一个副本马上更新下一个。可以通过参数控制这些行为,它们是
- –update-parallelism 每次更新多少副本
- –update-delay 副本间的更新时间间隔
1 2 |
docker service update --replicas 3 --update-parallelism 2 --update-delay 1m30s webserver |
副本从5个减少到3个,每次更新2个部分,间隔为1分30秒。
可以使用docker service inspect
命令查看相关设置
回滚更新
如果更新有问题,可以回滚到上一个版
1 2 |
[root@centos7-server ~]# docker service update --rollback webserver |
也可以通过下面的命令进行回滚
1 2 |
[root@centos7-server ~]# docker service rollback webserver |
限制每个节点运行一个副本
swarm默认会根据节点的负载情况进行service的部署,一个节点可能会运行一个或多个service,这是swarm的运行模式replicated
决定的,可以使用docker service inspect命令查看目前使用的模式。可以改变这个模式,让每个节点只能运行一个副本,也就是global
模式。
1 2 |
[root@centos7-server ~]# docker service create --mode global --name webserver |
查看运行情况
1 2 3 4 5 |
[root@centos7-server ~]# docker service ps webserver ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS bswrz4cc9ogg webserver.jxiii029kf5rc790dlctq7dgn nginx:latest nas-share Running Running 15 seconds ago tv4jkam5z1bu webserver.mb24ea1omq0n0gfae2f2jh9o1 nginx:latest centos74vm Running Running 16 seconds ago |
约束service的运行位置
除了可以限制每个节点运行一个service,还可以指定service在某个特定节点运行,使用label
即可。
- 首先为每个节点使用label打上印记
- 然后设置service运行在指定label的node
lable实际上是一个键值对,可以任意指定它们的值,有意义即可。例如:
指定开发机:
1 2 |
docker node update --label-add env=test nas-share |
指定生产机:
1 2 |
docker node update --label-add env=prod centos74vm |
然后部署service时指定label即可
1 2 3 4 5 6 |
docker service create \ --constraint node.labels.env==test \ --replicas 3 \ --name webserver \ nginx |
约束的添加和移除
1 2 3 |
docker service update --constraint-rm node.labels.env==test webserver docker service update --constraint-add node.labels.env==prod webserver |
转载请注明:Pure nonsense » Docker集群(docker swarm)