管理和維護 Docker 引擎叢集
當您執行 Docker Engine 的 Swarm 時,管理節點是用於管理 Swarm 和儲存 Swarm 狀態的關鍵組成部分。 瞭解管理節點的一些關鍵功能對於正確部署和維護 Swarm 至關重要。
請參閱節點的運作方式,以簡要瞭解 Docker Swarm 模式以及管理節點和工作節點之間的差異。
在 Swarm 中操作管理節點
Swarm 管理節點使用Raft 共識演算法來管理 Swarm 狀態。 您只需要瞭解 Raft 的一些一般概念即可管理 Swarm。
管理節點的數量沒有限制。 實現多少個管理節點的決定是效能和容錯之間的權衡。 將管理節點新增至 Swarm 可提高 Swarm 的容錯能力。 但是,額外的管理節點會降低寫入效能,因為更多節點必須確認更新 Swarm 狀態的提案。 這表示更多的網路來回流量。
Raft 要求大多數管理節點(也稱為法定人數)就提議的 Swarm 更新(例如節點新增或移除)達成一致。 成員資格操作受制於與狀態複製相同的約束。
維護管理節點的法定人數
如果 Swarm 失去管理節點的法定人數,則 Swarm 無法執行管理任務。 如果您的 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,則 Swarm 將變得不可用,直到您重新啟動節點或使用 --force-new-cluster
重新啟動。
您可以使用 docker swarm
和 docker node
子系統來管理 Swarm 成員資格。 如需如何新增工作節點以及將工作節點提升為管理節點的詳細資訊,請參閱將節點新增至 Swarm。
分佈管理節點
除了維護奇數個管理節點之外,在放置管理節點時還要 chúyì 資料中心拓撲。 為了獲得最佳容錯能力,請將管理節點分佈在至少 3 個可用區域中,以支援整組機器故障或常見的維護情況。 如果您在任何這些區域中遇到故障,Swarm 應維護可用的管理節點的法定人數,以處理請求並重新平衡工作負載。
Swarm 管理節點 | 重新分割(在 3 個可用區域上) |
---|---|
3 | 1-1-1 |
5 | 2-2-1 |
7 | 3-2-2 |
9 | 3-3-3 |
僅執行管理節點
預設情況下,管理節點也充當工作節點。這表示排程器可以將任務分配給管理節點。對於小型且非關鍵的叢集,只要您使用 CPU 和記憶體的資源限制來排程服務,將任務分配給管理節點的風險相對較低。
然而,由於管理節點使用 Raft 共識演算法以一致的方式複製資料,因此它們對資源耗盡很敏感。您應該將叢集中的管理節點與可能阻礙叢集操作(例如叢集心跳或領導者選舉)的程序隔離。
為了避免干擾管理節點的運作,您可以清空管理節點,使其無法作為工作節點使用。
$ docker node update --availability drain <NODE>
當您清空節點時,排程器會將在該節點上執行的任何任務重新分配給叢集中其他可用的工作節點。它還會阻止排程器將任務分配給該節點。
新增工作節點以進行負載平衡
透過將節點新增到叢集來平衡叢集的負載。只要工作節點符合服務的要求,複製的服務任務就會盡可能平均地分佈在叢集中。當限制服務僅在特定類型的節點上運行時,例如具有特定 CPU 數量或記憶體量的節點,請記住不符合這些要求的工作節點無法運行這些任務。
監控 Swarm 健康狀態
您可以透過 `/nodes` HTTP 端點以 JSON 格式查詢 Docker nodes
API 來監控管理節點的健康狀況。有關更多資訊,請參閱nodes API 文件。
在命令列中,運行 docker node inspect <節點 ID>
來查詢節點。例如,要查詢節點作為管理節點的可達性:
$ docker node inspect manager1 --format "{{ .ManagerStatus.Reachability }}"
reachable
要查詢節點作為接受任務的工作節點的狀態:
$ docker node inspect manager1 --format "{{ .Status.State }}"
ready
從這些命令中,我們可以看到 manager1
作為管理節點的狀態為 reachable
(可達),作為工作節點的狀態為 ready
(就緒)。
unreachable
(不可達)的健康狀態表示此特定管理節點無法從其他管理節點訪問。在這種情況下,您需要採取措施來恢復不可達的管理節點。
- 重新啟動 Docker 守護程序,看看管理節點是否恢復可達。
- 重新啟動機器。
- 如果重新啟動或重新開機都無效,您應該新增另一個管理節點或將工作節點提升為管理節點。您還需要使用
docker node demote <節點名稱>
和docker node rm <節點 ID>
將失敗的節點條目從管理節點集合中清除。
或者,您也可以從管理節點使用 docker node ls
獲取叢集健康狀況的概覽。
$ 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 加入叢集一次。節點 ID 空間應該是全局唯一的。
要將管理節點乾淨地重新加入叢集:
- 使用
docker node demote <節點名稱>
將節點降級為工作節點。 - 使用
docker node rm <節點名稱>
將節點從叢集中移除。 - 使用
docker swarm join
將節點以全新狀態重新加入叢集。
有關將管理節點加入叢集的更多資訊,請參閱將節點加入叢集。
強制移除節點
在大多數情況下,您應該在使用 docker node rm
命令將節點從叢集中移除之前將其關閉。如果節點變得不可達、無響應或遭到入侵,您可以透過傳遞 --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 管理節點將叢集狀態和管理日誌儲存在 /var/lib/docker/swarm/
目錄中。此資料包含用於加密 Raft 日誌的密鑰。沒有這些密鑰,您將無法恢復叢集。
您可以使用任何管理節點備份叢集。請使用以下步驟。
如果叢集啟用了自動鎖定,您需要解鎖密鑰才能從備份恢復叢集。如有必要,請擷取解鎖密鑰並將其儲存在安全的位置。如果您不確定,請閱讀鎖定您的叢集以保護其加密密鑰。
在備份資料之前停止管理節點上的 Docker,以便在備份期間不會更改任何資料。可以在管理節點運行時進行備份(「熱」備份),但不建議這樣做,並且在恢復時結果不太可預測。當管理節點關閉時,其他節點會繼續產生不屬於此備份的叢集資料。
注意
請務必維持叢集管理節點的法定人數。在管理節點關閉期間,如果更多節點遺失,您的叢集更容易遺失法定人數。您運行的管理節點數量是一個權衡。如果您經常關閉管理節點進行備份,請考慮運行五個管理節點的叢集,這樣您就可以在備份運行時再遺失一個管理節點,而不會中斷您的服務。
備份整個
/var/lib/docker/swarm
目錄。重新啟動管理節點。
要恢復,請參閱從備份恢復。
從災難中復原
從備份還原
按照備份叢集中所述備份叢集後,請使用以下步驟將資料恢復到新的叢集。
關閉已恢復叢集的目標主機上的 Docker。
移除新叢集上
/var/lib/docker/swarm
目錄的內容。使用備份的內容恢復
/var/lib/docker/swarm
目錄。注意
新節點使用與舊節點相同的磁碟儲存加密密鑰。目前無法更改磁碟儲存加密密鑰。
對於啟用了自動鎖定的叢集,解鎖密鑰也與舊叢集上的相同,並且需要解鎖密鑰才能恢復叢集。
在新節點上啟動 Docker。如有必要,請解鎖叢集。使用以下命令重新初始化叢集,以便此節點不會嘗試連接到屬於舊叢集(並且可能不再存在)的節點。
$ docker swarm init --force-new-cluster
驗證叢集的狀態是否符合預期。這可能包括特定應用程式的測試,或者只是檢查
docker service ls
的輸出以確保所有預期的服務都存在。如果您使用自動鎖定,請輪換解鎖密鑰。
新增管理節點和工作節點,以使您的新叢集達到運行容量。
在新叢集上恢復您之前的備份方案。
從失去法定人數中復原
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 定期將任務轉移到不同的節點以實現平衡,則使用這些任務的客戶端將會受到干擾。目標是避免為了 Swarm 的平衡而中斷正在運行的服務。當新任務啟動或運行任務的節點變得不可用時,這些任務將分配給負載較低的節點。目標是最終的平衡,同時最大限度地減少對最終用戶的干擾。
您可以將 `--force` 或 `-f` 標誌與 `docker service update` 命令一起使用,以強制服務將其任務重新分佈到可用的工作節點上。這將導致服務任務重新啟動。客戶端應用程式可能會受到干擾。如果您已配置它,您的服務將使用滾動更新。
如果您使用的是早期版本,並且您希望在工作節點之間實現負載的均勻平衡,並且不介意中斷正在運行的任務,則可以透過暫時向上擴展服務來強制 Swarm 重新平衡。使用 `docker service inspect --pretty <服務名稱>` 來查看服務的已配置規模。當您使用 `docker service scale` 時,具有最少任務數量的節點將成為接收新工作負載的目標。您的 Swarm 中可能有多個負載不足的節點。您可能需要幾次以適度的增量向上擴展服務,以在所有節點之間實現您想要的平衡。
當負載平衡到您滿意的程度時,您可以將服務縮減到原始規模。您可以使用 `docker service ps` 來評估您的服務在節點之間的當前平衡。