將節點遷移至 containerd 2


Google Kubernetes Engine (GKE) 叢集會使用 containerd 節點映像檔,搭配所有執行 1.24 以上版本的工作站節點。工作站節點會根據 GKE 版本使用特定版本的 containerd:

  • 如果節點執行 GKE 1.32 以下版本,並使用 containerd 節點映像檔,則會使用 containerd 1.7 以下版本。
  • 執行 GKE 1.33 的節點會使用 containerd 2.0。

將 GKE 節點從 1.32 版升級至 1.33 版時,節點會從使用 containerd 1.7 遷移至新的主要版本 containerd 2.0。您無法變更 GKE 版本使用的 containerd 版本。

如果確定工作負載在 containerd 2 上正常運作,可以略過這個頁面。

GKE 如何轉換至 containerd 2

請參閱下列時間表,瞭解 GKE 如何將現有叢集轉換為使用 containerd 2:

  • 在 1.32 次要版本中,GKE 使用 containerd 1.7。containerd 1.7 已淘汰 Docker 結構定義 1 映像檔和 Container Runtime Interface (CRI) v1alpha2 API。如要瞭解舊版中已淘汰的其他功能,請參閱「已淘汰的設定屬性」。
  • 在 1.33 次要版本中,GKE 使用 containerd 2.0,這個版本移除了對 Docker 結構定義 1 映像檔和 CRI v1alpha2 API 的支援。
  • CRI 外掛程式中的下列 containerd 設定屬性已淘汰,並將在 containerd 2.2 中移除,GKE 版本則尚未公布:registry.authsregistry.configsregistry.mirrors

如要瞭解自動升級至後續子版本 (例如 1.33) 的大致時間,請參閱發布管道的預估時間表

改用 containerd 2 的影響

請參閱下節,瞭解這項轉換對 containerd 2 的影響。

已暫停自動升級

GKE 偵測到叢集使用已淘汰的功能時,會暫停自動升級至 1.33 版。不過,如果叢集節點使用這些功能,建議您建立維護排除規則,防止節點升級。如果 GKE 未偵測到使用情形,維護排除功能可確保節點不會升級。

從使用這些功能遷移後,如果 1.33 是叢集節點的自動升級目標,且沒有其他因素會阻礙自動升級,GKE 會繼續自動將次要版本升級至 1.33。如果是標準叢集節點集區,您也可以手動升級節點集區

支援服務終止日期,以及未準備遷移的影響

GKE 會暫停自動升級,直到標準支援期結束為止。如果叢集已註冊延長版管道,節點可繼續使用該版本,直到延長支援服務結束為止。如要進一步瞭解支援終止後的自動節點升級作業,請參閱支援終止後的自動升級作業

如果未遷移這些功能,當 1.32 終止支援,且叢集節點自動升級至 1.33 時,叢集可能會發生下列問題:

  • 使用 Docker 結構定義 1 映像檔的工作負載會失敗。
  • 呼叫 CRI v1alpha2 API 的應用程式無法呼叫 API。

找出受影響的叢集

GKE 會監控叢集,並使用 Recommender 服務,透過深入分析和建議提供指引,協助您找出使用這些已淘汰功能的叢集節點。

版本需求

如果叢集執行下列版本或更新版本,就會收到這些洞察資訊和建議:

  • 1.28.15-gke.1159000
  • 1.29.9-gke.1541000
  • 1.30.5-gke.1355000
  • 1.31.1-gke.1621000

取得洞察資料和建議

按照操作說明查看洞察資料和建議。 您可以使用 Google Cloud 控制台取得洞察資料。您也可以使用 Google Cloud CLI 或 Recommender API,依下列子類型篩選:

  • DEPRECATION_CONTAINERD_V1_SCHEMA_IMAGES: Docker 結構定義 1 映像檔
  • DEPRECATION_CONTAINERD_V1ALPHA2_CRI_API: CRI v1alpha2 API

停止使用已淘汰的功能

請參閱下列內容,瞭解如何從 containerd 2 中已淘汰的功能遷移。

從 Docker 結構定義 1 映像檔遷移至其他選項

找出必須遷移的工作負載 (使用映像檔),然後遷移這些工作負載。

尋找要遷移的圖片

您可以使用不同工具找出必須遷移的圖片。

