服務如何運作

要在 Docker 引擎處於 Swarm 模式時部署應用程式映像,您需要建立服務。通常,服務是某些較大型應用程式環境中的微服務映像。服務的範例可能包含 HTTP 伺服器、資料庫或您希望在分散式環境中執行的任何其他類型的可執行程式。

建立服務時,您需要指定要使用的容器映像以及要在執行中容器內執行的指令。您也可以定義服務的選項,包括

  • Swarm 在 Swarm 外部提供服務的埠
  • 服務用於連線到 Swarm 中其他服務的覆蓋網路
  • CPU 和記憶體限制和保留
  • 滾動更新策略
  • 要在 Swarm 中執行的映像複本數量

服務、任務和容器

將服務部署到 Swarm 時,Swarm 管理器會接受您的服務定義作為服務的所需狀態。然後,它會將服務排程在 Swarm 中的節點上,作為一個或多個複本任務。任務在 Swarm 中的節點上彼此獨立執行。

例如,假設您想要在 HTTP 聆聽器的三個執行個體之間進行負載平衡。下圖顯示具有三個複本的 HTTP 聆聽器服務。三個聆聽器執行個體中的每一個都是 Swarm 中的一個任務。

 HTTP listener service with three replicas

容器是一個隔離的程序。在 Swarm 模式模型中,每個任務都會叫用一個容器。任務類似於排程器放置容器的「插槽」。容器啟動後,排程器會辨識任務處於執行狀態。如果容器未通過健康檢查或終止,則任務會終止。

任務和排程

任務是 Swarm 內排程的原子單位。當您透過建立或更新服務來宣告所需的服務狀態時,協調器會透過排程任務來實現所需的狀態。例如,您定義一個服務,指示協調器始終保持三個 HTTP 聆聽器執行個體在執行中。協調器會透過建立三個任務來回應。每個任務都是排程器透過產生容器來填滿的插槽。容器是任務的執行個體。如果 HTTP 聆聽器任務後續未通過健康檢查或當機,協調器會建立一個新的複本任務,以產生一個新的容器。

任務是一種單向機制。它會以單調方式經歷一系列狀態:已指派、已準備、執行中等等。如果任務失敗,協調器會移除任務及其容器,然後根據服務指定的所需狀態建立新的任務來取代它。

Docker Swarm 模式的底層邏輯是一個通用的排程器和協調器。服務和任務抽象本身並不知道它們所實作的容器。假設您可以實作其他類型的任務,例如虛擬機器任務或非容器化程序任務。排程器和協調器與任務的類型無關。但是,目前版本的 Docker 只支援容器任務。

下圖顯示 Swarm 模式如何接受服務建立請求,以及如何將任務排程到工作節點。

Services flow

擱置中的服務

服務的設定方式可能導致 Swarm 中目前沒有任何節點可以執行其任務。在這種情況下,服務會保持 `pending` 狀態。以下是一些服務可能保持 `pending` 狀態的範例。

**秘訣**

如果您只想防止服務被部署,請將服務縮放為 0,而不是嘗試將其設定為保持 `pending` 狀態。

  • 如果所有節點都已暫停或已清空,並且您建立服務,則該服務會保持擱置狀態,直到有節點可用為止。實際上,第一個可用的節點會取得所有任務,因此在生產環境中,這並不是一個好做法。

  • 您可以為服務保留特定數量的記憶體。如果 Swarm 中沒有節點具有所需的記憶體量,則服務會保持擱置狀態,直到可以執行其任務的節點可用為止。如果您指定一個非常大的值(例如 500 GB),則任務會永遠保持擱置狀態,除非您真的有一個可以滿足它的節點。

  • 您可以對服務施加放置限制,而這些限制在特定時間可能無法滿足。

此行為說明您的任務需求和設定與 Swarm 的目前狀態並未緊密關聯。作為 Swarm 的管理員,您宣告 Swarm 的所需狀態,而管理器會與 Swarm 中的節點合作以建立該狀態。您不需要微觀管理 Swarm 上的任務。

複本和全域服務

服務部署有兩種類型:複本和全域。

對於複本服務,您需要指定要執行的相同任務數量。例如,您決定部署具有三個複本的 HTTP 服務,每個複本都提供相同的內容。

全域服務是一種在每個節點上運行一個任務的服務。任務數量沒有預先指定。每次向 Swarm 添加節點時,協調器都會創建一個任務,並且排程器會將該任務分配給新節點。適合全域服務的候選者包括監控代理、防毒軟體掃描器或其他您想要在 Swarm 中每個節點上運行的容器類型。

下圖顯示了三個服務副本(灰色)和一個全域服務(黑色)。

Global vs replicated services

深入瞭解

  • 瞭解 Swarm 模式節點如何運作。
  • 瞭解 Swarm 模式中PKI 的運作方式。