用於容器編排的 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 模式下編排容器的全部內容。 在您的非生產環境中嘗試這些以了解其工作原理。