已棄用的 Kubernetes API

Kubernetes 是一個 API 驅動的系統,其 API 會隨著時間推移而演進,以反映對問題空間不斷發展的理解。這在系統及其 API 中是常見的做法。演進 API 的一個重要部分是良好的棄用政策和流程,以通知使用者 API 變更的實作方式。換句話說,您的 API 的消費者需要事先知道 API 將在什麼版本中被移除或變更。這消除了對消費者的意外和重大變更。

Kubernetes 棄用政策說明了 Kubernetes 如何處理其 API 版本的變更。棄用政策規定了在宣佈棄用後,API 版本將被支援的時間範圍。因此,重要的是要了解棄用公告,並知道何時將移除 API 版本,以協助將影響降至最低。

這是一個範例公告,說明在 Kubernetes 1.16 中移除已棄用的 API 版本,並在發佈前幾個月發佈。這些 API 版本將會在之前再次宣佈棄用。這顯示有一個良好的政策來通知消費者 API 版本的支援。

Helm 範本在定義 Kubernetes 物件時會指定一個 Kubernetes API 群組,類似於 Kubernetes 資訊清單檔案。它在範本的 apiVersion 欄位中指定,並識別 Kubernetes 物件的 API 版本。這表示 Helm 使用者和圖表維護者需要了解何時已棄用 Kubernetes API 版本,以及它們將在何時從 Kubernetes 版本中移除。

圖表維護者

您應該稽核您的圖表,檢查是否有在 Kubernetes 版本中已棄用或已移除的 Kubernetes API 版本。發現即將或已不受支援的 API 版本,應更新為支援的版本,並發佈新版本的圖表。API 版本由 kindapiVersion 欄位定義。例如,以下是在 Kubernetes 1.16 中移除的 Deployment 物件 API 版本

apiVersion: apps/v1beta1
kind: Deployment

Helm 使用者

您應該稽核您使用的圖表(類似於 圖表維護者),並識別任何 API 版本在 Kubernetes 版本中已棄用或已移除的圖表。對於已識別的圖表,您需要檢查圖表的最新版本(具有支援的 API 版本),或自行更新圖表。

此外,您還需要稽核任何已部署的圖表(即 Helm 版本),再次檢查是否有任何已棄用或已移除的 API 版本。這可以使用 helm get manifest 命令取得版本的詳細資訊來完成。

使用支援的 API 更新 Helm 版本的方法取決於您的發現,如下所示

  1. 如果您只找到已棄用的 API 版本,則
  • 使用具有支援的 Kubernetes API 版本的圖表版本執行 helm upgrade
  • 在升級中新增說明,例如不要回滾至此目前版本之前的 Helm 版本
  1. 如果您找到在 Kubernetes 版本中已移除的任何 API 版本,則
  • 如果您執行的 Kubernetes 版本仍然可以使用這些 API 版本(例如,您使用的是 Kubernetes 1.15,並且發現您使用的 API 將在 Kubernetes 1.16 中移除)
    • 請遵循步驟 1 的程序
  • 否則(例如,您已經執行了一個 Kubernetes 版本,其中 helm get manifest 報告的某些 API 版本已不再可用)

注意:在使用支援的 API 更新 Helm 版本的所有情況下,您都不應該將版本回滾至具有支援的 API 的版本之前的版本。

建議:最佳做法是在升級至移除這些 API 版本的 Kubernetes 叢集之前,將使用已棄用 API 版本的版本升級至支援的 API 版本。

如果您沒有按照先前的建議更新版本,則在嘗試在已移除其 API 版本的 Kubernetes 版本中升級版本時,會發生類似以下的錯誤

Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s)
for this kubernetes version and it is therefore unable to build the kubernetes
objects for performing the diff. error from kubernetes: unable to recognize "":
no matches for kind "Deployment" in version "apps/v1beta1"

Helm 在這種情況下會失敗,因為它嘗試在目前部署的版本(其中包含在此 Kubernetes 版本中移除的 Kubernetes API)與您傳遞的具有更新/支援 API 版本的圖表之間建立差異修補程式。失敗的根本原因是,當 Kubernetes 移除 API 版本時,Kubernetes Go 用戶端程式庫將無法再解析已棄用的物件,因此 Helm 在呼叫程式庫時會失敗。不幸的是,Helm 無法從這種情況中恢復,並且無法再管理這樣的版本。如需如何從這種情況中恢復的更多詳細資訊,請參閱 更新版本資訊清單的 API 版本

更新版本資訊清單的 API 版本

資訊清單是 Helm 版本物件的屬性,該物件儲存在叢集中 Secret(預設)或 ConfigMap 的資料欄位中。資料欄位包含一個已進行 base 64 編碼的 gzip 物件(對於 Secret,有一個額外的 base 64 編碼)。在版本的命名空間中,每個版本/修訂版都有一個 Secret/ConfigMap。

您可以使用 Helm mapkubeapis 外掛來執行版本的更新,以支援 API。如需更多詳細資訊,請參閱自述檔案。

或者,您可以按照以下手動步驟來執行版本資訊清單的 API 版本更新。根據您的配置,您將按照 Secret 或 ConfigMap 後端的步驟進行操作。

  • 取得與最新部署的版本相關聯的 Secret 或 Configmap 的名稱
    • Secret 後端:kubectl get secret -l owner=helm,status=deployed,name=<release_name> --namespace <release_namespace> | awk '{print $1}' | grep -v NAME
    • ConfigMap 後端:kubectl get configmap -l owner=helm,status=deployed,name=<release_name> --namespace <release_namespace> | awk '{print $1}' | grep -v NAME
  • 取得最新部署的版本詳細資訊
    • Secret 後端:kubectl get secret <release_secret_name> -n <release_namespace> -o yaml > release.yaml
    • ConfigMap 後端:kubectl get configmap <release_configmap_name> -n <release_namespace> -o yaml > release.yaml
  • 備份版本,以便在出現問題時需要還原
    • cp release.yaml release.bak
    • 在緊急情況下,還原:kubectl apply -f release.bak -n <release_namespace>
  • 解碼版本物件
    • Secret 後端:cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d | base64 -d | gzip -d > release.data.decoded
    • ConfigMap 後端:cat release.yaml | grep -oP '(?<=release: ).*' | base64 -d | gzip -d > release.data.decoded
  • 變更資訊清單的 API 版本。可以使用任何工具(例如編輯器)進行變更。這在您解碼的版本物件(release.data.decoded)的 manifest 欄位中
  • 編碼版本物件
    • Secret 後端:cat release.data.decoded | gzip | base64 | base64
    • ConfigMap 後端:cat release.data.decoded | gzip | base64
  • 將部署的版本檔案(release.yaml)中的 data.release 屬性值替換為新的編碼版本物件
  • 將檔案套用到命名空間:kubectl apply -f release.yaml -n <release_namespace>
  • 使用具有支援的 Kubernetes API 版本的圖表版本執行 helm upgrade
  • 在升級中新增說明,例如不要回滾至此目前版本之前的 Helm 版本