Pod

Pod 是您可以在 Kubernetes 中建立與管理的最小可部署運算單元。

Pod(如同鯨魚群或豆莢)是一組一個或多個容器,具有共用儲存和網路資源,以及如何執行容器的規範。Pod 的內容始終共置和共同排程,並在共用環境中執行。Pod 模擬應用程式特定的「邏輯主機」:它包含一個或多個相對緊密耦合的應用程式容器。在非雲端環境中,在同一實體或虛擬機器上執行的應用程式,類似於在同一邏輯主機上執行的雲端應用程式。

除了應用程式容器之外,Pod 也可以包含在 Pod 啟動期間執行的初始化容器。您也可以注入臨時容器以偵錯執行中的 Pod。

什麼是 Pod?

Pod 的共用情境是一組 Linux 命名空間、cgroup 以及潛在的其他隔離機制,這些機制與隔離 容器 的機制相同。在 Pod 的情境中,個別應用程式可能會套用更進一步的子隔離。

Pod 類似於一組具有共用命名空間和共用檔案系統卷的容器。

Kubernetes 叢集中的 Pod 主要有兩種使用方式

  • 執行單一容器的 Pod。「每個 Pod 一個容器」模型是最常見的 Kubernetes 使用情境;在這種情況下,您可以將 Pod 視為單一容器的包裝器;Kubernetes 管理的是 Pod,而不是直接管理容器。

  • 執行需要協同運作之多個容器的 Pod。Pod 可以封裝由多個共同部署的容器組成的應用程式,這些容器緊密耦合且需要共用資源。這些共同部署的容器形成一個單一的凝聚單元。

    在單一 Pod 中將多個共同部署和共同管理的容器分組是一種相對進階的使用情境。您應該僅在容器緊密耦合的特定情況下使用此模式。

    您不需要執行多個容器來提供複製(用於彈性或容量);如果您需要多個副本,請參閱工作負載管理

使用 Pod

以下是一個 Pod 的範例,其中包含一個執行 nginx:1.14.2 映像檔的容器。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

若要建立如上所示的 Pod,請執行以下指令

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml

Pod 通常不是直接建立的,而是使用工作負載資源建立的。請參閱使用 Pod 以取得更多關於 Pod 如何與工作負載資源搭配使用的資訊。

用於管理 Pod 的工作負載資源

通常您不需要直接建立 Pod,即使是單例 Pod 也是如此。相反地,請使用工作負載資源(例如 DeploymentJob)來建立它們。如果您的 Pod 需要追蹤狀態,請考慮 StatefulSet 資源。

每個 Pod 都旨在執行給定應用程式的單一執行個體。如果您想要水平擴充您的應用程式(透過執行更多執行個體來提供更多整體資源),您應該使用多個 Pod,每個執行個體一個 Pod。在 Kubernetes 中,這通常稱為複製。複寫的 Pod 通常由工作負載資源及其控制器以群組方式建立和管理。

請參閱Pod 和控制器以取得更多關於 Kubernetes 如何使用工作負載資源及其控制器來實作應用程式擴充和自動修復的資訊。

Pod 原生提供兩種用於其組成容器的共用資源:網路儲存

使用 Pod

您很少會在 Kubernetes 中直接建立個別的 Pod,即使是單例 Pod 也是如此。這是因為 Pod 被設計為相對短暫、可拋棄的實體。當 Pod 被建立時(直接由您建立,或間接由控制器建立),新的 Pod 會被排程在您叢集中的一個節點上執行。Pod 會保留在該節點上,直到 Pod 執行完成、Pod 物件被刪除、Pod 因資源不足而被驅逐,或節點故障為止。

Pod 的名稱必須是有效的 DNS 子網域值,但這可能會為 Pod 主機名稱產生非預期的結果。為了獲得最佳相容性,名稱應遵循更嚴格的 DNS 標籤規則。

Pod 作業系統

功能狀態: Kubernetes v1.25 [stable]

您應該將 .spec.os.name 欄位設定為 windowslinux,以指示您希望 Pod 在哪個作業系統上執行。這兩個是 Kubernetes 目前唯一支援的作業系統。未來,此列表可能會擴充。

在 Kubernetes v1.32 中,.spec.os.name 的值不會影響 kube-scheduler 選擇哪個節點來執行 Pod。在任何具有多個作業系統來執行節點的叢集中,您都應該在每個節點上正確設定 kubernetes.io/os 標籤,並使用基於作業系統標籤的 nodeSelector 來定義 Pod。kube-scheduler 會根據其他標準將您的 Pod 指派給節點,並且可能成功或不成功地選擇合適的節點放置位置,其中節點作業系統適合該 Pod 中的容器。Pod 安全性標準也使用此欄位來避免強制執行與作業系統無關的策略。

