採用 Sidecar 容器

本節適用於為其工作負載採用新的內建sidecar 容器功能的人員。

正如部落格文章中所述,Sidecar 容器並非新概念。Kubernetes 允許在 Pod 中執行多個容器來實現此概念。但是,將 sidecar 容器作為常規容器執行存在許多限制,這些限制正在透過新的內建 sidecar 容器支援得到修復。

特性狀態: Kubernetes v1.33 [stable] (預設啟用:true)

目標

  • 瞭解對 sidecar 容器的需求
  • 能夠排查 sidecar 容器的問題
  • 瞭解通用“注入”sidecar 容器到任何工作負載的選項

準備工作

你需要擁有一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個節點(不作為控制平面主機)的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 遊樂場之一

你的 Kubernetes 伺服器版本必須是 1.29 或更高版本。

要檢查版本,請輸入 kubectl version

Sidecar 容器概述

Sidecar 容器是與主應用容器在同一個Pod 中執行的輔助容器。這些容器用於透過提供附加服務或功能(例如日誌記錄、監控、安全性或資料同步)來增強或擴充套件主*應用容器*的功能,而無需直接修改主應用程式程式碼。你可以在Sidecar 容器概念頁面中瞭解更多資訊。

Sidecar 容器的概念並非新鮮事物,並且存在多種實現此概念的方法。除了你(定義 Pod 的人)希望執行的 sidecar 容器之外,你還會發現一些附加元件會在 Pod 啟動前修改 Pod,從而新增額外的 sidecar 容器。注入這些額外 sidecar 的機制通常是准入控制器(MutatingAdmissionWebhook)。例如,服務網格附加元件可能會注入一個 sidecar,用於配置不同 Pod 之間的相互 TLS 和傳輸中加密。

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

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

內建 Sidecar 容器的優勢

使用 Kubernetes 對 Sidecar 容器的本地支援提供了多項優勢

  1. 你可以配置原生 sidecar 容器在初始化容器之前啟動。
  2. 內建 sidecar 容器可以被編寫為保證它們最後終止。一旦所有常規容器完成並終止,sidecar 容器將收到 SIGTERM 訊號而終止。如果 sidecar 容器未優雅關閉,將使用 SIGKILL 訊號終止它。
  3. 對於 Jobs,當 Pod 的 restartPolicy: OnFailurerestartPolicy: Never 時,原生 sidecar 容器不會阻止 Pod 完成。對於傳統的 sidecar 容器,需要特別注意處理這種情況。
  4. 此外,對於 Jobs,即使常規容器不會使用 Pod 的 restartPolicy: Never,內建 sidecar 容器一旦完成仍會持續重啟。

請參閱與 Init 容器的區別以瞭解更多資訊。

採用內建 sidecar 容器

從 Kubernetes 1.29 版本開始,SidecarContainers 功能門控處於 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 物件,這不會是問題。然而,有些工具會刪除未知欄位;如果你有這些工具,它們必須使用 v1.28+ 版本的 Kubernetes API 客戶端程式碼重新編譯。

檢查此問題的方法是使用 `kubectl describe pod` 命令以及已透過可變准入的 Pod。如果有任何工具刪除了新欄位(`restartPolicy:Always`),你將不會在命令輸出中看到它。

如果遇到此類問題,請建議工具或 Webhook 的作者使用其中一種修補策略來修改物件,而不是進行完整的物件更新。

Sidecar 的自動注入

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

例如,你可以關注 Istio 社群的討論。該討論探討了以下選項。

  1. 標記那些支援 sidecar 的 Pod。你可以使用節點標籤和節點親和性來標記支援 sidecar 容器的節點以及落在這些節點上的 Pod。
  2. 在注入時檢查節點相容性。在 sidecar 注入期間,你可以使用以下策略來檢查節點相容性:
    • 查詢節點版本並假設該功能門控在 v1.29+ 版本上已啟用
    • 查詢節點 Prometheus 指標並檢查功能啟用狀態
    • 假設節點正在以與 API 伺服器支援的版本偏差執行
    • 可能還有其他自定義方法來檢測節點相容性。
  3. 開發一個通用 Sidecar 注入器。通用 Sidecar 注入器的想法是將 Sidecar 容器作為常規容器以及原生 Sidecar 容器注入。並具有執行時邏輯來決定哪個將起作用。通用 Sidecar 注入器是浪費的,因為它將請求計數兩次,但可以被認為是特殊情況下的可行解決方案。
    • 一種方法是在原生 sidecar 容器啟動時檢測節點版本,如果該版本不支援 sidecar 功能,則立即退出。
    • 考慮執行時功能檢測設計
      • 定義一個空目錄,以便容器可以相互通訊
      • 注入一個初始化容器,我們稱之為 NativeSidecar,其 restartPolicy=Always
      • NativeSidecar 必須向一個空目錄寫入一個檔案,表示首次執行,並立即以退出碼 0 退出。
      • NativeSidecar 在重啟時(當支援原生 sidecar 時)檢查該檔案是否已存在於空目錄中,並修改它——表明內建 sidecar 容器受到支援且正在執行。
      • 注入常規容器,我們稱之為 OldWaySidecar
      • OldWaySidecar 啟動時檢查空目錄中是否存在檔案。
      • 如果檔案表明 NativeSidecar 未執行,則它假定 sidecar 功能不受支援,並將其作為 sidecar 執行。
      • 如果檔案指示 NativeSidecar 正在執行,它要麼什麼都不做並永遠休眠(在 Pod 的 restartPolicy=Always 的情況下),要麼立即以退出程式碼 0 退出(在 Pod 的 restartPolicy!=Always 的情況下)。

下一步

最後修改時間:2024 年 11 月 6 日太平洋標準時間上午 10:05:清理教程:pod-sidecar-containers.md (96d69d62fe)