Swarm 是 Docker 公司在 2014 年 12 月初发布的一套较为简单的工具,用来管理 Docker 集群,它将一群 Docker 宿主机变成 一个单一的,虚拟的主机。Swarm 使用标准的 Docker API接口作为其前端访问入口。
换言之,各种形式的 Docker Client(docker client in go,docker_py,docker 等)均可以直接与 Swarm 通信。Swarm 几乎全部用 Go 语言来完成开发。Swarmdeamon 只是一个调度器(Scheduler)加路由器(router),Swarm 自己不运行容器,它只是接受 docker 客户端发送过来的请求,调度适合的节点来运行容器,这意味着,即使Swarm 由于某些原因挂掉了,集群中的节点也会照常运行,当 Swarm 重新恢复 运行之后,它会收集重建集群信息。
一、实验环境
- RHEL7.3
- firewalld、selinux都为disabled
- server1(manager) 172.25.70.1
- server2(node) 172.25.70.2
- server3(node) 172.25.70.3
- vits(client) 172.25.70.250
二、使实验环境纯净(没有正在运行的容器)
1、server1-3先安装docker服务。
2、清理正在运行的容器 - docker1
- docker2
- docker3
二、Docker Swarm集群的搭建部署
1、在管理节点的server1上,初始化swarm集群
[root@docker1 ~]# docker swarm init
在server1节点上查看桥接信息
[root@docker1 ~]# brctl show
在server1节点上查看docker的网络信息
[root@docker1 ~]# docker network ls
2、server2,server3(work节点)加入集群
[root@docker2 ~]# docker swarm join --token SWMTKN-1-22orditrldquxn5oav8pa010i5ko3b7cwij10n9hn0gy6qmcz6-1clgkdrlmokqrvnwdvigm3a95 172.25.70.1:2377
==================================================
[root@docker3 ~]# docker swarm join --token SWMTKN-1-22orditrldquxn5oav8pa010i5ko3b7cwij10n9hn0gy6qmcz6-1clgkdrlmokqrvnwdvigm3a95 172.25.70.1:2377
- docker2
- docker3
在server1(manager节点)查看节点信息
[root@docker1 ~]# docker node ls
三、使用swarm集群,部署web服务
1、三个节点都要导入nginx镜像
[root@docker1 ~]# docker images
================================
[root@docker2 ~]# docker load -i nginx.tar
[root@docker2 ~]# docker images
======================================
[root@docker3 ~]# docker load -i nginx.tar
[root@docker3 ~]# docker images
- docker1
- docker2
- docker3
2、在集群上部署了三个Nginx容器,用来提供服务
#创建驱动为overlay的网络
[root@docker1 ~]# docker network create -d overlay webnet
sa49fosqntucc6ru6ml246ttp
[root@docker1 ~]# docker service create --name web \
> --network webnet \
#–replicas 3就是代表集群的个数变为3。manager会将容器平均分配到三个节点上
> --replicas 3 \
#或-publish 80:80或-publish=80:80/tcp
> -p 80:80 \
#创建一个名称为web,副本为3,开放端口为80的nginx容器
> nginx
#这里使用的是自己创建的驱动为overlay的网络(值的一提的是:如果这里指定网络,则必须是驱动为overlay的网络)。当然也可以不加--network webnet,使用默认的网络。只是使用自己的网络,可能出现的问题会比较少。
查看80端口
[root@docker1 ~]# netstat -antlp
查看docker服务列表
[root@docker1 ~]# docker service ls
查看docker集群的web服务列表
[root@docker1 ~]# docker service ps web
2、三个节点都要操作:从容器中复制文件到容器nginx默认发布目录
- docker1
[root@docker1 ~]# vim index.html
[root@docker1 ~]# cat index.html
docker1
[root@docker1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bf96fae2716 nginx:latest "nginx -g 'daemon of…" 5 minutes ago Up 5 minutes 80/tcp web.3.wakph39kuar3ni10wa6mgo6yw
[root@docker1 ~]# docker cp index.html web.3.wakph39kuar3ni10wa6mgo6yw:/usr/share/nginx/html
- docker2
[root@docker2 ~]# vim index.html
[root@docker2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b72c74090510 nginx:latest "nginx -g 'daemon of…" 6 minutes ago Up 6 minutes 80/tcp web.1.72cjhnfb21exc1caz2vhz8m6t
[root@docker2 ~]# docker cp index.html web.1.72cjhnfb21exc1caz2vhz8m6t:/usr/share/nginx/html
- docker3
[root@docker3 ~]# vim index.html
[root@docker3 ~]# cat index.html
docker3
[root@docker3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b3407ebbad1a nginx:latest "nginx -g 'daemon of…" 8 minutes ago Up 7 minutes 80/tcp web.2.vwbydpm9pucpmos3lbiuf3t1l
[root@docker3 ~]# docker cp index.html web.2.vwbydpm9pucpmos3lbiuf3t1l:/usr/share/nginx/html
3、在物理机上测试(负载均衡)
[root@vits ~]# for i in {1..10}; do curl 172.25.70.1/index.html;done
- 1
- 2
- 3
四、容器拉伸以及缩减(增加或减少服务数目)
1.拉伸(增加scale的数目)
[root@docker1 ~]# docker service scale web=6
[root@docker1 ~]# docker ps
查看每个主机上正在运行的容器个数
[root@docker1 ~]# docker ps
- docker1
- docker2
- docker3
查看docker集群的web服务列表
[root@docker1 ~]# docker service ps web
2、测试
[root@vits ~]# for i in {1..10}; do curl 172.25.70.2/index.html;done
我们可以看到六个容器都可以访问。
2.减少scale的数目
[root@docker1 ~]# docker service scale web=3
[root@docker1 ~]# docker service ps web
测试:
[root@vits ~]# for i in {1..10}; do curl 172.25.70.3/index.html;done
五、监控
首先,在网上下载visualizer.tar
1.在docker1上,导入visualizer镜像
[root@docker1 ~]# docker load -i visualizer.tar
查看容器:
[root@docker1 ~]# docker images
2、创建swarm的监控容器
[root@docker1 ~]# 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 \
> dockersamples/visualizer
查看运行viz的容器
[root@docker1 ~]# docker ps
查看8080端口
[root@docker1 ~]# netstat -antlp | grep 8080
3、测试:web页面去监控管理的集群每个容器的状态
172.25.70.1:8080
当server3的docker服务关闭后,web从server3转移到别的节点
[root@docker3 ~]# systemctl stop docker.service
值的一提的是:即使server3的docker服务重新启动,web也不会从server2重新移回到server3。除非执行增加服务或减少服务的操作,使Docker swarm集群重新分配节点的数目
当增加服务的数目时,Docker swarm集群会自动分配每个节点的web数目,并展示到监控界面
[root@docker3 ~]# systemctl start docker
========================================
[root@docker1 ~]# docker service scale web=12
六、滚动更新(灰度更新)
1、导入要更新镜像
(这里以httpd镜像为例。值的注意的是:滚动更新用的镜像和之前的镜像必须是平行的,即结构类似,比如端口等等——因为上篇博文中创建web服务时用到了80端口,所以滚动更新使用的镜像中也必须是80端口)
[root@docker1 ~]# docker load -i httpd.tar
============================================
[root@docker2 ~]# docker load -i httpd.tar
============================================
[root@docker3 ~]# docker load -i httpd.tar
2、增加web服务数目为30
[root@docker1 ~]# docker service scale web=30
看到的镜像是nginx:latest(滚动更新之前)
3、设定每5秒更新一次,每次更新5个
[root@docker1 ~]# docker service update --image httpd --update-delay 5s --update-parallelism 5 web
看到的镜像是httpd:latest(滚动更新之后)