用docker swarm搭建docker集群
前言 |
在项目中通常用高可用的方式部署多个web应用服务,如果web应用服务项目部署在IIS上面,通常用负载均衡指向多台IIS服务器来实现高可用;如果使用docker容器部署web应用服务项目,可以用k8s或者docker swarm来偏排容器,以容器集群的方式实现高可用。
本篇讲述用docker swarm来实现docker集群编排。
使用负载均衡 + IIS方式的缺点:
web应用节点不能动态扩容。
当web应用节点挂掉之后,需要额外写一个守护程序用来检测web应用是否处于运行状态, 如果web应用停止,由守护程序启动web应用。
部署成本高,要一台一台的部署web应用。
使用docker swarm编排docker集群的优势:
可以动态对web应用进行动态扩容。
由docker swarm来监控docker节点是否可用,如果docker节点出故障不可用,docker swarm会创建一新的docker节点来代替出故障的docker节点。
不需要到每一台服务器去部署web应用服务,用docker swarm的service命令一次性动态部署多个web应用服务。
docker swarm介绍 |
docker swarm 分为管理节点(manger node)、工作节点(work node)、服务(services),任务(Task)。
swarm可以包含一个或多个管理节点,一个或多个工作节点。
(1) 工作节点:运行docker的服务器。
工作节点接收管理节点的任务,并执行任务。
(2) 管理节点:
管理节点同时也是工作节点,维护集群的状态。 管理节点分为首领管理节点与非首领管理节点,首领管理节点只有一个,非首领管理节点可以有多个。
当首领管理节点不可用时,docker swarm会选举其中一个非首领管理节点为首领管理节点。当非首领管理节点接到命令时会将命令转交给首领管理节点,首领管理节点会把命令执行于整个swarm集群。
如果工作点都挂掉只剩下一个管理节点,docker swarm仍然可以保持集群和服务的运行。
管理节点建议用奇数个,最好3个或5个,一般不超过5个,因为swarm内部是通过RAFT协议达成共识状态,管理节点越多,越不容易达成共识。
(3) 服务:服务定义了swarm node上要执行的任务。
在管理节点上一行命令可以完成多个服务实例的创建,均衡的分配服务实例到工作节点。
swarm服务编排的主要功能是保证service在期望状态下运行,当某个工作节点或工作节点中运行的服务实例挂掉时,管理节点会在其它某个可用的工作节点(包含管理节点)中创建一个新的服务实例,并始终保持可用服务实例的数量。
(4) 任务:运行在docker里面的容器,swarm集群里运行的各个服务实例的容器就是任务,比如5个webapi容器也叫5个任务。
dokcer swarm常用命令 |
# 创建网络
docker network create -d overlay my-network
# 查看网络
docker network ls
# 创建并启动服务
docker service create image_name
docker service create -p 80:80 image_name
docker service create --replicas 5 image_name
docker service create --name your_service_name -p 8001:50001 --replicas 3 image_name
docker service create --name your_service_name --network my-network -p 8001:50001 --replicas 3 image-name
# 更新镜像到某个版本,同时并发更新2个副本,每轮更新完之后间隔30秒
docker service update --image 镜像名:版本号 --update-parallelism 2 --update-delay 30s 服务名
# 停止某个服务并删除
docker service rm your_service_name
# 查看已经在运行的服务
docker service ls
# 查看某个服务运行状态
docker service ps your_service_name
# 查看某个节点的运行状态
docker node ps 主机名
# 增加和删除DNS
docker service update --dns-add 131.10.23.63 your_service_name
docker service update --dns-rm 131.10.23.63 your_service_name
# 增加和删除端口映射
docker service update --publish-add 80:80 your_service_name
docker service update --publish-rm 80:80 your_service_name
# 缩容和扩容
docker service scale your_service_name=2
docker service scale your_service_name=5
docker service update --replicas 6 your_service_name
# 查看一个或多个节频数的详细信息
docker service inspect your_service_name
# 检查节点的可用性
docker node inspect --pretty node1
# 将节点设置为drain状态,禁止在某个节点上运行service
docker node update --availability drain node_name
# 启用被清空的节点
docker node update --availability active node_name
swarm集群搭建 |
第1步,准备工作
准备5台centos虚拟机,并在每台centos虚拟机上安装好docker,各虚拟机要能相互ping通与访问。
在其中一个虚拟机上安装docker私有仓库harbor,并上传一个业务镜像到harbor。
harbor安装教程:https://www.cnblogs.com/yyee/p/13121272.html
5台centos虚拟机的主机名与 IP分别为:
主机名:yyee-centos-2,IP:192.168.0.102
主机名:yyee-centos-3,IP:192.168.0.103
主机名:yyee-centos-4,IP:192.168.0.104
主机名:yyee-centos-5,IP:192.168.0.105
主机名:yyee-centos-6,IP:192.168.0.106
yyee-centos-1这台虚拟机用来做harbor服务器。
harbor服务器地址为:https//192.168.0.101
(上传到harbor的业务镜像 eshop/demo1.mvcone)
第2步,初始化swarm
用主机名为:yyee-centos-2,IP为:192.168.0.102 的这台服务器来作为swarm集群的首领节点。
切换到yyee-centos-2服务器,初始化swarm:
docker swarm init --advertise-addr 192.168.0.102:2377 --listen-addr 192.168.0.102:2377
--advertise-addr 表示不论这台机器有多少个ip,swarm使用192.168.0.102这个ip,2377端口是swarm默认用的端口。
--listen-addr 表示swarm工作点节的监听端口。
--advertise-addr跟--listen-addr两个参数一定要写。
执行初始化命令后,输出工作节点的token信息:
Swarm initialized: current node (ogyj7zoooxuwvvrqac71vrh6q) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-4tl00cn536nw7gs3xef8ehw8n 192.168.0.102:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
(这个是工作节点的token信息)
这段信息是说当前节点现在是管理节点,使用docker swarm join-token manager 命令将当前节点加入到swarm集群并为首领导节点。
现在将当前管理节点加入swarm:
docker swarm join-token manager
将当前管理节点加入swarm后自动成了首领节点,输出管理节点的 token信息:
To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-7wpqojsl3c6vgz2c137we4cf5 192.168.0.102:2377
(这个是管理节点的token信息)
对比两次生成的 token可以看出,加入 swarm管理节点与加入 swarm工作节点的 token是不同的。
区分其它工作节点是加入到swarm中的管理节点还是加入到swarm中的工作节点,是在执行docker swarm join --token命令的时候以token来分区的,--token参数后面跟管理节点的token就加入管理节点,--token参数后面跟工作节点的token就加入工作节点。
第3步,将其它虚拟机加入swarm集群
按顺序切换到yyee-centos-3到yyee-centos-6四台服务器,分别将这些节点加入到swarm管理节点或工作节点:
# 将yyee-centos-3加入管理节点 docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-7wpqojsl3c6vgz2c137we4cf5 192.168.0.102:2377 --advertise-addr 192.168.0.103:2377 --listen-addr 192.168.0.103:2377 # 将yyee-centos-4加入管理节点 docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-7wpqojsl3c6vgz2c137we4cf5 192.168.0.102:2377 --advertise-addr 192.168.0.104:2377 --listen-addr 192.168.0.104:2377 # 将yyee-centos-5加入工作节点 docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-4tl00cn536nw7gs3xef8ehw8n 192.168.0.102:2377 --advertise-addr 192.168.0.105:2377 --listen-addr 192.168.0.105:2377 # 将yyee-centos-6加入工作节点 docker swarm join --token SWMTKN-1-6aqpwmmhhzuo8tgvzn42aqww5woroccuhhli86q9en3b4yndt2-4tl00cn536nw7gs3xef8ehw8n 192.168.0.102:2377 --advertise-addr 192.168.0.106:2377 --listen-addr 192.168.0.106:2377
-- token 要加入的swarm管理节点token、ip、端口。
--advertise-addr 工作节点IP及口端。
--listen-add 工作节点的监听 ip及端口。
切换到某个管理节点(非管理节点不可以执行docker node ls命令),查看swarm集群中的节点列表:
docker node ls
ID后面跟*号的,表示当前是在哪个节点上执行的docker nodel ls命令。
从信息中看出,有一个首领节点,两个管理节点,两个工作节点。
如果出现错误:Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure ,需要关闭所有节点的防火墙或开放所有节点的2377端口。防火命令使用说明参考:https://www.cnblogs.com/yyee/p/13140188.html
# 关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service # 或者开放端口 firewall-cmd --zone=public --add-port=2376/tcp --permanent 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
如果出现错误:Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid ,因为集群时间不一致导致的。
解决办法:
1. 通过date命令查看各个主机的当前时间,发现时间不一致;
2. 需要在每个工作节点上同步时间;
3. 在manager节点(yyee-centos-1)上执行命令docker swarm leave --force 离开集群,然后docker swarm init重新初始化集群,然后worker节点加入集群,因为时间改变,证书失效,重新初始化生成证书。
在每个节点上执行:
yum -y install ntp ntpdate
ntpdate cn.pool.ntp.org
然后重新初始化swarm,重新将工作节点加入到swarm。
第4步,提升或降级管理节点
提升工作节点为管理节点: docker node promote 节点ID
降级管理节点为工作节点: docker node demote 节点ID
提升与降级管理节点需要在管理节点上执行命令:
# 提升工作节点为管理节点 docker node promote 节点ID docker node promote vz0u0ao6k3zxksivuv6kkgftj #将yyee-centos-5 提升为管理节点 # 降级管理节点为工作节点 docker node demote 节点ID docker node demote vz0u0ao6k3zxksivuv6kkgftj #将yyee-centos-5 降级为工作节点
到这里swarm集群就搭建好了。
创建服务 |
使用 docker service create 命令创建服务
# docker service create --name 服务名称 -p 对外端口:容器内部端口 --replicas 副本数量 镜像名 docker service create --name my-mvcone -p 8001:50001 --replicas 3 192.168.0.101:10080/eshop/demo1.mvcone:v1.0.1
--name 服务名称
--replicas 指定服务创建副本的个数。
192.168.0.101:10080/eshop/demo1.mvcone:v1.0.1 私有仓库ip:端口/项目名称/镜像名
服务创建完成输出 :
查看所有服务列表:
dokcer service ls
从服务列表信息看出,my-mvcone服务有三个副本。
查看服务状态:
docker service ps my-mvcone
从服务状态信息看出服务有三个实例在运行:
浏览服务运行结果:
服务扩容 |
给my-mvcone服务扩容到6个副本
docker service update --replicas 6 my-mvcone #或者用扩容别名命令 docker service scale my-mvcone=6
然后查看服务副本个数及服务状态
#查看服务副本个数
docker service ls
#查看服务状态
docker service ps my-mvcone
升级服务版本 |
当项目迭代升级,有新的版本发布的时候,需要将将 my-mvcone服务从旧版本升级到新版本。
执行服务更新命令,将my-mvcone服务从v1.0.1升级到v1.0.2:
# 更新镜像到某个版本,同时并发更新2个副本,每轮更新完之后间隔30秒 docker service update --image 192.168.0.101:10080/eshop/demo1.mvcone:v1.0.2 --update-parallelism 2 --update-delay 30s my-mvcone
升级到 v1.0.2版本之后:
服务升级完成,从v1.0.1升级到了v1.0.2 。
更新回滚 |
如果更新后效果不理想,可以通过 --rollback 快速恢复到更新之前的状态。
docker service update my_mveone --rollback
回滚加 --rollback参数。
退出swarm集群 |
将某个工作节点退出swarm集群。
docker swarm leave
或
docker swarm leave --force