採用 Sidecar 容器

本節內容與採用新的內建 Sidecar 容器 功能來處理其工作負載的人員相關。

Sidecar 容器並非新概念,如 部落格文章 中所述。Kubernetes 允許在 Pod 中執行多個容器來實作此概念。然而,以一般容器方式執行 Sidecar 容器有許多限制,而新的內建 Sidecar 容器支援正在解決這些限制。

功能狀態: Kubernetes v1.29 [beta] (預設啟用:true)

目標

  • 瞭解 Sidecar 容器的需求
  • 能夠排除 Sidecar 容器的問題
  • 瞭解將 Sidecar 容器通用 "注入" 到任何工作負載的選項

開始之前

您需要有一個 Kubernetes 叢集,並且必須配置 kubectl 命令列工具以與您的叢集通訊。建議在至少有兩個節點且這些節點未充當控制平面主機的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用以下 Kubernetes playground 之一

您的 Kubernetes 伺服器版本必須為 1.29 或更高版本。若要檢查版本,請輸入 kubectl version

Sidecar 容器概觀

Sidecar 容器是與主要應用程式容器在同一個 Pod 中一起執行的輔助容器。這些容器用於增強或擴展主要應用程式容器的功能,透過提供額外的服務或功能,例如記錄、監控、安全性或資料同步,而無需直接修改主要應用程式程式碼。您可以在Sidecar 容器 概念頁面中閱讀更多資訊。

Sidecar 容器的概念並非新穎,並且有許多實作方式。除了您 (定義 Pod 的人員) 想要執行的 Sidecar 容器之外,您也可能會發現某些 addons 會在 Pod 啟動執行之前修改 Pod,以便加入額外的 Sidecar 容器。注入這些額外 Sidecar 的機制通常是變更 Webhook。例如,服務網格 addon 可能會注入一個 Sidecar,用於配置不同 Pod 之間的相互 TLS 和傳輸中加密。

雖然 Sidecar 容器的概念並非新穎,但 Kubernetes 中此功能的原生實作卻是新的。與每個新功能一樣,採用此功能可能會帶來某些挑戰。

本教學課程探討終端使用者以及 Sidecar 容器作者可能會遇到的挑戰和解決方案。

內建 Sidecar 容器的優點

使用 Kubernetes 原生支援 Sidecar 容器提供多項優點

  1. 您可以配置原生 Sidecar 容器在 init 容器 之前啟動。
  2. 可以編寫內建 Sidecar 容器以保證它們最後終止。一旦所有常規容器完成並終止,Sidecar 容器將以 SIGTERM 訊號終止。如果 Sidecar 容器未正常關閉,將使用 SIGKILL 訊號終止它。
  3. 在 Jobs 中,當 Pod 的 restartPolicy: OnFailurerestartPolicy: Never 時,原生 Sidecar 容器不會阻止 Pod 完成。對於舊式 Sidecar 容器,需要特別注意處理這種情況。
  4. 此外,在 Jobs 中,內建 Sidecar 容器在完成後會持續重新啟動,即使常規容器在 Pod 的 restartPolicy: Never 情況下也不會重新啟動。

請參閱與 init 容器的差異以瞭解更多資訊。

採用內建 Sidecar 容器

SidecarContainers 功能閘道 從 Kubernetes 1.29 版本開始處於 Beta 狀態,並且預設為啟用。某些叢集可能已停用此功能,或安裝了與此功能不相容的軟體。

當發生這種情況時,Pod 可能會被拒絕,或者 Sidecar 容器可能會阻止 Pod 啟動,導致 Pod 無法使用。這種情況很容易偵測到,因為 Pod 只是卡在初始化階段。然而,通常不清楚是什麼原因導致了問題。

以下是在為工作負載採用 Sidecar 容器時可以採取的注意事項和疑難排解步驟。

確保功能閘道已啟用

作為第一步,請確保 API 伺服器和節點都處於 Kubernetes v1.29 或更高版本。在節點執行較早版本 (未啟用此功能) 的叢集上,此功能將會失效。

您應確保控制平面中的 API 伺服器和所有節點都已啟用功能閘道。

檢查功能閘道是否啟用的方法之一是執行類似這樣的命令

  • 針對 API 伺服器

    kubectl get --raw /metrics | grep kubernetes_feature_enabled | grep SidecarContainers
    
  • 針對個別節點

    kubectl get --raw /api/v1/nodes/<node-name>/proxy/metrics | grep kubernetes_feature_enabled | grep SidecarContainers
    

如果您看到類似這樣的內容

kubernetes_feature_enabled{name="SidecarContainers",stage="BETA"} 1

這表示該功能已啟用。

檢查第三方工具和變更 Webhook

如果您在驗證功能時遇到問題,則可能表示其中一個第三方工具或變更 Webhook 已損壞。

SidecarContainers 功能閘道啟用時,Pod 的 API 中會新增一個欄位。某些工具或變更 Webhook 可能是在較早版本的 Kubernetes API 上建置的。

如果工具有使用各種修補策略來修改 Pod 物件,並原封不動地傳遞未知的欄位,這將不會是問題。然而,有些工具會移除未知的欄位;如果您使用這些工具,則必須使用 Kubernetes API 客户端程式碼 v1.28+ 版本重新編譯。

檢查此問題的方法是使用 kubectl describe pod 指令,針對您的 Pod 執行,該 Pod 已經通過 mutating admission。如果任何工具移除了新的欄位 (restartPolicy:Always),您將不會在指令輸出中看到它。

如果您遇到類似的問題,請建議工具或 webhook 的作者使用修補策略之一來修改物件,而不是完整物件更新。

自動注入邊車容器 (sidecar container)

如果您正在使用會自動注入邊車容器 (sidecar container) 的軟體,您可以遵循幾種可能的策略,以確保可以使用原生邊車容器 (native sidecar container)。所有策略通常都是您可以選擇的選項,以決定要注入邊車容器 (sidecar container) 的 Pod 是否會落在支援此功能的節點 (Node) 上。

例如,您可以參考Istio 社群中的這段對話。該討論探討了以下列出的選項。

  1. 標記會落在支援邊車容器 (sidecar container) 的節點 (Node) 上的 Pod。您可以使用節點標籤 (node labels) 和節點親和性 (node affinity) 來標記支援邊車容器 (sidecar container) 的節點 (Node) 以及落在這些節點 (Node) 上的 Pod。
  2. 在注入時檢查節點 (Node) 的相容性。在邊車容器 (sidecar container) 注入期間,您可以使用以下策略來檢查節點 (Node) 相容性
    • 查詢節點 (Node) 版本,並假設在 1.29+ 版本中已啟用功能閘道 (feature gate)
    • 查詢節點 (Node) Prometheus 指標,並檢查功能啟用狀態
    • 假設節點 (Node) 正在以來自 API 伺服器 (API server) 的支援的版本偏差 (version skew) 執行
    • 可能還有其他自訂方法可以偵測節點 (Node) 相容性。
  3. 開發通用邊車容器 (sidecar container) 注入器。通用邊車容器 (sidecar container) 注入器的概念是同時注入邊車容器 (sidecar container) 作為常規容器 (regular container) 和原生邊車容器 (native sidecar container)。並具有執行階段邏輯來決定哪一個可以運作。通用邊車容器 (sidecar container) 注入器很浪費資源,因為它會計算兩次請求,但可以被視為特殊情況下可行的解決方案。
    • 一種方法是在原生邊車容器 (native sidecar container) 啟動時偵測節點 (Node) 版本,如果該版本不支援邊車容器 (sidecar container) 功能,則立即退出。
    • 考慮執行階段功能偵測設計
      • 定義一個 emptyDir,以便容器 (container) 彼此通訊
      • 注入一個 init 容器 (init container),我們稱之為 NativeSidecar,並設定 restartPolicy=Always
      • NativeSidecar 必須寫入一個檔案到 emptyDir,指示首次執行,並立即以退出代碼 0 退出。
      • NativeSidecar 在重新啟動時(當原生邊車容器 (native sidecar container) 受到支援時)檢查該檔案是否已存在於 emptyDir 中,並變更它 - 表示內建邊車容器 (built-in sidecar container) 受到支援且正在執行。
      • 注入常規容器 (regular container),我們稱之為 OldWaySidecar
      • OldWaySidecar 在啟動時檢查 emptyDir 中是否存在檔案。
      • 如果該檔案指示 NativeSidecar 未執行,則 OldWaySidecar 會假設邊車容器 (sidecar container) 功能不受支援,並假設自己是邊車容器 (sidecar container) 來運作。
      • 如果該檔案指示 NativeSidecar 正在執行,則 OldWaySidecar 要麼什麼都不做並永遠休眠(在 Pod 的 restartPolicy=Always 的情況下),要麼立即以退出代碼 0 退出(在 Pod 的 restartPolicy!=Always 的情況下)。

接下來

最後修改時間:2024 年 11 月 06 日 太平洋標準時間上午 10:05:Clean up a tutorial: pod-sidecar-containers.md (96d69d62fe)