〔CKS 筆記整理〕揭秘 Kubernetes Pod :Pause 容器、共享網路與資源管理

摘要

本文旨在探討 Kubernetes Pod 的設計核心。文章將深入淺出地解說共享網路命名空間的機制、Pause Container 的功能,以及 Sidecar 模式在啟動順序與資源管理上的挑戰,整理對 Pod 生命週期管理的觀念。

對於初學者而言,Pod 常被簡單定義為「一個或多個容器的集合」,但這個定義並未完全解釋其設計目的。Pod 的核心概念,其實是為了在雲端環境中模擬一台「邏輯主機(Logical Host)」。這決定了應用程式之間的通訊模式,以及多個容器在同一環境下運作時,因緊密耦合(Tightly Coupled)所產生的影響。

共享網路:優勢與限制

當多個容器運行在同一個 Pod 時,它們的關係類似於在同一台虛擬機(VM)上運行的多個處理程序(Process)。這種關係建立在「共享網路命名空間(Shared Network Namespace)」之上,意即 Pod 內的所有容器都共用同一個 Cluster IP 位址與 Port 空間。

這樣的架構設計帶來了以下優勢:

  • 低延遲通訊:容器間可透過 localhost 直接通訊,繞過 NAT 與路由設定。
  • 簡化發現機制:無需依賴服務發現(Service Discovery)或外部 DNS。
  • 信任域內:視為內部網路,通常無需複雜的認證機制即可互連。

然而,這也帶來了實務上的限制。開發者必須像在單機環境一樣,妥善規劃 Port 的使用。若兩個容器嘗試監聽同一個 Port(例如都佔用 80 Port),將導致 Address already in use 錯誤,並使容器啟動失敗。此外,在設定監聽介面(Bind Interface)時,需根據用途嚴格區分(例如):

用途建議綁定介面典型範例說明
僅供內部使用127.0.0.1 (Localhost)Cloud SQL Auth Proxy僅允許同 Pod 內的主程式連線,避免將管理介面暴露給外部,安全性較高。
需接收外部流量0.0.0.0 (Any)Envoy / Nginx Proxy必須監聽所有介面,才能接收來自 Pod 外部(如 Service 或 Ingress)的流量。

共享儲存:檔案系統的運用

除了網路,檔案系統的共享是「邏輯主機」概念的另一大支柱。在傳統伺服器上,不同的處理程序可以讀寫同一個目錄下的檔案;在 Pod 中,我們則透過 Volume 來實現這項功能。

最常見的例子是 emptyDir。當多個容器掛載同一個 emptyDir Volume 時,它們就像是存取本機上的同一個暫存資料夾。

  • 運作模式:容器 A 將日誌寫入 /var/log/app.log(掛載點),容器 B(Sidecar)可以直接讀取該路徑下的檔案並轉送至 Log Server。
  • 實務意義:如果沒有共享儲存,Sidecar 就難以取得主程式產生的靜態檔案或日誌。這進一步強化了 Pod 的設計哲學:容器之間不只共享 IP,也能共享儲存空間。

基礎設施的錨點:Pause Container

為了維持共享環境的穩定,Kubernetes 引入了一個輕量級元件:Pause Container(或稱 Infra Container)。

當 Kubelet 啟動 Pod 時,最先啟動的並非應用程式,而是這個沙箱容器。Pause Container 的主要職責是建立並持有 Linux Namespaces(包含 Network、IPC 與 UTS 等)。隨後啟動的業務容器與輔助容器,則是透過加入這個已建立的命名空間來運作。

這是一種將「網路環境」與「應用程式生命週期」解耦的設計。即使主程式因錯誤而重啟,只要 Pause Container 仍在運行,Pod 的 IP 位址就不會改變,既有的路由規則也能維持,大幅降低了應用程式復原時的網路波動。

如果你有權限登入 Kubernetes 的 Worker Node,可以試試看使用以下指令找到這個關鍵元件:

sudo crictl ps | grep pause

Sidecar 模式與啟動順序

基於 pod 的特性,Sidecar Pattern 常被用來處理輔助性任務,例如將 Service Mesh 的代理伺服器或日誌收集器獨立為 Sidecar 容器,讓主程式的容器專注於核心業務。然而,容器的啟動順序一直是實務上的痛點,特別是在 Kubernetes v1.29 版本前後有顯著差異:

版本啟動行為潛在風險 (Race Condition)最佳實務
v1.28 以前無順序保證
容器平行啟動
主程式比 Sidecar 先啟動,導致連線資料庫失敗,引發 CrashLoopBackOff。在主程式啟動腳本中加入 sleep 或迴圈偵測邏輯,等待 Sidecar 就緒。
v1.29 以後原生支援 Sidecar
依序啟動
問題已解決。平台確保 Sidecar 完全就緒後,才啟動主程式。使用 initContainers 並設定 restartPolicy: Always,定義原生 Sidecar。

資源共享與管理

除了網路與啟動順序,資源管理也是不可忽視的一環。Pod 的資源需求是內部所有容器的總和。若未妥善設定資源限制(Resource Limits),單一 Sidecar 容器(如日誌代理程式)若發生記憶體洩漏,可能會耗盡節點資源,或觸發 Pod 層級的驅逐機制,導致主程式一同被終止。因此,為每個容器設定獨立的資源配額是維持穩定性的關鍵。

此外,進階的使用者可以透過設定 shareProcessNamespace: true 來打破容器間的 PID 隔離。這允許在 Sidecar 中使用 ps 指令觀察主程式的狀態。

可以嘗試在測試環境開啟了 shareProcessNamespace: true,你可以進入 Sidecar 容器驗證是否能看到其他容器的 Process:

# 在 Sidecar 中也能看到主程式的 Process
kubectl exec -it <pod-name> -c sidecar -- ps aux

然而,啟用此功能需特別留意安全風險,請僅在 labs 或 測試環境中開啟。由於 Linux 的環境變數可透過 /proc/{PID}/environ 讀取,若應用程式將機敏資訊(如密碼或金鑰)儲存於環境變數中,共享 PID Namespace 將導致這些資訊對 Pod 內的所有容器可見。除非是為了短期除錯,否則不建議在生產環境中長期開啟此選項,以避免潛在的資訊外洩或隔離性破壞。

總結來說,理解 Pod 作為邏輯主機的機制,從共享網路的低延遲優勢,到 Pause Container 提供的穩定基礎,以及 Sidecar 模式的運作細節,有助於更準確地利用 pod 的特性,在享受 Kubernetes 便利性的同時,也確保服務運行的穩定性。

Extended Reference & FYI

This Content is Authored by the writer, with AI-assisted proofreading and SEO optimization.