用于容器编排的 Docker Swarm
已发表: 2019-08-08关于 Docker Swarm 以及它如何管理和编排集群中的所有容器。
什么是 Docker Swarm?
Docker swarm 是一种处理 Docker 引擎集群的模式,因此得名 Swarm。 Docker 主机集群以由管理人员和工作人员组成的集群模式运行。 参与 swarm 的 docker-engine 实例称为节点。
生产级集群部署由分布在多个服务器上的 docker 节点组成。
为什么要使用它? – 容器编排
当您在生产环境中工作时,数百个 docker 容器将在其中运行多个应用程序。 管理所有这些容器对于所有 DevOps 工程师来说都是一个巨大的痛苦; 这就是 Docker Swarm 可以帮助您的地方。 它可以轻松管理和编排运行多个 docker 容器的集群。
以下是它的一些特点:
- 高可用性——旨在提供不停机或中断。
- 负载平衡——如果任何节点发生故障,自动分配集群中其他节点上的资源和请求。
- 去中心化——多个管理节点在生产环境中运行; 因此集群从不依赖于单个管理节点。
- 可扩展性——使用单个 docker swarm 命令,您可以轻松地扩展或缩减集群中的容器。
编排 Docker 容器
现在您已经了解了 Docker Swarm 的基础知识,让我们看一下它的实现示例。
在这个例子中,我在一个集群中运行了三台机器,详细信息如下:
manager1: 192.168.56.104 worker1: 192.168.56.105 worker2: 192.168.56.102
要在 docker 中初始化 swarm 模式,请在管理器节点上运行以下命令。 标志--advertise-addr
用于向可以加入集群的节点通告自己。
geekflare@manager1:~$ docker swarm init --advertise-addr 192.168.56.104 Swarm initialized: current node (lssbyfzuiuh3sye1on63eyixf) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上述命令将生成一个令牌,其他节点将使用该令牌加入该集群。 使用生成的令牌复制命令并在工作节点上运行它。
在 worker1 节点上运行令牌。
geekflare@worker1:~$ docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377 This node joined a swarm as a worker.
在 worker2 节点上运行令牌。
geekflare@worker2:~$ docker swarm join --token SWMTKN-1-3h3d8qgvdlxi8tl1oqpfho9khx7i1t5nq7562s9gzojbcm9kr6-azy4rffrzou0nem9hxq4ro5am 192.168.56.104:2377 This node joined a swarm as a worker.
现在,在管理节点上,您可以检查集群中正在运行的节点。
geekflare@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION lssbyfzuiuh3sye1on63eyixf * manager1 Ready Active Leader 18.09.6 utdr3dnngqf1oy1spupy1qlhu worker1 Ready Active 18.09.6 xs6jqp95lw4cml1i1npygt3cg worker2 Ready Active 18.09.6
让我们构建我们在 Dockerfile 教程中使用的geekflare_mongodb
docker 镜像。
docker build -t geekflare_mongodb .
通过创建 swarm 服务来运行 MongoDB docker 镜像的容器。 27017 是暴露 MongoDB 的端口号。
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 geekflare_mongodb image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image. kok58xa4zi05psh3uy6s5x9e6 overall progress: 1 out of 1 tasks 1/1: running verify: Service converged
检查 docker swarm 服务是否已启动。 MODE 已复制意味着容器已在集群中的所有节点上复制,REPLICAS 1/1 意味着当前只有一个 swarm 服务正在运行。
geekflare@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS kok58xa4zi05 Mongo-Container replicated 1/1 geekflare_mongodb:latest *:27017->27017/tcp
让我们检查一下这个单一服务在集群中的哪个节点上运行。 它在 manager1 节点上运行。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS jgqjo92rbq23 Mongo-Container.1 geekflare_mongodb:latest manager1 Running Running about a minute ago
运行 docker ps 命令以获取有关运行此 swarm 服务的容器的更多详细信息。
geekflare@manager1:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 05d77e7b4850 geekflare_mongodb:latest "/bin/sh -c usr/bin/…" 2 minutes ago Up 2 minutes 27017/tcp Mongo-Container.1.jgqjo92rbq23sv01hrufdigtx
您也可以在“全局”模式下运行 swarm 服务,而不是默认的“复制”模式。 全局模式在集群中的所有节点上运行 swarm 服务的一项任务。
在我以全局模式运行服务之前,让我删除现有的正在运行的容器。
geekflare@manager1:~$ docker service rm Mongo-Container Mongo-Container
使用 –mode 标志以全局模式在 docker 容器内启动 swarm 服务。
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 --mode global geekflare_mongodb image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image. mfw8dp0zylffppkllkcjl8391 overall progress: 3 out of 3 tasks utdr3dnngqf1: running lssbyfzuiuh3: running xs6jqp95lw4c: running verify: Service converged
检查 swarm 服务是否以全局模式启动。 由于集群中运行了三个节点(1 个管理器,2 个工作器),这就是副本数为 3 的原因。
geekflare@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS mfw8dp0zylff Mongo-Container global 3/3 geekflare_mongodb:latest *:27017->27017/tcp
3 个服务现在在 3 个节点上运行,通过运行以下命令进行检查。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS zj2blvptkvj6 Mongo-Container.xs6jqp95lw4cml1i1npygt3cg geekflare_mongodb:latest worker2 Running Running about a minute ago 3eaweijbbutf Mongo-Container.utdr3dnngqf1oy1spupy1qlhu geekflare_mongodb:latest worker1 Running Running about a minute ago yejg1o2oyab7 Mongo-Container.lssbyfzuiuh3sye1on63eyixf geekflare_mongodb:latest manager1 Running Running about a minute ago
接下来,让我展示如何定义副本数。 在此之前,我将删除当前正在运行的容器。