使用深入分析和建議或 Cloud Logging

如「找出受影響的叢集」一節所述,如果叢集執行的是最低版本或更新版本,您可以使用洞察和建議,找出使用 Docker 結構定義 1 映像檔的叢集。此外,您可以在 Cloud Logging 中使用下列查詢檢查 containerd 記錄,找出叢集中的 Docker Schema 1 映像檔:

jsonPayload.SYSLOG_IDENTIFIER="containerd"
"conversion from schema 1 images is deprecated"

如果圖片已擷取超過 30 天,您可能不會看到圖片的記錄。

直接在節點上使用 ctr 指令

如要查詢特定節點,傳回以 Schema 1 形式提取的所有未刪除映像檔,請在節點上執行下列指令:

  ctr --namespace k8s.io images list 'labels."io.containerd.image/converted-docker-schema1"'

舉例來說,如果您要排解特定節點的疑難,但自提取映像檔以來已超過 30 天,因此 Cloud Logging 中沒有記錄項目,這個指令就很有用。

使用 crane 開放原始碼工具

您也可以使用 crane 等開放原始碼工具檢查映像檔。

執行下列 crane 指令,檢查映像檔的結構定義版本:

crane manifest $tagged_image | jq .schemaVersion

準備工作負載

如要準備執行 Docker 結構定義 1 映像檔的工作負載,必須將這些工作負載遷移至 Docker 結構定義 2 映像檔,或開放容器倡議 (OCI) 映像檔。請考慮下列遷移選項:

  • 尋找替代圖片:您或許可以找到公開的開放原始碼圖片,或是供應商提供的圖片。
  • 轉換現有映像檔:如果找不到替代映像檔,可以按照下列步驟將現有的 Docker 結構定義 1 映像檔轉換為 OCI 映像檔:
    1. 將 Docker 映像檔拉取至 containerd,系統會自動將其轉換為 OCI 映像檔。
    2. 將新的 OCI 映像檔推送至登錄檔。

從 CRI v1alpha2 API 遷移

CRI v1alpha2 API 已在 Kubernetes 1.26 中移除。您必須找出會存取 containerd 通訊端的工作負載,並更新這些應用程式,才能使用 v1 API。

找出可能受影響的工作負載

您可以運用不同技術,找出可能需要遷移的工作負載。這些技術可能會產生誤判,您必須進一步調查,確認是否不需要採取任何行動。

使用洞察資料和建議

如果叢集執行的是最低版本或更新版本,您可以使用洞察和建議,找出使用 v1alpha2 API 的叢集。詳情請參閱「找出受影響的叢集」。

在 Google Cloud 控制台中查看洞察資料時,請參閱側欄面板「將工作負載從已淘汰的 CRI v1alpha2 API 遷移至其他選項」。這個面板中的「Workloads to Verify」(待驗證的工作負載) 表格會列出可能受影響的工作負載。這份清單包含任何未由 GKE 管理的工作負載,這些工作負載具有包含 containerd Socket 路徑的 hostPath 磁碟區 (例如 /var/run/containerd/containerd.sock/run/containerd/containerd.sock)。

請務必瞭解下列事項:

  • 這份清單可能包含誤判結果。清單中顯示的工作負載不一定表示正在使用已淘汰的 API。這只表示工作負載參照的 hostPath 磁碟區包含 containerd 通訊端。舉例來說,監控代理程式可能會包含節點的根檔案系統 (/),以收集指標。包括節點的根檔案系統 (技術上包含通訊端的路徑),但指標代理程式可能不會實際呼叫 CRI v1alpha2 API。
  • 這份清單可能空白或不完整。如果使用已淘汰 API 的工作負載生命週期較短,且在 GKE 執行定期檢查時未執行,就可能導致清單空白或不完整。如果系統顯示這項建議,表示叢集內至少有一個節點偵測到 CRI v1alpha2 API 用量。

因此,建議您使用下列方法進一步調查,確認實際的 API 使用情況。

檢查受影響的第三方工作負載

如果是部署到叢集的第三方軟體,請確認這些工作負載未使用 CRI v1alpha2 API。您可能需要與相關供應商聯絡,確認軟體版本是否相容。

使用 kubectl

下列指令會尋找存取 containerd Socket 的工作負載,協助您找出可能受影響的工作負載。這項功能使用的邏輯與 Google Cloud 控制台建議中的「待驗證的工作負載」表格類似。系統會傳回未由 GKE 管理的工作負載,這些工作負載具有包含插槽路徑的hostPath磁碟區。與建議一樣,這項查詢可能會傳回誤判結果,或遺漏短期工作負載。

執行下列指令:

kubectl get pods --all-namespaces -o json | \
jq -r '
  [
    "/", "/var", "/var/","/var/run", "/var/run/",
    "/var/run/containerd", "/var/run/containerd/", "/var/run/containerd/containerd.sock",
    "/run", "/run/", "/run/containerd", "/run/containerd/",
    "/run/containerd/containerd.sock"
  ] as $socket_paths |
  [
    "kube-system", "kube-node-lease", "istio-system", "asm-system",
    "gatekeeper-system", "config-management-system", "config-management-monitoring",
    "cnrm-system", "hnc-system", "gke-managed-system", "gke-gmp-system",
    "gmp-system", "gke-managed-cim"
  ] as $excluded_namespaces |
  .items[] |
  select(
    (.spec.volumes[]?.hostPath.path as $p | $socket_paths | index($p))
    and
    ([.metadata.namespace] | inside($excluded_namespaces) | not)
  ) |
  .metadata.namespace + "/" + .metadata.name
'
使用 eBPF 追蹤功能找出 API 呼叫端

如要更明確地判斷哪些工作負載呼叫 CRI v1alpha2 API,您可以部署兩個專用 DaemonSet:containerd-socket-tracercri-v1alpha2-api-deprecation-reporter。這些工具使用擴充 Berkeley 封包篩選器 (eBPF),追蹤與 containerd 插座的連線,並將連線與實際已淘汰的 API 呼叫建立關聯:

  • containerd-socket-tracer 會記錄開啟 containerd 通訊端連線的任何程序,以及 Pod 和容器詳細資料。
  • cri-v1alpha2-api-deprecation-reporter 會記錄上次呼叫 CRI v1alpha2 API 的時間。

只要將這兩項工具的時間戳記相互對照,即可找出發出已淘汰 API 呼叫的確切工作負載。相較於單獨檢查 hostPath 磁碟區,這個方法可提供更高程度的信心,因為它會觀察實際的通訊端連線和 API 用量。

如需部署及使用這些工具的詳細操作說明,以及如何解讀記錄,請參閱「追蹤 containerd Socket 連線」。

如果使用這些工具後,仍無法找出已淘汰 API 呼叫的來源,但建議仍處於有效狀態,請參閱「取得支援」。

找出使用 CRI v1alpha2 API 的工作負載後 (可透過上述方法或檢查程式碼庫),您必須更新其程式碼,改用 v1 API。

更新應用程式代碼

如要更新應用程式,請移除應用程式匯入 k8s.io/cri-api/pkg/apis/runtime/v1alpha2 用戶端程式庫的位置,並修改程式碼以使用 v1 版本的 API。這個步驟包括變更匯入路徑,以及更新程式碼呼叫 API 的方式。

舉例來說,請參閱下列使用已淘汰程式庫的 Golang 程式碼:

  package main

  import (
    ...

    runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
  )

  func foo() {
    ...

    client := runtimeapi.NewRuntimeServiceClient(conn)
    version, err := client.Version(ctx, &runtimeapi.VersionRequest{})

    ...
  }

在此,應用程式會匯入 v1alpha2 程式庫,並使用該程式庫發出 RPC。如果 RPC 使用 containerd 通訊端的連線,則這個應用程式會導致 GKE 暫停叢集的自動升級。

請按照下列步驟搜尋及更新應用程式程式碼:

  1. 執行下列指令,搜尋 v1alpha2 匯入路徑,找出有問題的 Golang 應用程式:

      grep -r "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
    

    如果這項指令的輸出內容顯示檔案中使用了 v1alpha2 程式庫,您就必須更新檔案。

    舉例來說,請替換下列應用程式碼:

      runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
    
  2. 更新程式碼以使用 v1:

      runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
    

取得支援

如果您按照指示使用 eBPF 追蹤功能找出 API 呼叫者,但仍無法判斷已淘汰 API 呼叫的來源,且建議仍處於有效狀態,請考慮採取下列後續步驟: