swarm简介:
Swarm 是 Docker 公司在 2014 年 12 月初发布的一套用来管理 Docker 集群的工具,将多个 Docker 宿主机变成一个单一的虚拟的主机。Swarm 使用标准的 Docker API 接口作为其前端访问入口,与Docker Client 直接通信。
工作原理:
Docker 客户端通过 Docker API 向 Swarm 管理端发送请求,Swarm Manager 通过守护进程调用集群中的某个节点来执行任务。因为容器都是运行在节点上,Swarm
作为一个独立的集群管理工具,故并不会因某些原因导致不能正常工作而影响集群内所有节点的正常运行。当服务恢复正常后,Swarm会读取日志来执行集群的恢复动作。
架构:
![]()
***Docker Client 是用户端
***Swarm Manager 作为管理程序运行在一台管理节点上,这个节点在 Swarm 集群中承担 leader 角色。
***Swarm Node 01,02,N 是 Swarm 集群的其他成员,和 Swarm Manager 管理节点一起组成完整的 Swarm 集群,每一个节点都会运行 Swarm 容器。
***Docker Daemon 是运行于每一个成员内的守护进程,承担着调度器和路由器的功能。
***Discovery service 提供服务发现功能。
集群搭建
实验环境:linux 7.3
实验主机:
server1:172.25.17.1
server2:172.25.17.2
server3:172.25.17.3
1.将server1作为leader端,首先需要在server1端准备docker镜像swarm并加入docker仓库:
[root@server1 mnt]# docker load -i swarm.tar
51d7ab1945b2: Loading layer [==================================================>] 17.83 MB/17.83 MB
556db563f19a: Loading layer [==================================================>] 280.6 kB/280.6 kB
e80f64357437: Loading layer [==================================================>] 2.048 kB/2.048 kB
5f70bf18a086: Loading layer [==================================================>] 1.024 kB/1.024 kB
Loaded image: swarm:latest
在server1端创建swarm集群,先要进行swarm的初始化,在初始化的结果中会指明其他节点加入本集群的具体方法:
[root@server1 mnt]# docker swarm init
Swarm initialized: current node (mtieasakcwbaktqeups4528ot) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-4xdsbmvrgkd1190w85rq1hxkcf3eelpi0cba15jig8g3gofruv-73dokex4kkwpikacatc5p3wc2 \
172.25.17.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
将上面结果的这一段代码复制到server2和server3端,就可以将servre2和server3加入到swarm集群中:
将server2加入集群:
[root@server2 docker]# docker swarm join \
> --token SWMTKN-1-4xdsbmvrgkd1190w85rq1hxkcf3eelpi0cba15jig8g3gofruv-73dokex4kkwpikacatc5p3wc2 \
> 172.25.17.1:2377
This node joined a swarm as a worker.
同样将server3加入集群:
[root@server3 ~]# docker swarm join \
> --token SWMTKN-1-4xdsbmvrgkd1190w85rq1hxkcf3eelpi0cba15jig8g3gofruv-73dokex4kkwpikacatc5p3wc2 \
> 172.25.17.1:2377
This node joined a swarm as a worker.
加入集群之后在server1中可以查看到集群状态,其中server1为leader:
[root@server1 mnt]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
bfix2u0ahdlfyawnak66iwowc server2 Ready Active
mtieasakcwbaktqeups4528ot * server1 Ready Active Leader
nc7eqtmt7ga3mxw9ri96q2jst server3 Ready Active
2.向swarm集群中部署服务,以nginx为例:
要在集群中部署服务,需要在每个节点的docker仓库都有服务镜像。以nginx为例,需要在server1、server2、server3三个节点都有nginx镜像。解决这个问题的方法有两种:
1.在有外部网络的情况下,可以直接在官网下载镜像之后导入到docker仓库,或者使用阿里云镜像加速器,这样镜像下载会更快。具体操作参考之前博客:阿里云镜像加速器使用
2.在没有外部网络或者使用的虚拟机没有配置网络连接的情况下,在物理机端搭建本地仓库(物理机端需要有nginx镜像),并设定其他主机通过5000端口访问物理机使用仓库中的镜像。具体操作参考之前博客:docker搭建本地仓库和使用
本文使用以上第2中本地仓库共享镜像的方式:
创建服务,将3个节点都加入集群:
[root@server1 docker]# docker service create --name nginx --publish 80:80 --replicas 3 westos.org:5000/nginx
rnj5tjgwu057ff4vtcl4249o9
加入成功之后可以看到三个节点服务都开启:
[root@server1 docker]# docker service ls
ID NAME MODE REPLICAS IMAGE
rnj5tjgwu057 nginx replicated 3/3 westos.org:5000/nginx
查看服务状态:
[root@server1 docker]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ihdz5586t3se nginx.1 westos.org:5000/nginx server1 Running Running about a minute ago
kklhg9476kz8 nginx.2 westos.org:5000/nginx server2 Running Running about a minute ago
icoj36m8yef9 nginx.3 westos.org:5000/nginx server3 Running Running about a minute ago
将nginx服务数量设定为6个:
[root@server1 docker]# docker service scale nginx=6
查看服务状态,每个节点上只运行两个nginx服务,实现服务的均衡分配:
[root@server1 docker]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ihdz5586t3se nginx.1 westos.org:5000/nginx server1 Running Running 8 minutes ago
kklhg9476kz8 nginx.2 westos.org:5000/nginx server2 Running Running 8 minutes ago
icoj36m8yef9 nginx.3 westos.org:5000/nginx server3 Running Running 8 minutes ago
ts4u17h7uoie nginx.4 westos.org:5000/nginx server1 Running Running 10 seconds ago
tk4afrjc4kg7 nginx.5 westos.org:5000/nginx server2 Running Running 8 seconds ago
pzz5egk1dxey nginx.6 westos.org:5000/nginx server3 Running Running 8 seconds ago
当然在每个服务端的nginx服务都可以被访问到:

使用visualizer工具监控集群的负载均衡
1.由于本文使用本地仓库共享镜像的方式,所以先将visualizer镜像包导入到物理机的docker仓库:
[root@foundation17 docker]# docker load -i visualizer.tar
5bef08742407: Loading layer 4.221 MB/4.221 MB
5f70bf18a086: Loading layer 1.024 kB/1.024 kB
0a19bde117a5: Loading layer 60.01 MB/60.01 MB
f7e883283ebc: Loading layer 3.942 MB/3.942 MB
dfd8ee95c7e7: Loading layer 1.536 kB/1.536 kB
300a6cad969a: Loading layer 8.704 kB/8.704 kB
d1627040da6d: Loading layer 489 kB/489 kB
00ed018016c5: Loading layer 2.56 kB/2.56 kB
d5aa1ab1b431: Loading layer 4.096 kB/4.096 kB
2d6a463420f7: Loading layer 4.608 kB/4.608 kB
53888d7f4cca: Loading layer 2.56 kB/2.56 kB
ea93ed99abca: Loading layer 2.598 MB/2.598 MB
fa467b43abc0: Loading layer 4.096 kB/4.096 kB
94cd25765710: Loading layer 96.48 MB/96.48 MB
Loaded image: dockersamples/visualizer:latest
成功导入:

