当前位置: 首页 > 工具软件 > Swarm > 使用案例 >

swarm(1)

凌善
2023-12-01

        从主机的层面来看,DockerSwarm管理的是DockerHost集群。所以先来讨论一个重要的概念-集群化(Clustering)。
服务器集群由一组网络上相互连接的服务器组成,它们一起协同工作。一个集群和一堆服务器最显著的区别在于:集群能够像单个系统那样工作,同时提供高可用、负载均衡和并行处理。

        如果我们部署应用和服务时选择的是多个独立的服务器而非集群,资源的整体利用率则很难达到最优,因为我们无法提前知道如何分布这些应用才能达到资源利用的最大化。而且,应用使用资源的趋势是波动的,早上某些服务可能需要大量的内存,而下午使用量就降下来了。提前指定应用应该运行在哪个服务器上会丧失业务的弹性,当某个服务器宕机了,我们不得不手工将受影响的应用迁移到其他服务器上。
 

      实现集群化后我们的思维方式就必须改变了:不再考虑一个一个的服务器,而是将集群看做是一个整体。

       部署应用时,我们只考虑需要多少内存和CPU而不是考虑会使用那台服务器的内存和CPU。我们不应该关心应用会被部署在哪里,我们关心的是运行这个应用需要哪些资源,然后将它部署到集群,集群管理程序(比如DockerSwarm)会搞定这些细节。

        集群整体容量的调整是通过往集群中添加和删除主机节点实现的。但不管做怎样的操作,集群始终还是一个整体。

        我们会创建Docker Swarm集群、部署应用、伸缩扩展应用,以及对应用执行滚动升级。
 

Docker Swarm Mode

        Dockerv1.12是一个非常重要的版本,Docker重新实现了集群的编排方式。在此之前,提供集群功能的DockerSwarm是一个单独的软件,而且依赖外部数据库(比如Consul、etcd或Zookeeper)。从v112开始,DockerSwarm的功能已经完全与DockerEngine集成,要管理集群,只需要启动 Swarm Mode。安装好DockerSwarm就已经在那里了,服务发现也在那里了(不需要安装Consul等外部数据库)。
相比Kubernetes,用DockerSwarm创建集群非常简单,不需要额外安装任何软件,也不需要做任何额外的配置。很适合作为学习容器编排引擎的起点。

重要概念

在创建集群之前,先明确几个概念。

 swarm

 swarm运行DockerEngine的多个主机组成的集群。
从V112开始,集群管理和编排功能已经集成进DockerEngine。当DockerEngine初始化了一个 swarm或者加入到一个存在的swarm时,它就启动了swarm mode。
没启动swarmmode时,Docker执行的是容器命令;运行swarmmode后,Docker增加了编排 service 的能力。
 Docker允许在同一个Docker主机上既运行swarm service又运行单独的容器。

node

    

       swarm中的每个DockerEngine都是一个node,有两种类型的node:manager 和 worker.
       为了向swarm中部署应用,我们需要在manager node 上执行部署命令,manager node会将部署任务拆解并分配给一个或多个worker node 完成部署。
      managernode负责执行编排和集群管理工作,保持并维护swarm处于期望的状态。swarm中如果有多个 manager node,它们会自动协商并选举出一个 leader 执行编排任务。

     woker node接受并执行由manager node派发的任务。默认配置下manager node 同时也是一个

     worknode会定期向managernode报告自己的状态和它正在执行的任务的状态,这样manager就可以维护整个集群的状态。

 service

        service定义了worker node上要执行的任务。swarm的主要编排任务就是保证service处于期望的状态下。
       举一个service的例子:在swarm中启动一个http服务,使用的镜像是 httpdlatest,副本数为 3。 manager node 负责创建这个 service,经过分析知道需要启动3个 httpd 容器,根据当前各 worker node的状态将运行容器的任务分配下去,比如worker1上运行两个容器,worker2 上运行一个容器。运行了一段时间,worker2突然宕机了,manager监控到这个故障,于是立即在worker3上启动了一个新的httod 容器,这样就保证了service处于期望的三个副本状态。

实践 Docker Swarm。
创建三节点的swarm集群。
角色  p

 swarm-manager 192.168.56.10
 swarm-worker1 192.168.56.20
 swarm-worker2 192.168.56.30

#cat  /etc/hosts
192.168.56.10  swarm-manager
192.168.56.20  swarm-worker1
192.168.56.30  swarm-worker2

关闭SElinux,firewalld添加端口

# firewal1-cmd --add-port=2377/tcp--permanent
# firewal1-cmd --add-port=7946/tcp--permanent
# firewall-cmd --add-port=7946/udp --permanent
# firewall-cmd--add-port=4789/udp--permanent
# firewal1-cmd --add-port=4789/tcp--permanent
 firewal1-cmd--reload

        swarm-manager是managernode,swarm-worker1和swarm-worker2是worker node。所有节点的Docker版本均不低于v1.12。
