本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

APIServer dry-run 和 kubectl diff

宣告式配置管理,又稱配置即程式碼,是 Kubernetes 的主要優勢之一。它允許使用者提交叢集的期望狀態,並跟蹤不同版本,透過 CI/CD 流水線改進審計和自動化。Apply 工作組正在努力彌補一些不足,並很高興地宣佈 Kubernetes 1.13 將伺服器端 Dry-Run 和 kubectl diff 提升到 Beta 階段。這兩個功能是 Kubernetes 宣告式模型的重大改進。

挑戰

為了在 Kubernetes 中獲得無縫的宣告式體驗,仍缺少一些部分,我們試圖解決其中一些問題

  • 雖然編譯器和 linter 在檢測程式碼拉取請求中的錯誤方面做得很好,但 Kubernetes 配置檔案缺少良好的驗證。現有的解決方案是執行 kubectl apply --dry-run,但這會執行一個**本地** Dry-Run,它不與伺服器通訊:它沒有伺服器驗證,也不會透過驗證准入控制器。例如,自定義資源名稱只在伺服器上進行驗證,因此本地 Dry-Run 無濟於事。
  • 由於多種原因,可能很難知道伺服器將如何應用您的物件
    • 預設值會設定一些可能意想不到的值,
    • 變更 Webhook 可能會設定欄位或覆蓋/更改某些值。
    • 補丁和合並可能會產生令人驚訝的效果,並導致意想不到的物件。例如,很難知道列表在合併後將如何排序。

工作組已嘗試解決這些問題。

APIServer Dry-Run

APIServer Dry-Run 旨在解決這兩個問題

  • 它允許將對 apiserver 的單個請求標記為“Dry-Run”,
  • apiserver 保證 Dry-Run 請求不會持久化到儲存中,
  • 請求仍然像典型的請求一樣處理:欄位被預設設定,物件被驗證,它透過驗證准入鏈和變更准入鏈,然後最終物件像往常一樣返回給使用者,而不會被持久化。

儘管動態准入控制器不應該對每個請求產生副作用,但只有當所有準入控制器明確宣告它們沒有任何 Dry-Run 副作用時,Dry-Run 請求才會處理。

如何啟用它

伺服器端 Dry-Run 透過功能門啟用。現在該功能在 1.13 中處於 Beta 階段,它應該預設啟用,但仍然可以使用 kube-apiserver --feature-gates DryRun=true 啟用/停用。

如果您有動態准入控制器,您可能需要修復它們以

  • 當 Webhook 請求中指定了 Dry-Run 引數時,刪除所有副作用,
  • admissionregistration.k8s.io/v1beta1.Webhook 物件的 sideEffects 欄位中指定該物件在 Dry-Run 時沒有副作用(或根本沒有副作用)。

如何使用它

您可以透過使用 kubectl apply --server-dry-run 從 kubectl 觸發該功能,這將用 dryRun 標誌裝飾請求,並返回應用後的物件,如果失敗則返回錯誤。

Kubectl diff

APIServer Dry-Run 很方便,因為它允許您檢視物件將如何處理,但如果物件很大,則很難準確識別更改了什麼。kubectl diff 透過顯示當前“活動”物件和新的“Dry-Run”物件之間的差異來精確地實現您想要的功能。它使得只關注對物件所做的更改、伺服器如何合併這些更改以及變更 Webhook 如何影響輸出變得非常方便。

如何使用它

kubectl diff 旨在儘可能類似於 kubectl applykubectl diff -f some-resources.yaml 將顯示 yaml 檔案中資源的差異。甚至可以使用 KUBECTL_EXTERNAL_DIFF 環境變數使用自己選擇的 diff 程式,例如

KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml

接下來

工作組仍在努力改進其中一些功能

  • 伺服器端應用正在透過為欄位新增所有權語義來改進應用場景!它還將改進對 CRD 和聯合的支援!
  • diff 中缺少一些 kubectl apply 功能,但可能很有用,例如按標籤過濾或顯示修剪資源的能力。
  • 最終,kubectl diff 將使用伺服器端應用!