然后将visualizer推送到本地仓库,以供swarm集群节点使用:
[root@foundation17 docker]# docker tag dockersamples/visualizer westos.org:5000/visualizer
[root@foundation17 docker]# docker push westos.org:5000/visualizer
The push refers to a repository [westos.org:5000/visualizer]
5f70bf18a086: Image successfully pushed
94cd25765710: Image successfully pushed
fa467b43abc0: Image successfully pushed
ea93ed99abca: Image successfully pushed
53888d7f4cca: Image successfully pushed
2d6a463420f7: Image successfully pushed
d5aa1ab1b431: Image successfully pushed
00ed018016c5: Image successfully pushed
d1627040da6d: Image successfully pushed
300a6cad969a: Image successfully pushed
dfd8ee95c7e7: Image successfully pushed
f7e883283ebc: Image successfully pushed
0a19bde117a5: Image successfully pushed
5bef08742407: Image successfully pushed
Pushing tag for rev [17e55a9b2354] on {http://westos.org:5000/v1/repositories/visualizer/tags/latest}
2.创建服务:
[root@server1 docker]# docker service create \
> --name=viz \
> --publish=8080:8080/tcp \
> --constraint=node.role==manager \
> --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
> westos.org:5000/visualizer
zhuazelhgj1rshtrue478a5xq
这个服务开启较慢,查看服务状态为1/1时表示服务开启成功了:
[root@server1 docker]# docker service ls
ID NAME MODE REPLICAS IMAGE
rnj5tjgwu057 nginx replicated 6/6 westos.org:5000/nginx
zhuazelhgj1r viz replicated 0/1 westos.org:5000/visualizer
[root@server1 docker]# docker service ls
ID NAME MODE REPLICAS IMAGE
rnj5tjgwu057 nginx replicated 6/6 westos.org:5000/nginx
zhuazelhgj1r viz replicated 1/1 westos.org:5000/visualizer
3.为了便于负载均衡效果的查看,重新将nginx服务改为3个:
[root@server1 docker]# docker service scale nginx=3
nginx scaled to 3
[root@server1 docker]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ts4u17h7uoie nginx.4 westos.org:5000/nginx server1 Running Running 30 minutes ago
tk4afrjc4kg7 nginx.5 westos.org:5000/nginx server2 Running Running 30 minutes ago
pzz5egk1dxey nginx.6 westos.org:5000/nginx server3 Running Running 30 minutes ago
查看每个节点的开启的服务,每个节点的nginx服务都会有唯一的NAMES,以server1为例:
[root@server1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7001d892af7 westos.org:5000/visualizer:latest "npm start" 7 minutes ago Up 7 minutes (healthy) 8080/tcp viz.1.hxnj1vrztkdiscwcwv5anuv3g
25d49133fd76 westos.org:5000/nginx:latest "nginx -g 'daemon ..." 32 minutes ago Up 32 minutes 80/tcp nginx.4.ts4u17h7uoie7346tzzfw98zd
这个NAMES就代表了server1主机上的nginx服务,为了负载均衡的效果查看,在每个节点端都将默认发布文件复制到nginx的默认发布目录:
server1端:
[root@server1 ~]# echo server1 > index.html
[root@server1 ~]# docker container cp index.html nginx.4.ts4u17h7uoie7346tzzfw98zd:/usr/share/nginx/html
server2端:
[root@server2 ~]# echo server2 > index.html
[root@server2 ~]# docker container cp index.html nginx.5.tk4afrjc4kg71iqrnih0fehzm:/usr/share/nginx/html
server3端:
[root@server3 ~]# echo server3 > index.html
[root@server3 ~]# docker container cp index.html nginx.6.pzz5egk1dxeyibb3qfuyzrts4:/usr/share/nginx/html
4.测试:
在server1端进行9次对swarm leader的解析,实现负载均衡:
[root@server1 ~]# for i in {1..10};do curl 172.25.17.1;done
server2
server1
server3
server2
server1
server3
server2
server1
server3
server2
在浏览器中访问swarm leader端的8080端口,可以看到一个visualizer服务和三个nginx服务:

服务的滚动更新
如果要更新nginx服务的版本,可以采用滚动更新的方式。
在物理机端将新的nginx镜像推送到本地仓库:
[root@foundation17 ~]# docker tag rhel7:v1 westos.org:5000/rhel7:v1
[root@foundation17 ~]# docker push westos.org:5000/rhel7:v1
在server1端进行更新:
[root@server1 ~]# docker service scale nginx=30 #为了效果将服务个数设定为30个
[root@server1 ~]# docker service update --image westos.org/rhel7:v1 --update-parallelism 3 --update-delay 10s nginx #每次更新三个,更新延迟为10s
之后就可以在浏览器中看到服务的动态更新,或者可以docker service ps nginx查看
3万+

被折叠的 条评论
为什么被折叠?