Pod 和控制器

您可以使用工作負載資源來為您建立和管理多個 Pod。資源的控制器處理複製和推出,以及在 Pod 故障時的自動修復。例如,如果節點故障,控制器會注意到該節點上的 Pod 已停止運作,並建立一個替換 Pod。排程器會將替換 Pod 放置到健康的節點上。

以下是一些管理一個或多個 Pod 的工作負載資源範例

Pod 範本

工作負載資源的控制器從 Pod 範本 建立 Pod,並代表您管理這些 Pod。

PodTemplate 是用於建立 Pod 的規格,包含在工作負載資源中,例如 DeploymentsJobsDaemonSets

工作負載資源的每個控制器都使用工作負載物件內的 PodTemplate 來建立實際的 Pod。PodTemplate 是您用來執行應用程式的任何工作負載資源的期望狀態的一部分。

當您建立 Pod 時,您可以在 Pod 範本中為在 Pod 中執行的容器包含環境變數

下面的範例是一個簡單 Job 的資訊清單,其中包含一個 template,該範本啟動一個容器。該 Pod 中的容器印出訊息然後暫停。

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # This is the pod template
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # The pod template ends here

修改 Pod 範本或切換到新的 Pod 範本對已存在的 Pod 沒有直接影響。如果您變更工作負載資源的 Pod 範本,則該資源需要建立使用更新範本的替換 Pod。

例如,StatefulSet 控制器確保執行的 Pod 符合每個 StatefulSet 物件的目前 Pod 範本。如果您編輯 StatefulSet 以變更其 Pod 範本,StatefulSet 會開始根據更新的範本建立新的 Pod。最終,所有舊的 Pod 都會被新的 Pod 取代,並且更新完成。

每個工作負載資源都實作了自己的規則來處理 Pod 範本的變更。如果您想更詳細地了解 StatefulSet,請閱讀 StatefulSet 基礎教學中的更新策略

在節點上,kubelet 不會直接觀察或管理任何關於 Pod 範本和更新的細節;這些細節都被抽象化了。這種抽象化和關注點分離簡化了系統語意,並使得在不變更現有程式碼的情況下擴充叢集的行為成為可能。

Pod 更新和替換

如前一節所述,當工作負載資源的 Pod 範本變更時,控制器會根據更新的範本建立新的 Pod,而不是更新或修補現有的 Pod。

Kubernetes 不會阻止您直接管理 Pod。可以就地更新執行中 Pod 的某些欄位。但是,Pod 更新操作(例如 patchreplace)有一些限制

  • 關於 Pod 的大多數中繼資料都是不可變的。例如,您無法變更 namespacenameuidcreationTimestamp 欄位;generation 欄位是唯一的。它只接受會遞增欄位目前值的更新。

  • 如果設定了 metadata.deletionTimestamp,則無法將新條目新增至 metadata.finalizers 列表。

  • Pod 更新可能不會變更 spec.containers[*].imagespec.initContainers[*].imagespec.activeDeadlineSecondsspec.tolerations 以外的欄位。對於 spec.tolerations,您只能新增新的條目。

  • 當更新 spec.activeDeadlineSeconds 欄位時,允許兩種更新類型

    1. 將未指派的欄位設定為正數;
    2. 將欄位從正數更新為較小的非負數。

資源共享和通訊

Pod 能夠在其組成容器之間實現資料共享和通訊。

Pod 中的儲存

Pod 可以指定一組共用儲存。Pod 中的所有容器都可以存取共用卷,允許這些容器共享資料。卷也允許 Pod 中的持久資料在其中一個容器需要重新啟動的情況下倖存下來。請參閱儲存以取得更多關於 Kubernetes 如何實作共用儲存並使其可供 Pod 使用的資訊。

Pod 網路

每個 Pod 都會針對每個位址族系指派一個唯一的 IP 位址。Pod 中的每個容器都共用網路命名空間,包括 IP 位址和網路埠。在 Pod 內部(且僅限在內部),屬於 Pod 的容器可以使用 localhost 相互通訊。當 Pod 中的容器與Pod 外部的實體通訊時,它們必須協調如何使用共用網路資源(例如埠)。在 Pod 內部,容器共用一個 IP 位址和埠空間,並且可以透過 localhost 找到彼此。Pod 中的容器也可以使用標準的程序間通訊(例如 SystemV 號誌或 POSIX 共用記憶體)相互通訊。不同 Pod 中的容器具有不同的 IP 位址,並且無法在沒有特殊設定的情況下透過作業系統層級的 IPC 通訊。想要與在不同 Pod 中執行的容器互動的容器可以使用 IP 網路進行通訊。

