用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
原文地址:https://www.cnblogs.com/yyee/p/13139107.html