geekflare@manager1:~$ docker service rm Mongo-Container Mongo-Container
在命令中使用 –replicas 标志并提及您想要的 swarm 服务的副本数。 例如,我想要 swarm 服务的两个副本:
geekflare@manager1:~$ docker service create --name "Mongo-Container" -p 27017:27017 --replicas=2 geekflare_mongodb image geekflare_mongodb:latest could not be accessed on a registry to record its digest. Each node will access geekflare_mongodb:latest independently, possibly leading to different nodes running different versions of the image. 4yfl41n7sfak65p6zqwwjq82c overall progress: 2 out of 2 tasks 1/2: running 2/2: running verify: Service converged
检查当前运行的 swarm 服务。 您可以看到一个副本在 manager1 节点上运行,另一个在 worker1 节点上运行。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS xukodj69h79q Mongo-Container.1 geekflare_mongodb:latest worker1 Running Running 9 seconds ago e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 9 seconds ago
转到 worker1 节点并检查 docker 容器是否正在运行 swarm 服务。
geekflare@worker1:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5042b7f161cb geekflare_mongodb:latest "/bin/sh -c usr/bin/…" About a minute ago Up About a minute 27017/tcp Mongo-Container.1.xukodj69h79q3xf0pouwm7bwv
要停止此容器,请运行以下命令。
geekflare@worker1:~$ docker stop 5042b7f161cb 5042b7f161cb
现在,如果您从 manager1 节点检查哪些所有节点都在运行该服务,您将看到它在 manager1 节点和 worker2 节点上运行。 worker1 节点的当前状态是 Shutdown(因为我们停止了运行服务的容器)。 但由于该服务必须运行两个副本,因此在 worker 2 上启动了另一个服务。
这就是使用 docker swarm 实现高可用性的方式。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 30 seconds ago xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 38 seconds ago "task: non-zero exit (137)" e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 3 minutes ago
扩展或缩小 docker 容器非常容易。 下面的命令会将 mongo 容器扩展到 5。
geekflare@manager1:~$ docker service scale Mongo-Container=5 Mongo-Container 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
查看当前运行的 mongo 容器副本数,一定是 5 个。
geekflare@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 4yfl41n7sfak Mongo-Container replicated 5/5 geekflare_mongodb:latest *:27017->27017/tcp
检查这 5 个副本在集群中的运行位置。 1 个副本在 manager1 节点上运行,2 个副本在两个工作节点上运行。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 2 minutes ago xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 2 minutes ago "task: non-zero exit (137)" e66zllm0foc8 Mongo-Container.2 geekflare_mongodb:latest manager1 Running Running 5 minutes ago qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 Running Running 47 seconds ago 9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 Running Running 46 seconds ago e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 Running Running 44 seconds ago
在您的集群中,如果您不希望您的服务在管理器节点上运行,并且只想将其保留用于管理节点,则可以将管理器节点耗尽。
geekflare@manager1:~$ docker node update --availability drain manager1 manager1
检查管理器节点的可用性。
geekflare@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION lssbyfzuiuh3sye1on63eyixf * manager1 Ready Drain Leader 18.09.6 utdr3dnngqf1oy1spupy1qlhu worker1 Ready Active 18.09.6 xs6jqp95lw4cml1i1npygt3cg worker2 Ready Active 18.09.6
您将看到服务不再在管理节点上运行; 它们分布在集群中的工作节点上。
geekflare@manager1:~$ docker service ps Mongo-Container ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS cd2rlv90umej Mongo-Container.1 geekflare_mongodb:latest worker2 Running Running 5 minutes ago xukodj69h79q \_ Mongo-Container.1 geekflare_mongodb:latest worker1 Shutdown Failed 5 minutes ago "task: non-zero exit (137)" qo405dheuutj Mongo-Container.2 geekflare_mongodb:latest worker1 Running Running 41 seconds ago e66zllm0foc8 \_ Mongo-Container.2 geekflare_mongodb:latest manager1 Shutdown Shutdown 44 seconds ago qmp0gqr6ilxi Mongo-Container.3 geekflare_mongodb:latest worker2 Running Running 3 minutes ago 9ddrf4tsvnu2 Mongo-Container.4 geekflare_mongodb:latest worker1 Running Running 3 minutes ago e9dhoud30nlk Mongo-Container.5 geekflare_mongodb:latest worker1 Running Running 3 minutes ago
这就是关于 Docker Swarm 以及如何在 docker swarm 模式下编排容器的全部内容。 在您的非生产环境中尝试这些以了解其工作原理。