Pod 內的容器將系統主機名稱視為與 Pod 的已配置 name 相同。在網路章節中有更多關於此內容的資訊。

Pod 安全性設定

若要設定 Pod 和容器的安全性約束,您可以使用 Pod 規格中的 securityContext 欄位。此欄位讓您可以細緻地控制 Pod 或個別容器可以執行的操作。例如

  • 捨棄特定的 Linux 功能,以避免 CVE 的影響。
  • 強制 Pod 中的所有程序以非 root 使用者或特定使用者或群組 ID 執行。
  • 設定特定的 seccomp 設定檔。
  • 設定 Windows 安全性選項,例如容器是否以 HostProcess 執行。

靜態 Pod

靜態 Pod 由特定節點上的 kubelet daemon 直接管理,而沒有 API 伺服器 觀察它們。雖然大多數 Pod 由控制平面管理(例如,Deployment),但對於靜態 Pod,kubelet 直接監督每個靜態 Pod(並在它故障時重新啟動它)。

靜態 Pod 始終綁定到特定節點上的Kubelet。靜態 Pod 的主要用途是執行自我託管的控制平面:換句話說,使用 kubelet 來監督個別的控制平面元件

kubelet 會自動嘗試在 Kubernetes API 伺服器上為每個靜態 Pod 建立一個鏡像 Pod。這表示在節點上執行的 Pod 在 API 伺服器上是可見的,但無法從那裡控制。請參閱指南建立靜態 Pod 以取得更多資訊。

具有多個容器的 Pod

Pod 的設計目的是支援形成凝聚服務單元的多個協同運作的程序(作為容器)。Pod 中的容器會自動共同部署和共同排程在叢集中相同的實體或虛擬機器上。容器可以共享資源和相依性、相互通訊,並協調終止的時間和方式。

Kubernetes 叢集中的 Pod 主要有兩種使用方式

  • 執行單一容器的 Pod。「每個 Pod 一個容器」模型是最常見的 Kubernetes 使用情境;在這種情況下,您可以將 Pod 視為單一容器的包裝器;Kubernetes 管理的是 Pod,而不是直接管理容器。
  • 執行需要協同運作之多個容器的 Pod。Pod 可以封裝由多個共同部署的容器組成的應用程式,這些容器緊密耦合且需要共用資源。這些共同部署的容器形成一個單一的凝聚服務單元,例如,一個容器為公眾提供儲存在共用卷中的資料,而另一個獨立的 邊車容器 重新整理或更新這些檔案。Pod 將這些容器、儲存資源和短暫的網路身分識別包裝在一起作為一個單元。

例如,您可能有一個容器充當共用卷中檔案的 Web 伺服器,以及一個單獨的 邊車容器,它從遠端來源更新這些檔案,如下圖所示

Pod creation diagram

有些 Pod 除了初始化容器之外,還有應用程式容器。預設情況下,初始化容器會在應用程式容器啟動之前執行並完成。

您也可以擁有邊車容器,為主要應用程式 Pod 提供輔助服務(例如:服務網格)。

功能狀態: Kubernetes v1.29 [beta]

預設情況下啟用,SidecarContainers 功能閘道 允許您為初始化容器指定 restartPolicy: Always。設定 Always 重新啟動策略可確保您設定它的容器被視為在 Pod 的整個生命週期中保持運作的邊車。您明確定義為邊車容器的容器會在主要應用程式 Pod 之前啟動,並保持運作直到 Pod 關閉。

容器探針

探針是 kubelet 在容器上定期執行的診斷。為了執行診斷,kubelet 可以調用不同的動作

  • ExecAction(在容器執行期環境的幫助下執行)
  • TCPSocketAction(由 kubelet 直接檢查)
  • HTTPGetAction(由 kubelet 直接檢查)

您可以在 Pod 生命周期文件中閱讀更多關於探針的資訊。

下一步

若要理解 Kubernetes 為何將常見的 Pod API 包裝在其他資源中(例如 StatefulSetsDeployments),您可以閱讀先前的技術,包括

上次修改時間:2024 年 11 月 12 日 星期二 10:03 AM PST:Update _index.md (85b76bf80a)