一、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)构成。

docker swarm界面 docker swarm使用_容器

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

docker swarm界面 docker swarm使用_redis_02

三、实例部署测试

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容器和运维方面相关知识的,请前往博客主页查看。