服務的工作原理
當 Docker Engine 處於 Swarm 模式時,要部署應用程式映象,您需要建立一個服務。通常,服務是某個更大應用程式上下文中的微服務的映象。服務的示例可能包括 HTTP 伺服器、資料庫或您希望在分散式環境中執行的任何其他型別的可執行程式。
建立服務時,您可以指定要使用的容器映象以及要在執行的容器內執行的命令。您還可以為服務定義選項,包括:
- Swarm 使服務在 Swarm 外部可用的埠
- 用於將服務連線到 Swarm 中其他服務的覆蓋網路
- CPU 和記憶體的限制和預留
- 滾動更新策略
- 在 Swarm 中執行的映象副本數
服務、任務和容器
當您將服務部署到 Swarm 時,Swarm 管理器會接受您的服務定義作為服務的期望狀態。然後,它將服務作為一個或多個副本任務排程到 Swarm 中的節點上。這些任務在 Swarm 中的節點上彼此獨立執行。
例如,假設您想在三個 HTTP 監聽器例項之間進行負載均衡。下圖顯示了一個包含三個副本的 HTTP 監聽器服務。監聽器的三個例項中的每一個都是 Swarm 中的一個任務。


容器是一個隔離的程序。在 Swarm 模式模型中,每個任務只調用一個容器。任務類似於排程器放置容器的“插槽”。一旦容器處於活動狀態,排程器就會識別出該任務處於執行狀態。如果容器健康檢查失敗或終止,任務也會終止。
任務和排程
任務是 Swarm 中排程的原子單元。當您透過建立或更新服務來宣告服務的期望狀態時,編排器透過排程任務來實現期望的狀態。例如,您定義一個服務,指示編排器始終保持三個 HTTP 監聽器例項執行。編排器會響應建立三個任務。每個任務都是一個插槽,排程器透過生成一個容器來填充。容器是任務的例項化。如果一個 HTTP 監聽器任務隨後健康檢查失敗或崩潰,編排器會建立一個新的副本任務,該任務會生成一個新的容器。
任務是一種單向機制。它會單調地經過一系列狀態:已分配、已準備、執行中等。如果任務失敗,編排器會移除該任務及其容器,然後根據服務指定的期望狀態建立一個新任務來替換它。
Docker Swarm 模式的底層邏輯是一個通用的排程器和編排器。服務和任務抽象本身並不知道它們所實現的容器。理論上,您可以實現其他型別的任務,例如虛擬機器任務或非容器化程序任務。排程器和編排器對任務的型別是不可知的。但是,當前版本的 Docker 僅支援容器任務。
下圖顯示了 Swarm 模式如何接受服務建立請求並將任務排程到工作節點。


待處理服務
服務的配置方式可能導致 Swarm 中當前沒有任何節點可以執行其任務。在這種情況下,服務將保持在 `pending`(待處理)狀態。以下是服務可能保持在 `pending` 狀態的一些示例。
提示如果您只是想阻止部署服務,請將服務擴充套件到 0,而不是試圖以使其保持在 `pending` 狀態的方式來配置它。
如果所有節點都處於暫停或排空狀態,而您建立了一個服務,那麼該服務將處於待處理狀態,直到有節點可用。實際上,第一個可用的節點會獲得所有任務,因此在生產環境中這樣做並不好。
您可以為服務預留特定數量的記憶體。如果 Swarm 中沒有節點具有所需的記憶體量,則該服務將保持待處理狀態,直到有節點可以執行其任務。如果您指定一個非常大的值,例如 500 GB,那麼任務將永遠處於待處理狀態,除非您真的有可以滿足它的節點。
您可以對服務施加放置約束,而這些約束在特定時間可能無法得到滿足。
這種行為說明了任務的需求和配置與 Swarm 的當前狀態並非緊密相關。作為 Swarm 的管理員,您宣告 Swarm 的期望狀態,而管理器則與 Swarm 中的節點協同工作以建立該狀態。您無需對 Swarm 上的任務進行微觀管理。
複製服務和全域性服務
服務部署有兩種型別:複製服務和全域性服務。
對於複製服務,您可以指定要執行的相同任務的數量。例如,您決定部署一個包含三個副本的 HTTP 服務,每個副本都提供相同的內容。
全域性服務是在每個節點上執行一個任務的服務。沒有預先指定的任務數量。每次向 Swarm 新增一個節點時,編排器都會建立一個任務,排程器會將該任務分配給新節點。全域性服務的理想選擇是監控代理、防病毒掃描程式或您希望在 Swarm 的每個節點上執行的其他型別的容器。
下圖顯示了一個灰色的三服務副本和一個黑色的全域性服務。

