一、Swarm简介
1、swarm介绍
Dockere Swarm是Docker公司推出的用来管理docker集群的编排工具,代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机,提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。,换言之,各种形式的DockerClient(compose,docker-py等)均可以直接与Swarm通信,甚至Docker本身都可以很容易的与Swarm集成,这大大方便了用户将原本基于单节点的系统移植到Swarm上,同时Swarm内置了对Docker网络插件的支持,用户也很容易的部署跨主机的容器集群服务。
从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,我们就不需要像之前一样,再配置 Etcd 或者 Consul 来进行服务发现配置了。而目前一般使用的docker版本都是高于这个版本的。
Swarm deamon相当于是一个调度器(Scheduler)加路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,选择合适的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,当Swarm重新恢复运行之后,他会收集重建集群信息。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
2、swarm原理
如下图所示,swarm 集群由管理节点(manager)和工作节点(work node)构成。
swarm mananger:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
work node:即上图中的 available node,主要负责运行manager节点调度来的服务。
service :应用编排
task : 应用实例
3、swarm的调度策略
swarm在调度节点运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:random、spread、binpack
1)Random(随机)
随机选择一个Node来运行容器,一般用作调试用,可能会使容器分配很不均匀。
2)Spread
Spread策略会选择运行容器最少的那台节点来运行新的容器,使容器比较均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
3)Binpack
Binpack策略最大化的避免容器碎片化,binpack策略会选择运行容器最集中的那台机器来运行新的容器。就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。
4、swarm模式的特性
1)容错性强
当集群中某个或某几个节点宕机后,cluster会根据自己的服务注册发现机制,以及之前设定的值–replicas,在集群中其他健康节点上,重新拉起容器副本。整个副本迁移的过程无需人工干预,迁移后原本的集群的load balance依旧好使,使集群恢复到预期的状态。(类似k8s的功能)
2)节点的可扩展性
Swarm Cluster不光只是提供了优秀的高可用性,同时也提供了副本弹性扩展或缩减的功能。当容器副本想改变时,只需通过scale参数即可很方便的达到预期。
注意区别:
复制服务(–replicas n)
将一系列复制任务分发至各节点当中,具体取决于您所需要的设置状态,例如“–replicas 3”,某个节点可能同时存在多个容器副本。(类似k8s中的deployment)
全局服务(–mode=global)
适用于集群内全部可用节点上都需要此服务的任务,例如“–mode global”。如果大家在 Swarm 集群中设有 10 台 Docker 节点,则全部节点之上都部署有该容器。(类似于k8s中的daemonset)
二、swarm集群部署
1、服务器规划
角色 | IP地址 |
---|---|
manager | 192.168.2.140 |
node1 | 192.168.2.141 |
node2 | 192.168.2.142 |
2、创建 swarm 集群管理节点(manager)
初始化 swarm 集群,在规划的manager节点进行初始化,就是集群的管理节点。
[root@k8s-m1 compose-test]# docker swarm init --advertise-addr 192.168.2.140
Swarm initialized: current node (hkhxn2djs9owibdx1gsq8s0fm) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1tce5hvvwrnf7enszpvjnc5kidxh9724o482vyu3tdhn55b7fs-7qi2xytdz15npxea9uz09on54 192.168.2.140:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
以上输出,证明已经初始化成功。需要把join的相关信息复制出来,在增加node节点时会用到,忘记了可以通过 docker swarm join-token worker
查看 。还可以添加多个管理节点,使用最后一行的docker swarm join-token manager
查看相关的添加命令。
#使用该输出结果添加进来的就是worker节点
[root@k8s-m1 compose-test]# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1tce5hvvwrnf7enszpvjnc5kidxh9724o482vyu3tdhn55b7fs-7qi2xytdz15npxea9uz09on54 192.168.2.140:2377
#使用该输出结果添加出来的就是manager节点
[root@k8s-m1 compose-test]# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1tce5hvvwrnf7enszpvjnc5kidxh9724o482vyu3tdhn55b7fs-3hw1dgxnswnmn2b0hom0eazoh 192.168.2.140:2377
#通过docker info 可以查看集群的相关信息
[root@k8s-m1 compose-test]# docker info
.....
Node Address: 192.168.2.140
Manager Addresses:
192.168.2.140:2377
192.168.2.141:2377
......
3、创建 swarm 集群工作节点(worker)
这里直接创建好俩台机器,node1 和 node2 。直接执行上一步的join行相关命令
[root@k8s-m2 ~]# docker swarm join --token SWMTKN-1-1tce5hvvwrnf7enszpvjnc5kidxh9724o482vyu3tdhn55b7fs-7qi2xytdz15npxea9uz09on54 192.168.2.140:2377
This node joined a swarm as a worker.
##删除节点,在相应的节点上执行
[root@k8s-m2 ~]# docker swarm leave
##将节点添加为 manager节点
[root@k8s-m2 ~]# docker swarm join --token SWMTKN-1-1tce5hvvwrnf7enszpvjnc5kidxh9724o482vyu3tdhn55b7fs-3hw1dgxnswnmn2b0hom0eazoh 192.168.2.140:2377
This node joined a swarm as a manager.
[root@k8s-m2 ~]#
以上数据输出说明已经添加成功。
4、查看集群信息
进入集群中的某一节点,执行:docker info 可以查看当前集群的信息。
[root@k8s-m1 compose-test]# docker info
#查看集群节点
[root@k8s-m1 compose-test]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
pmam1lvqtnej1u0iidnfit29d * k8s-m1 Ready Active Leader 19.03.9
lccgk1w1h85rmddn961rq6mqp k8s-m2 Ready Active 19.03.9
sim3mrvc776ats8oj7647xcmw k8s-m3 Ready Active 19.03.9
三、实例部署测试
1、部署服务到集群中
注意:跟集群管理有关的任何操作,都是在manager 节点上操作的。
以下例子,在一个工作节点上创建一个名为 pingtest 和redis的服务,这里是随机指派给一个工作节点:
[root@k8s-m1 ~]# docker service create --replicas 1 --name pingtest alpine ping www.baidu.com
[root@k8s-m1 ~]# docker service create -p 6379:6379 --replicas 1 --name redis redis
2、查看服务部署情况
查看 pingtest 服务运行在哪个节点上,可以看到目前是在 k8s-m1 节点:
[root@k8s-m1 ~]# docker service ps pingtest
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
9x9egswr0d09 pingtest.1 alpine:latest k8s-m1 Running Running 51 minutes ago
3、查看 pingtest 部署的具体信息
### --pretty 是格式化输出
[root@k8s-m1 ~]# docker service inspect pingtest --pretty
ID: v6euaefndeyatcq99sfovks5q
Name: pingtest
Service Mode: Replicated
Replicas: 1
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: alpine:latest@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300
Args: ping www.baidu.com
Init: false
Resources:
Endpoint Mode: vip
4、修改副本数
#修改副本数
[root@k8s-m1 ~]# docker service update --replicas 2 redis
redis
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
#查看所有服务
[root@k8s-m1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
v6euaefndeya pingtest replicated 1/1 alpine:latest
wdffmjjycyyg redis replicated 2/2 redis:latest *:6379->6379/tcp
5、部署global模式的服务
#先删除redis服务,创建一个global模式的服务
[root@k8s-m1 ~]# docker service rm redis
redis
[root@k8s-m1 ~]# docker service create -p 6379:6379 --mode=global --name redis redis
d745h87vfl04nbr5lbzl7qvvk
overall progress: 3 out of 3 tasks
sim3mrvc776a: running [==================================================>]
pmam1lvqtnej: running [==================================================>]
lccgk1w1h85r: running [==================================================>]
verify: Service converged
[root@k8s-m1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
v6euaefndeya pingtest replicated 1/1 alpine:latest
**加粗样式**d745h87vfl04 redis global 3/3 redis:latest *:6379->6379/tcp
[root@k8s-m1 ~]# docker service ps redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wbklclpklgq2 redis.lccgk1w1h85rmddn961rq6mqp redis:latest k8s-m2 Running Running 2 minutes ago
vp91pjp4wie4 redis.pmam1lvqtnej1u0iidnfit29d redis:latest k8s-m1 Running Running 2 minutes ago
lgfcacvhm248 redis.sim3mrvc776ats8oj7647xcmw redis:latest k8s-m3 Running Running 2 minutes ago
#可以看到mode模式为global模式的服务在每个节点都有部署
6、滚动升级服务
以下实例,我们将介绍服务版本如何滚动升级至其他版本。
#创建一服务
[root@k8s-m1 ~]# docker service create --replicas 1 --name alpine --update-delay 10s alpine:3.18 ping www.baidui.com
image alpine:3.18 could not be accessed on a registry to record
its digest. Each node will access alpine:3.18 independently,
possibly leading to different nodes running different
versions of the image.
pk13bmvzbcxbumzoihletj5sp
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
#查看
[root@k8s-m1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
pk13bmvzbcxb alpine replicated 1/1 alpine:3.18
ah72skm0q6jb pingtest replicated 1/1 alpine:latest
#升级
[root@k8s-m1 ~]# docker service update --image alpine alpine
alpine
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
#检查
[root@k8s-m1 ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
pk13bmvzbcxb alpine replicated 1/1 alpine:latest
ah72skm0q6jb pingtest replicated 1/1 alpine:latest
#版本已经发生变化,升级成功
#还可以重新回到原来的版本
[root@k8s-m1 ~]# docker service update --image alpine:3.18 alpine
[root@k8s-m1 ~]# docker service ps alpine
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zig8ku5v2xj1 alpine.1 alpine:3.18 k8s-m2 Running Running 25 seconds ago
tt06vxjyj0fe \_ alpine.1 alpine:latest k8s-m2 Shutdown Shutdown 57 seconds ago
bye27dklm8a4 \_ alpine.1 alpine:3.18 k8s-m2 Shutdown Shutdown 5 minutes ago
[root@k8s-m1 ~]#
7、停止某个节点接收新的任务
查看所有的节点:
[root@k8s-m1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
pmam1lvqtnej1u0iidnfit29d * k8s-m1 Ready Active Leader 19.03.9
lccgk1w1h85rmddn961rq6mqp k8s-m2 Ready Active 19.03.9
sim3mrvc776ats8oj7647xcmw k8s-m3 Ready Active 19.03.9
可以看到目前所有的节点都是 Active, 可以接收新的任务分配。
停止节点 k8s-m2:
[root@k8s-m1 ~]# docker node update k8s-m2 --availability drain
k8s-m2
[root@k8s-m1 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
pmam1lvqtnej1u0iidnfit29d * k8s-m1 Ready Active Leader 19.03.9
lccgk1w1h85rmddn961rq6mqp k8s-m2 Ready Drain 19.03.9
sim3mrvc776ats8oj7647xcmw k8s-m3 Ready Active 19.03.9
注意:k8s-m2状态变为 Drain。不会影响到集群的服务,只是k8s-m2节点不再接收新的任务,集群的负载能力有所下降。
可以通过以下命令重新激活节点:
[root@k8s-m1 ~]# docker node update k8s-m2 --availability active
关于docker swarm的更多命令可以通过自动补全或者-h进行查看测试。
更多关于docker容器和运维方面相关知识的,请前往博客主页查看。