管理與維護 Docker Engine 叢集
當您執行 Docker Engine 叢集時,管理節點是管理叢集和儲存叢集狀態的關鍵元件。了解管理節點的一些關鍵功能對於正確部署和維護叢集至關重要。
請參閱節點運作方式,以簡要了解 Docker Swarm 模式以及管理節點與工作者節點之間的差異。
在 Swarm 中操作管理節點
Swarm 管理節點使用Raft 共識演算法來管理叢集狀態。您只需要了解 Raft 的一些一般概念即可管理 Swarm。
管理節點的數量沒有限制。關於要實作多少個管理節點的決定,是效能與容錯之間的一種權衡。將管理節點新增到 Swarm 可使叢集更具容錯性。然而,額外的管理節點會降低寫入效能,因為更多的節點必須確認更新叢集狀態的提案。這意味著更多的網路往返流量。
Raft 要求大多數管理節點(也稱為法定人數 (quorum))就叢集的提議更新(例如節點的添加或移除)達成一致。成員資格操作受與狀態複製相同的限制。
維持管理節點的法定人數 (Quorum)
如果叢集失去管理節點的法定人數,則叢集無法執行管理任務。如果您的 Swarm 有多個管理節點,請務必保持兩個以上。為了維持法定人數,大多數管理節點必須可用。建議使用奇數個管理節點,因為下一個偶數個不會讓法定人數更容易維持。例如,無論您有 3 個還是 4 個管理節點,您仍然只能失去 1 個管理節點並維持法定人數。如果您有 5 個或 6 個管理節點,您仍然只能失去兩個。
即使 Swarm 失去管理節點的法定人數,現有工作者節點上的 Swarm 任務仍會繼續執行。然而,Swarm 節點無法被新增、更新或移除,並且新的或現有的任務無法啟動、停止、移動或更新。
如果您確實失去管理節點的法定人數,請參閱從失去法定人數中復原以了解疑難排解步驟。
將管理節點配置為在靜態 IP 位址上發布
當初始化 Swarm 時,您必須指定 --advertise-addr 旗標以將您的位址發布給 Swarm 中的其他管理節點。更多資訊請參閱在 Swarm 模式下執行 Docker Engine。由於管理節點旨在成為基礎設施的穩定元件,您應該為發布位址使用固定 IP 位址,以防止 Swarm 在機器重啟時變得不穩定。
如果整個 Swarm 重新啟動且每個管理節點隨後都獲得新的 IP 位址,則任何節點都無法聯絡現有的管理節點。因此,當節點嘗試以其舊 IP 位址相互聯絡時,Swarm 會停滯。
動態 IP 位址對於工作者節點來說是可行的。
新增管理節點以實現容錯
您應該在 Swarm 中維持奇數個管理節點,以支援管理節點故障。擁有奇數個管理節點可確保在網路分割期間,如果網路被分割成兩組,法定人數更有可能保持可用以處理請求。如果您遇到超過兩個網路分割,則無法保證維持法定人數。
| Swarm 大小 | 多數 | 容錯能力 |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
| 8 | 5 | 3 |
| 9 | 5 | 4 |
例如,在一個擁有 5 個節點的 Swarm 中,如果您失去 3 個節點,您就沒有法定人數。因此,在您復原其中一個不可用的管理節點或使用災難復原命令復原叢集之前,您無法新增或移除節點。請參閱從災難中復原。
雖然可以將 Swarm 縮減到單一管理節點,但無法降級最後一個管理節點。這可確保您維持對 Swarm 的存取權,並且 Swarm 仍可處理請求。縮減到單一管理節點是不安全的,且不建議這樣做。如果最後一個節點在降級操作期間意外離開 Swarm,則 Swarm 會變得不可用,直到您重新啟動該節點或使用 --force-new-cluster 重新啟動。
您可以使用 docker swarm 和 docker node 子系統來管理 Swarm 成員資格。有關如何新增工作者節點以及將工作者節點提升為管理節點的更多資訊,請參閱將節點新增至 Swarm。
分佈管理節點
除了維持奇數個管理節點之外,在放置管理節點時,請注意資料中心拓撲。為了獲得最佳容錯能力,請將管理節點分佈在至少 3 個可用性區域中,以支援整組機器故障或常見維護情境。如果其中任何一個區域發生故障,Swarm 應該能夠維持管理節點的法定人數,以處理請求和重新平衡工作負載。
| Swarm 管理節點 | 重新分割 (在 3 個可用性區域上) |
|---|---|
| 3 | 1-1-1 |
| 5 | 2-2-1 |
| 7 | 3-2-2 |
| 9 | 3-3-3 |
執行僅限管理員的節點
預設情況下,管理節點也充當工作者節點。這表示排程器可以將任務指派給管理節點。對於小型和非關鍵的 Swarm,只要您使用 CPU 和記憶體的資源限制來排程服務,將任務指派給管理節點的風險相對較低。
然而,由於管理節點使用 Raft 共識演算法以一致的方式複製資料,它們對資源匱乏很敏感。您應該將 Swarm 中的管理節點與可能阻礙 Swarm 操作(例如 Swarm 心跳或領導者選舉)的程序隔離。
為避免干擾管理節點操作,您可以排除 (drain) 管理節點,使其無法作為工作者節點使用。
$ docker node update --availability drain <NODE>
當您排除 (drain) 節點時,排程器會將節點上執行的任何任務重新指派給 Swarm 中其他可用的工作者節點。它也阻止排程器將任務指派給該節點。
新增工作者節點以實現負載平衡
將節點新增至 Swarm 以平衡 Swarm 的負載。只要工作者節點符合服務要求,複製的服務任務會隨著時間盡可能均勻地分佈在 Swarm 中。當限制服務僅在特定類型的節點上執行時,例如具有特定 CPU 數量或記憶體容量的節點,請記住不符合這些要求的工作者節點無法執行這些任務。
監控 Swarm 運行狀況
您可以透過 /nodes HTTP 端點以 JSON 格式查詢 Docker nodes API 來監控管理節點的運行狀況。有關更多資訊,請參閱節點 API 文件。
從命令列執行 docker node inspect <id-node> 來查詢節點。例如,查詢節點作為管理節點的可達性:
$ docker node inspect manager1 --format "{{ .ManagerStatus.Reachability }}"
reachable
查詢節點作為接受任務的工作者節點的狀態:
$ docker node inspect manager1 --format "{{ .Status.State }}"
ready
從這些命令中,我們可以看到 manager1 作為管理節點處於 reachable 狀態,同時作為工作者節點處於 ready 狀態。
unreachable 的運行狀況狀態表示此特定管理節點無法從其他管理節點到達。在這種情況下,您需要採取行動來復原不可達的管理節點:
- 重新啟動守護程式 (daemon),並查看管理節點是否恢復可達。
- 重新啟動機器。
- 如果重新啟動和重新開機都無效,您應該新增另一個管理節點或將工作者節點提升為管理節點。您還需要使用
docker node demote <NODE>和docker node rm <id-node>從管理節點集合中乾淨地移除失敗的節點條目。
或者,您也可以使用 docker node ls 從管理節點獲取 Swarm 運行狀況的概覽。
$ docker node ls
ID HOSTNAME MEMBERSHIP STATUS AVAILABILITY MANAGER STATUS
1mhtdwhvsgr3c26xxbnzdc3yp node05 Accepted Ready Active
516pacagkqp2xc3fk9t1dhjor node02 Accepted Ready Active Reachable
9ifojw8of78kkusuc4a6c23fx * node01 Accepted Ready Active Leader
ax11wdpwrrb6db3mfjydscgk7 node04 Accepted Ready Active
bb1nrq2cswhtbg4mrsqnlx1ck node03 Accepted Ready Active Reachable
di9wxgz8dtuh9d2hn089ecqkf node06 Accepted Ready Active
管理節點疑難排解
您絕不應該透過從另一個節點複製 raft 目錄來重新啟動管理節點。資料目錄對於節點 ID 而言是唯一的。一個節點只能使用一個節點 ID 加入 Swarm 一次。節點 ID 空間應該是全域唯一的。
要乾淨地將管理節點重新加入叢集:
- 使用
docker node demote <NODE>將節點降級為工作者節點。 - 使用
docker node rm <NODE>從 Swarm 中移除節點。 - 使用
docker swarm join以全新狀態將節點重新加入 Swarm。
有關將管理節點加入 Swarm 的更多資訊,請參閱將節點加入 Swarm。
強制移除節點
在大多數情況下,您應該在使用 docker node rm 命令將節點從 Swarm 中移除之前將其關閉。如果節點變得不可達、無回應或受到危害,您可以透過傳遞 --force 旗標在不關閉節點的情況下強制移除該節點。例如,如果 node9 受到危害:
$ docker node rm node9
Error response from daemon: rpc error: code = 9 desc = node node9 is not down and can't be removed
$ docker node rm --force node9
Node node9 removed from swarm
在您強制移除管理節點之前,必須先將其降級為工作者角色。如果您降級或移除管理節點,請確保您始終擁有奇數個管理節點。
備份 Swarm
Docker 管理節點將 Swarm 狀態和管理節點日誌儲存在 /var/lib/docker/swarm/ 目錄中。此資料包含用於加密 Raft 日誌的金鑰。沒有這些金鑰,您將無法還原 Swarm。
您可以使用任何管理節點備份 Swarm。請使用以下程序。
如果 Swarm 啟用了自動鎖定 (auto-lock),您需要解鎖金鑰才能從備份中還原 Swarm。如有必要,請取得解鎖金鑰並將其儲存在安全位置。如果您不確定,請閱讀鎖定您的 Swarm 以保護其加密金鑰。
在備份資料之前,請在管理節點上停止 Docker,以確保在備份期間沒有資料被更改。雖然可以在管理節點運行時進行備份(「熱」備份),但這不建議,並且還原時的結果較不可預測。當管理節點關閉時,其他節點會繼續生成不屬於此備份的 Swarm 資料。
注意請務必維持 Swarm 管理節點的法定人數。在管理節點關閉期間,如果進一步遺失節點,您的 Swarm 更容易失去法定人數。您運行的管理節點數量是一種權衡。如果您定期關閉管理節點以進行備份,請考慮運行一個包含五個管理節點的 Swarm,這樣您就可以在備份運行時額外失去一個管理節點,而不會中斷您的服務。
備份整個
/var/lib/docker/swarm目錄。重新啟動管理節點。
要還原,請參閱從備份中還原。
從災難中復原
從備份中還原
按照備份 Swarm 中所述備份 Swarm 後,請使用以下程序將資料還原到新的 Swarm。
在用於還原 Swarm 的目標主機上關閉 Docker。
移除新 Swarm 上
/var/lib/docker/swarm目錄的內容。使用備份的內容還原
/var/lib/docker/swarm目錄。注意新節點使用與舊節點相同的磁碟儲存加密金鑰。目前無法更改磁碟儲存加密金鑰。
對於啟用了自動鎖定 (auto-lock) 的 Swarm,解鎖金鑰也與舊 Swarm 上的相同,並且需要解鎖金鑰才能還原 Swarm。
在新節點上啟動 Docker。如有必要,請解鎖 Swarm。使用以下命令重新初始化 Swarm,這樣此節點就不會嘗試連接到屬於舊 Swarm 但假定已不存在的節點。
$ docker swarm init --force-new-cluster驗證 Swarm 的狀態是否如預期。這可能包括應用程式特定的測試,或只是檢查
docker service ls的輸出,以確保所有預期的服務都存在。如果您使用自動鎖定 (auto-lock),請輪換解鎖金鑰。
新增管理節點和工作者節點,使您的新 Swarm 達到運作容量。
在新 Swarm 上恢復您以前的備份方案。
從失去法定人數中復原
Swarm 具備容錯能力,可以從任意數量的臨時節點故障(機器重新開機或帶有重新啟動的崩潰)或其他暫時性錯誤中復原。然而,如果 Swarm 失去法定人數,則無法自動復原。現有工作者節點上的任務會繼續運行,但無法執行管理任務,包括擴展或更新服務以及加入或從 Swarm 中移除節點。最佳復原方式是讓遺失的管理節點重新上線。如果無法做到,請繼續閱讀以了解復原 Swarm 的一些選項。
在一個包含 N 個管理節點的 Swarm 中,必須始終有法定人數(多數)的管理節點可用。例如,在一個擁有五個管理節點的 Swarm 中,至少三個必須處於運作狀態並相互通訊。換句話說,Swarm 最多可以容忍 (N-1)/2 個永久性故障,超過此數量,涉及 Swarm 管理的請求將無法處理。這些類型的故障包括資料損壞或硬體故障。
如果您失去管理節點的法定人數,您將無法管理 Swarm。如果您已失去法定人數,並且嘗試對 Swarm 執行任何管理操作,則會發生錯誤:
Error response from daemon: rpc error: code = 4 desc = context deadline exceeded從失去法定人數中復原的最佳方法是讓失敗的節點重新上線。如果無法做到,唯一能從此狀態復原的方法是從管理節點使用 --force-new-cluster 動作。這會移除所有管理節點,除了執行該命令的管理節點。由於現在只剩下一個管理節點,因此達成了法定人數。將節點提升為管理節點,直到您擁有所需數量的管理節點。
從要復原的節點執行:
$ docker swarm init --force-new-cluster --advertise-addr node01:2377
當您使用 --force-new-cluster 旗標執行 docker swarm init 命令時,您執行該命令的 Docker Engine 會成為單節點 Swarm 的管理節點,該節點能夠管理和運行服務。管理節點擁有所有關於服務和任務的先前資訊,工作者節點仍是 Swarm 的一部分,並且服務仍在運行。您需要新增或重新新增管理節點,以實現先前的任務分佈,並確保您擁有足夠的管理節點以維持高可用性並防止失去法定人數。
強制 Swarm 重新平衡
通常,您不需要強制 Swarm 重新平衡其任務。當您將新節點新增到 Swarm,或者節點在一段時間不可用後重新連接到 Swarm 時,Swarm 不會自動將工作負載分配給閒置節點。這是一個設計決策。如果 Swarm 為了平衡而定期將任務轉移到不同的節點,使用這些任務的用戶端將會受到干擾。目標是避免為了 Swarm 的平衡而中斷正在運行的服務。當新任務啟動時,或者當運行任務的節點變得不可用時,這些任務會分配給較不繁忙的節點。目標是最終的平衡,同時將對終端用戶的干擾降到最低。
您可以將 --force 或 -f 旗標與 docker service update 命令一起使用,以強制服務將其任務重新分配到可用的工作者節點。這會導致服務任務重新啟動。用戶端應用程式可能會受到干擾。如果您已配置,您的服務會使用滾動更新。
如果您使用較早的版本,並且希望在工作者之間實現負載的均勻平衡,同時不介意中斷正在運行的任務,您可以透過暫時向上擴展服務來強制 Swarm 重新平衡。使用 docker service inspect --pretty <servicename> 來查看服務的配置規模。當您使用 docker service scale 時,任務數量最少的節點將被選為接收新工作負載。您的 Swarm 中可能有多個負載不足的節點。您可能需要以適度的增量將服務擴展幾次,以在所有節點上實現您想要的平衡。
當負載平衡達到您的滿意度時,您可以將服務縮減回原始規模。您可以使用 docker service ps 來評估服務在節點之間的當前平衡狀況。