在swarm-manager上执行如下命令创建swarm。

 docker swarm init --advertise-addr192.168.56.101

# docker swarm init --advertise-addr 192.168.56.10
 Swarm initialized: current node (j6p2rf6fpcw416tkn2pa0jji0)is now a manager.

 To add a worker to this swarm, run the following command:

 docker swarm join--token SWMTKN-1-3g9tuoub2w34i8ysnmcnz3xa97bvgz8qrhd6wgenyrg650jii3-0hs8wh8h13i31ryowb73ndnx41921685610:2377

 To add a manager to this swarm, run 'docker swarm join-token manager'and follow the instructions.

 -advertise-addr 指定与其他 node 通信的地址。 docker swarm init 输出告诉我们:

1.swarm创建成功,swarm-manager成为manager node。2.添加 worker node 需要执行的命令。
3.添加manager node需要执行的命令。
执行 docker nodels 查看当前swarm的 node,目前只有一个manager。

# docker node ls
 ID                                               HOSTNAME            STATUS            AVAILABILITY                 ENGINE                      VERSION
 j6p2rf6fpcw416tkn2ps0jji0*                                          Ready             Active                                swarm-manager          Leader 19.03.2

复制前面的docker swarmjoin命令,在swarm-worker1和swarm-worker2 上执行,将它们添加到 swarm 中。命令输出如下:

#docker swarm join--token SWMTKN-1-
3g9tuoub2w34i8ysnmcnz3xa97bvgz8qrhd6wgenyrg650jii3-0hs8wh8h13i31ryowb73ndnx4192.168.56.10:2377

 docker nodels可以看到两个worker node已经添加进来了。

 docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION j6p2rf6fpcw4l6tkn2ps0jji0 *   swarm-manager       Ready               Active              Leader              19.03.2 g6z8cbpxend7tu55asz2q9f3z     swarm-worker1       Ready               Active                                  19.03.2 raa8bbtyukqqdk3pa0vfvhtwp     swarm-worker2       Ready               Active                                  19.03.2

如果当时没有记录下docker swarm init 提示的添加worker的完整命令,可以通过 docker swarm join-token worker 查看。
注意:此命令只能在manager node 上执行。

在swarm中部署第一个service。
创建好了Swarm集群现在部署一个运行httpd镜像的service执行如下命令。(-p 可以暴露端口,让容器外可以访问)

 docker service create --name web server httpd

部署service的命令形式与运行容器的dockerrun很相似,-name为service命名,httpd为镜像的名字。

 [root@swarm-manager ~]# docker service create --name web_server httpd

r6b1gole12n3t351zijsoxxz9
 overall progress: 1out of 1 tasks
1/1:running    [==================================================>]

verify:Service converged

通过docker servicels可以查看当前swarm 中的service。

[root@swarm-manager -]# docker service ls

ID                       NAME                    MODE                        REPLICAS                  IMAGE                    PORTS
r6blgole12n3     web_server                                               replicated 1/1               httpd:latest

 REPLICAS显示当前副本信息0/1的意思是web_server这个service期望的容器副本数量为1,目前已经启动的副本数量为0。也就是当前service还没有部署完成。命令docker serviceps可以查看 service 每个副本的状态。

可以看到service唯一的副本被分派到swarm-worker1,当前的状态是Preparing,还没达到期望的状态Running,我们不仅要问,这个副本在Preparing什么呢?
其实答案很简单swarm-worker1是在pull镜像,下载完成后,副本就会处于Running状态了。 service的运行副本数也正常了。

[rootlswarm-manager-]# docker service ps web_server ID  NAME  IMAGE  NODE
 DESIRED STATE  CURRENT STATE  ERROR
 PORTS
 kmphjjmtlpgk  web_server.1  httpd:latest
 swarm-manager
 Running  Running 3 minutes ago

如何实现service伸缩
上一节部署了只有一个副本的Service不过对于web服务,我们通常会运行多个实例。这样可以负载均衡,同时也能提供高可用。
 swarm要实现这个目标非常简单,增加service的副本数就可以了。在swarm-manager上执行如下命令:
 docker service scale web_server=5

[rooteswarm-manager ~]# docker service scale web_server=5 web server scaled to 5
 overall progress:5 out of 5 tasks
1/5: running   [==================================================>]

2/5: running   [==================================================>]

3/5: running   [==================================================>]

4/5: running   [==================================================>]

5/5: running   [==================================================>]
 verify:Service converged

副本数增加到5,通过docker servicels和docker serviceps查看副本的详细信息。

[rooteswarm-manager ~]# docker service ls
 ID                                NAME                                 MODE                                 REPLICAS               IMAGE                PORTS
 r6blqole12n3             web_server                        replicated                                      5/5                   httpd:latest
