採用 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 容器的本地支援提供了多項優勢
- 你可以配置原生 sidecar 容器在初始化容器之前啟動。
- 內建 sidecar 容器可以被編寫為保證它們最後終止。一旦所有常規容器完成並終止,sidecar 容器將收到
SIGTERM
訊號而終止。如果 sidecar 容器未優雅關閉,將使用SIGKILL
訊號終止它。 - 對於 Jobs,當 Pod 的
restartPolicy: OnFailure
或restartPolicy: Never
時,原生 sidecar 容器不會阻止 Pod 完成。對於傳統的 sidecar 容器,需要特別注意處理這種情況。 - 此外,對於 Jobs,即使常規容器不會使用 Pod 的
restartPolicy: Never
,內建 sidecar 容器一旦完成仍會持續重啟。
請參閱與 Init 容器的區別以瞭解更多資訊。
採用內建 sidecar 容器
從 Kubernetes 1.29 版本開始,SidecarContainers
功能門控處於 Beta 狀態,並預設啟用。某些叢集可能已停用此功能或安裝了與此功能不相容的軟體。
發生這種情況時,Pod 可能會被拒絕,或者 sidecar 容器可能會阻止 Pod 啟動,使 Pod 無法使用。這種情況很容易檢測,因為 Pod 只是卡在初始化階段。然而,通常不清楚是什麼導致了問題。
以下是為工作負載採用 sidecar 容器時可以考慮和採取的故障排除步驟。
確保功能門控已啟用
作為第一步,請確保 API 伺服器和節點都執行 Kubernetes v1.29 或更高版本。在節點執行早期版本(未啟用該功能)的叢集上,該功能將無法正常工作。
注意
此功能可以在版本 1.28 的節點上啟用。內建 sidecar 容器的終止行為在版本 1.28 中有所不同,不建議將 sidecar 的行為調整為該行為。但是,如果唯一關心的是啟動順序,則上述語句可以更改為在啟用了功能門控的節點上執行版本 1.28。你應該確保控制平面中的 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 的作者使用其中一種修補策略來修改物件,而不是進行完整的物件更新。
注意
可變 Webhook 可能會根據某些條件更新 Pod。因此,sidecar 容器可能對某些 Pod 起作用,而對其他 Pod 失敗。Sidecar 的自動注入
如果您正在使用自動注入 sidecar 的軟體,您可以遵循以下幾種策略來確保可以使用原生 sidecar 容器。所有策略通常都是您可以選擇的選項,以決定 sidecar 將注入的 Pod 是否會落在支援該功能的節點上。
例如,你可以關注 Istio 社群的討論。該討論探討了以下選項。
- 標記那些支援 sidecar 的 Pod。你可以使用節點標籤和節點親和性來標記支援 sidecar 容器的節點以及落在這些節點上的 Pod。
- 在注入時檢查節點相容性。在 sidecar 注入期間,你可以使用以下策略來檢查節點相容性:
- 查詢節點版本並假設該功能門控在 v1.29+ 版本上已啟用
- 查詢節點 Prometheus 指標並檢查功能啟用狀態
- 假設節點正在以與 API 伺服器支援的版本偏差執行
- 可能還有其他自定義方法來檢測節點相容性。
- 開發一個通用 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
的情況下)。
下一步
- 瞭解更多關於sidecar 容器的資訊。