跳至主要内容

7.1 Docker Swarm 模式

經過前幾章的介紹,現在您應該可以透過 Docker 以及 Docker Compose 來打包和執行應用程式了,而在下一個章節正式部署應用程式之前,我們需要了解如何建立一個高可用性且穩定的環境給正式環境的應用程式。

在正式環境下 Docker Compose 就顯得有些無力了,只能運作在單一台機器的特性,導致若是機器崩潰了,應用程式就會喪失所有的服務,容器也將隨之消失;在一些小型的服務或是自己的 SideProject 可能可以接受這些損失;但若是在一秒鐘幾十萬上下的應用程式呢?

這時候就需要一個工具來幫助我們管理所有的機器以及容器,或許您可能有聽過 Kubernetes 這樣的容器調度工具,其功能極為強大,但學習的成本也相對較高。

而 Docker 本身內建的 Docker Swarm 就是 Docker 給出關於容器調度的解答,雖然功能不及 Kubernetes,但足夠應付百分之八十的挑戰。

首先在終端機輸入 docker swarm init 的指令:

$ docker swarm init
Swarm initialized: current node (4v12tg6etj3dluufyyv5uelx8) is now a manager.

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

docker swarm join --token SWMTKN-1-29il8kravb42lbmui5aiohz9250wwd2bal2v7vazhhz4y5uo5b-b46io0m71cl1rf5byummmopnj 192.168.65.3:2377

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

逐行來解釋這裡發生了什麼事情。

Swarm initialized: current node (4v12tg6etj3dluufyyv5uelx8) is now a manager.

這邊 Docker 告訴我們,現在這個 node 是一個 manager,這邊出現了兩個在之前的章節沒有出現過的名詞,來解釋一下:

節點 ( Node ): 意思是在 Docker Swarm 中的機器,以目前的情況來說,這個 Docker Swarm 有一個節點,也就是您的電腦。

Manager ( 管理者 ): 擁有較高權限的節點,如同其名,它擁有管理整個 Swarm 的資格。

接著來看看第二段:

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

docker swarm join --token SWMTKN-1-29il8kravb42lbmui5aiohz9250wwd2bal2v7vazhhz4y5uo5b-b46io0m71cl1rf5byummmopnj 192.168.65.3:2377

Docker 在輸出中提示,可以透過下方的指令把 worker 加入到現在這個 Swarm 之中,那 worker 又是什麼呢?

Worker ( 工作者 ): 純粹拿來運行服務的節點,就是產線中的工作者,只能接受管理者派下來的任務,並且執行。

試著把這段新增 worker 的指令貼到終端機在執行一次試試看:

$ docker swarm join --token SWMTKN-1-29il8kravb42lbmui5aiohz9250wwd2bal2v7vazhhz4y5uo5b-b46io0m71cl1rf5byummmopnj 192.168.65.3:2377

Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.

可以看到 Docker 給予我們的回應是説,目前這個節點已經是 Swarm 的一部分,如果使用 docker swarm leave 這個指令就可以離開 Swarm。

那就先試著離開 Swarm 吧!

$ docker swarm leave

Error response from daemon: You are attempting to leave the swarm on a node that is participating as a manager. Removing the last manager erases all current state of the swarm. Use `--force` to ignore this message.

又失敗了,Docker 告訴我們因為這個節點是最後一個 manager,離開 Swarm 的話會造成目前 Swarm 的狀態遺失,所以如果要離開的話,請加入 --force 的指令。

那就加入 --force 先離開 Swarm 吧!

$ docker swarm leave --force

Node left the swarm

Docker Swarm 的狀態

在剛剛要離開 Swarm 的時候,Docker 提示說道如果最後一個 manager 也離開的話,就會造成目前 Swarm 的狀態遺失,這是什麼意思呢?

還記得在 Docker Volume 篇 時,有提過關於有狀態與無狀態這件事,最重要的就是資料的永續性,以便讓某一個物件保持狀態。

可以看到下方圖片中的上半部屬於 manager 的區塊,有著一個 Internal distributed state store ( 分散式資料庫 ),而每一個 manager 都和資料庫有著連接。

Docker Swarm 架構示意圖

而這個分散式的資料庫是拿來做什麼的呢?

其功能主要是紀錄整個 Docker Swarm 的詳細資訊,包含了應用程式的預期狀態,worker 所回傳的資料 ( 服務是否完成 ),有哪些節點屬於這個 Swarm,哪些工作應該要分配給哪些節點等等,可以說是整個 Swarm 保持狀態的核心。

這也是為什麼 Docker 會警告最後一個 manager 離開時會造成目前 Swarm 的狀態遺失,是因為當最後一個 manager 離開,這個 Docker Swarm 也會隨之解散,想當然而儲存的資料將會一併被抹去。

接著稍微提一下在 manager 區塊的右上角有一段 Raft consensus group,Raft 本身是一種演算法 ( 共識演算法 ),是一個非常有趣的演算法,目的就是在一個叢集中有多個節點組成,讓每個節點都維護相同的狀態。 也是 Docker Swarm 如何讓不同的 manager 間可以做到一致性的主要原因,這邊就不深入探討了,只要知道透過這個 Raft 演算法,Manager Node 之間的資訊會保持一致。

至於什麼樣的機器能夠加入 Docker Swarm 呢?只要可以安裝 Docker 不論是物理上的機器或是雲端的虛擬機器,亦或是 Windows、macOS、Linux 等作業系統,這些都不重要,重要的是它們都可以安裝 Docker,就可以加入 Docker Swarm。