[rootlswarm-manager~1# docker service ps web_server

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                ERROR               PORTS kmphjjmt1pqk        web_server.1        httpd:latest        swarm-manager       Running             Running 43 minutes ago                           tipv42u0c72y        web_server.2        httpd:latest        swarm-manager       Running             Running about a minute ago                       2zlyk1i44elq        web_server.3        httpd:latest        swarm-worker1       Running             Running about a minute ago                       ji4nls51y9sv        web_server.4        httpd:latest        swarm-worker2       Running             Running about a minute ago                       de79sh71mqm7        web_server.5        httpd:latest        swarm-worker2       Running             Running about a minute ago

5个副本已经分布再swarm的所有节点上。

默人配置下 manager node 也是worker node,所以swarm-manager上也运行了副本。如果不希望在manager上运行service,也可以执行如下命令
docker node update --availability drain swarm-manager

[root@swarm-manager ~]# docker node update --availability drain swarm-manager swarm-manager

通过docker  node  ls查看个节点现在的状态:

Drain 表示swarm-manager 已经不负责运行service,之前swarm-manager运行的副本会如何处理呢?用docker service ps查看一下。

[root@swarm-manager ~]# docker service ps web_server

ID                                  NAME                           IMAGE                           NODE                            DESIRED STATE                 CURRENT STATE                        ERROR                  PORTS

sysvltl5miry                 web_server.1                  httpd:latest                  swarm-worker1                  Running                               Running about a minute ago                       

kmphjjmt1pqk             \_ web_server.1              httpd:latest                   swarm-manager                Shutdown                            Shutdown about a minute ago                      

mdgv63jpfst5               web_server.2                 httpd:latest                   swarm-worker1                 Running                               Running about a minute ago                       

tipv42u0c72y              \_ web_server.2              httpd:latest                    swarm-manager              Shutdown                             Shutdown about a minute ago                      

2zlyk1i44elq               web_server.3                  httpd:latest                   swarm-worker1                  Running                               Running 7 minutes ago                            

ji4nls51y9sv               web_server.4                  httpd:latest                   swarm-worker2                  Running                               Running 7 minutes ago                            

de79sh71mqm7         web_server.5                 httpd:latest                    swarm-worker2                  Running                               Running 7 minutes ago             
 

swarm-manager上的副本web_server.2已经被shutdown了,为了达到5个副本数的目标,在swarm-worker1上添加了副本web_server=3

[root@swarm-manager ~]# docker service scale web_server=3 web_server scaled to 3 overall progress: 3 out of 3 tasks

1/3: running   [==================================================>]

2/3: running   [==================================================>]

3/3: running   [==================================================>]

verify: Service converged

[root@swarm-manager ~]# docker service ps web_server

ID                       NAME                   IMAGE               NODE                   DESIRED STATE       CURRENT STATE            ERROR               PORTS sysvltl5miry        web_server.1        httpd:latest        swarm-worker1       Running                     Running 2 minutes ago                        kmphjjmt1pqk         \_ web_server.1    httpd:latest        swarm-manager       Shutdown            Shutdown 2 minutes ago                       mdgv63jpfst5        web_server.2        httpd:latest        swarm-worker1       Running                  Running 2 minutes ago                        tipv42u0c72y         \_ web_server.2    httpd:latest        swarm-manager       Shutdown             Shutdown 2 minutes ago                       ji4nls51y9sv        web_server.4        httpd:latest        swarm-worker2       Running                    Running 9 minutes ago                       

可以看到,web_server.4和web——server.5这两个副本已经被删除了。

Swarm如何实现Failover

故障是在所难免的 容器可能崩溃,DockerHost可能宕机,不过幸运的是,  Swarm已经内置了
 failover 策略。
创建service的时候,我们没有告诉swarm发生故障时该如何处理,只是说明了我们期望的状态(比如运行3个副本),swarm会尽最大的努力达成这个期望状态,无论发生什么状况。
以上一节我们部署的Service为例,当前3个副本分布在swarm-worker1和 swarm-worker2 上。现在我们测试swarm的failover特性,关闭swarm-worker1

现在我们测试swarm的failover的特性,关闭swarm-worker1。

Swarm会检测到swarm-worker1的故障,并标记Down。

[root@swarm-manager ~]# docker node ls

ID                                                              HOSTNAME            STATUS         AVAILABILITY        MANAGER STATUS      ENGINE VERSION

j6p2rf6fpcw4l6tkn2ps0jji0 *                       swarm-manager       Ready            Drain                         Leader                            19.03.2

  19.03.2 g6z8cbpxend7tu55asz2q9f3z    swarm-worker1        Down              Active                                                              19.03.2

19.03.2 raa8bbtyukqqdk3pa0vfvhtwp       swarm-worker2        Ready             Active                                                              19.03.2

Swarm会将swarm-worker1上的副本调度到其他可用节点。我们可以通过docker service ps观察这个failover过程。

可以看到,web_server.1和web_server.2已经从swarm-worker1迁移到了swarm-worker2,之前运行在故障节点swarm-worker1上的副本状态被标记为Shutdown。

 类似资料: