從 Docker 遷移至 containerd 節點映像檔


本頁說明如何將 Google Kubernetes Engine (GKE) Standard 叢集和節點集區,從 Docker 遷移至使用 containerd 容器執行階段的節點映像檔。

總覽

Kubernetes 節點會使用容器執行階段啟動、管理及停止在 Pod 中執行的容器。containerd 執行階段是 GKE 支援的業界標準容器執行階段。

containerd 執行階段提供分層抽象化功能,可實作豐富的功能集,例如 gVisor映像檔串流,進而擴充 GKE 功能。相較於 Docker 執行階段,containerd 執行階段的資源效率更高,也更安全。

如要遷移容器執行階段,請按照下列步驟操作:

  • 找出使用 Docker 執行階段的節點
  • 確認遷移作業的影響
  • 變更節點圖片

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

找出使用 Docker 執行階段的節點

如要檢查哪些節點使用以 Docker 為基礎的節點映像檔,請使用下列方法:

  • 使用指令碼疊代 Google Cloud 專案中所有 GKE 叢集的所有節點。
  • 使用 Google Cloud CLI kubectl 或 Google Cloud 控制台,找出節點映像檔。
  • 使用淘汰洞察和建議,找出Google Cloud 專案中特定區域或地區的叢集和節點。

建議您使用指令碼,快速找出需要遷移的所有節點。

使用指令碼識別 Docker 節點

以下指令碼會逐一查看可用專案中每個叢集的每個節點,並提供可執行的建議,例如:

  • 是否為 Docker 映像檔設定節點自動佈建
  • 建議用於遷移的 containerd 節點映像檔對應項目
  • 建議用於遷移作業的節點映像檔版本
  • 建議執行的指令,用於遷移已識別的節點和設定

這個指令碼會忽略 GKE Autopilot 叢集,因為這類叢集預設使用 Container-Optimized OS 搭配 containerd 節點映像檔。

執行下列指令碼:

for project in $(gcloud projects list --format="value(projectId)")
do
  echo "ProjectId: $project"
  for clusters in $( \
    gcloud container clusters list \
      --project $project \
      --format="csv[no-heading](name,location,autopilot.enabled,currentMasterVersion,autoscaling.enableNodeAutoprovisioning,autoscaling.autoprovisioningNodePoolDefaults.imageType)")
  do
    IFS=',' read -r -a clustersArray <<< "$clusters"
    cluster_name="${clustersArray[0]}"
    cluster_zone="${clustersArray[1]}"
    cluster_isAutopilot="${clustersArray[2]}"
    cluster_version="${clustersArray[3]}"
    cluster_minorVersion=${cluster_version:0:4}
    cluster_autoprovisioning="${clustersArray[4]}"
    cluster_autoprovisioningImageType="${clustersArray[5]}"

    if [ "$cluster_isAutopilot" = "True" ]; then
      echo "  Cluster: $cluster_name (autopilot) (zone: $cluster_zone)"
      echo "    Autopilot clusters are running Containerd."
    else
      echo "  Cluster: $cluster_name (zone: $cluster_zone)"

      if [ "$cluster_autoprovisioning" = "True" ]; then
        if [ "$cluster_minorVersion"  \< "1.20" ]; then
          echo "    Node autoprovisioning is enabled, and new node pools will have image type 'COS'."
          echo "    This settings is not configurable on the current version of a cluster."
          echo "    Please upgrade you cluster and configure the default node autoprovisioning image type."
          echo "    "
        else
          if [ "$cluster_autoprovisioningImageType" = "COS" ]; then
            echo "    Node autoprovisioning is configured to create new node pools of type 'COS'."
            echo "    Run the following command to update:"
            echo "    gcloud container clusters update '$cluster_name' --project '$project' --zone '$cluster_zone' --enable-autoprovisioning --autoprovisioning-image-type='COS_CONTAINERD'"
            echo "    "
          fi

          if [ "$cluster_autoprovisioningImageType" = "UBUNTU" ]; then
            echo "    Node autoprovisioning is configured to create new node pools of type 'UBUNTU'."
            echo "    Run the following command to update:"
            echo "    gcloud container clusters update '$cluster_name' --project '$project' --zone '$cluster_zone' --enable-autoprovisioning --autoprovisioning-image-type='UBUNTU_CONTAINERD'"
            echo "    "
          fi
        fi
      fi

      for nodepools in $( \
        gcloud container node-pools list \
          --project $project \
          --cluster $cluster_name \
          --zone $cluster_zone \
          --format="csv[no-heading](name,version,config.imageType)")
      do
        IFS=',' read -r -a nodepoolsArray <<< "$nodepools"
        nodepool_name="${nodepoolsArray[0]}"
        nodepool_version="${nodepoolsArray[1]}"
        nodepool_imageType="${nodepoolsArray[2]}"

        nodepool_minorVersion=${nodepool_version:0:4}

        echo "    Nodepool: $nodepool_name, version: $nodepool_version ($nodepool_minorVersion), image: $nodepool_imageType"

        minorVersionWithRev="${nodepool_version/-gke./.}"
        linuxGkeMinVersion="1.14"
        windowsGkeMinVersion="1.21.1.2200"

        suggestedImageType="COS_CONTAINERD"

        if [ "$nodepool_imageType" = "UBUNTU" ]; then
          suggestedImageType="UBUNTU_CONTAINERD"
        elif [ "$nodepool_imageType" = "WINDOWS_LTSC" ]; then
          suggestedImageType="WINDOWS_LTSC_CONTAINERD"
        elif [ "$nodepool_imageType" = "WINDOWS_SAC" ]; then
          suggestedImageType="WINDOWS_SAC_CONTAINERD"
        fi

        tab=$'\n      ';
        nodepool_message="$tab Please update the nodepool to use Containerd."
        nodepool_message+="$tab Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues."
        nodepool_message+="$tab Run the following command to upgrade:"
        nodepool_message+="$tab "
        nodepool_message+="$tab gcloud container clusters upgrade '$cluster_name' --project '$project' --zone '$cluster_zone' --image-type '$suggestedImageType' --node-pool '$nodepool_name'"
        nodepool_message+="$tab "

        # see https://cloud.google.com/kubernetes-engine/docs/concepts/node-images
        if [ "$nodepool_imageType" = "COS_CONTAINERD" ] || [ "$nodepool_imageType" = "UBUNTU_CONTAINERD" ] ||
           [ "$nodepool_imageType" = "WINDOWS_LTSC_CONTAINERD" ] || [ "$nodepool_imageType" = "WINDOWS_SAC_CONTAINERD" ]; then
          nodepool_message="$tab Nodepool is using Containerd already"
        elif ( [ "$nodepool_imageType" = "WINDOWS_LTSC" ] || [ "$nodepool_imageType" = "WINDOWS_SAC" ] ) &&
               [ "$(printf '%s\n' "$windowsGkeMinVersion" "$minorVersionWithRev" | sort -V | head -n1)" != "$windowsGkeMinVersion" ]; then
          nodepool_message="$tab Upgrade nodepool to the version that supports Containerd for Windows"
        elif [ "$(printf '%s\n' "$linuxGkeMinVersion" "$minorVersionWithRev" | sort -V | head -n1)" != "$linuxGkeMinVersion" ]; then
          nodepool_message="$tab Upgrade nodepool to the version that supports Containerd"
        fi
        echo "$nodepool_message"
      done
    fi # not autopilot
  done
done

# Sample output:
#
# ProjectId:  my-project-id
#  Cluster: autopilot-cluster-1 (autopilot) (zone: us-central1)
#    Autopilot clusters are running Containerd.
#  Cluster: cluster-1 (zone: us-central1-c)
#    Nodepool: default-pool, version: 1.18.12-gke.1210 (1.18), image: COS
#
#       Please update the nodepool to use Containerd.
#       Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues.
#       Run the following command to upgrade:
#
#       gcloud container clusters upgrade 'cluster-1' --project 'my-project-id' --zone 'us-central1-c' --image-type 'COS_CONTAINERD' --node-pool 'default-pool'
#
#    Nodepool: pool-1, version: 1.18.12-gke.1210 (1.18), image: COS
#
#       Please update the nodepool to use Containerd.
#       Make sure to consult with the list of known issues https://cloud.google.com/kubernetes-engine/docs/concepts/using-containerd#known_issues.
#       Run the following command to upgrade:
#
#       gcloud container clusters upgrade 'cluster-1' --project 'my-project-id' --zone 'us-central1-c' --image-type 'COS_CONTAINERD' --node-pool 'pool-1'
#
#    Nodepool: winpool, version: 1.18.12-gke.1210 (1.18), image: WINDOWS_SAC
#
#       Upgrade nodepool to the version that supports Containerd for Windows
#
#  Cluster: another-test-cluster (zone: us-central1-c)
#    Nodepool: default-pool, version: 1.20.4-gke.400 (1.20), image: COS_CONTAINERD
#
#      Nodepool is using Containerd already
#

使用 Google Cloud識別節點映像檔

您可以使用 Google Cloud CLI kubectl 或 Google Cloud 控制台,檢查現有節點的節點映像檔。

gcloud

執行下列指令:

gcloud container node-pools list \
    --cluster=CLUSTER_NAME \
    --format="table(name,version,config.imageType)"

CLUSTER_NAME 替換為叢集名稱。

輸出結果會與下列內容相似:

NAME          NODE_VERSION    IMAGE_TYPE
default-pool  1.19.6-gke.600  UBUNTU

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 在叢集清單中,按一下要驗證的叢集名稱。

  3. 選取「節點」分頁標籤。

  4. 在「節點集區」區段中,檢查「映像檔類型」欄中的值。

kubectl

執行下列指令:

kubectl get nodes -o wide

輸出結果會與下列內容相似:

# For Docker runtime
NAME         STATUS   VERSION             OS-IMAGE                             CONTAINER-RUNTIME
gke-node-1   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1
gke-node-2   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1
gke-node-3   Ready    v1.16.15-gke.6000   Container-Optimized OS from Google   docker://19.3.1

CONTAINER-RUNTIME 欄中的值會顯示執行階段和版本。

使用淘汰深入分析和建議找出叢集

GKE 會偵測部分已淘汰的功能和 API 使用情形,包括以 Docker 為基礎的節點映像檔。詳情請參閱「功能和 API 淘汰項目」。

為偵測淘汰項目使用情形,GKE 會產生洞察資料和建議,並以 DEPRECATION_K8S_1_24_DOCKERSHIM 洞察子類型識別使用 Docker 型節點映像檔的情形。

一組洞察資訊和建議會指出叢集節點使用以 Docker 為基礎的節點映像檔。每項洞察和建議都會列出叢集中使用 Docker 節點映像檔的特定節點集區,這些節點集區必須遷移至 containerd 節點映像檔。

如要開始使用,請按照說明查看淘汰深入分析和建議。 如要使用 gcloud CLI 指令,請使用下列旗標,只查看這項淘汰作業的洞察資料:

--filter="insightSubtype:DEPRECATION_K8S_1_24_DOCKERSHIM"

找出使用以 Docker 為基礎的節點映像檔的叢集節點集區後,請按照操作說明將節點映像檔變更為 containerd 節點映像檔

確認遷移的影響

將正式叢集和節點集區遷移至使用 containerd 的節點映像檔之前,強烈建議您先在暫存環境中測試遷移作業的影響,盡量降低發生問題的風險。

建議您遷移節點時,不要同時升級節點,這樣在驗證工作負載是否能以新設定運作時,就能隔離變數。此外,如果您同時將節點集區升級至 1.24 版,則無法復原變更,因為 1.24 版不支援 Docker 節點,且您無法降級次要版本。

將節點映像檔變更為 containerd 映像檔

如果您使用指令碼識別 Docker 節點,可以運用指令碼傳回的建議指令,將節點自動佈建設定和節點映像檔變更為 containerd 對應項目。

您也可以更新節點集區,並使用 gcloud CLI 或 Google Cloud 主控台設定不同的映像檔,將節點從 Docker 映像檔類型遷移至 containerd 映像檔類型。

GKE 會使用選取的節點升級策略和設定,遷移節點的映像檔。建議您使用藍綠升級策略進行這項遷移作業,因為如果工作負載在升級期間遇到新節點映像檔的問題,您可以回溯至先前的環境,並使用原始節點映像檔設定。

gcloud

執行下列指令:

gcloud container clusters upgrade CLUSTER_NAME \
    --image-type=NODE_IMAGE \
    --node-pool=POOL_NAME \
    --cluster-version=NODE_VERSION

更改下列內容:

  • NODE_IMAGE:節點要使用的節點映像檔。
  • POOL_NAME:要遷移的節點集區名稱。
  • NODE_VERSION:節點集區的現有版本。建議您設定這個標記,否則 GKE 會嘗試在同一項作業中,將節點集區版本升級至控制層版本,並更新節點映像檔。如果控制平面執行的是 1.24 版,指令會失敗。如果控制層執行的是 1.23 版,指令就會成功執行,導致您無法單獨測試這兩項變更 (版本升級和映像檔更新)。

輸出結果會與下列內容相似:

NAME          NODE_VERSION    IMAGE_TYPE
default-pool  1.23.6-gke.600  UBUNTU_CONTAINERD

控制台

  1. 前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往 Google Kubernetes Engine

  2. 在叢集清單中,按一下要驗證的叢集名稱。

  3. 按一下「Nodes」(節點) 分頁標籤。

  4. 在「節點集區」區段中,按一下要修改的節點集區名稱。

  5. 在「Node pool details」(節點集區詳細資料) 頁面中,按一下 「Edit」(編輯)

  6. 在「節點」專區中,按一下「映像檔類型」下方的「變更」

  7. 選取其中一種 containerd 映像檔類型。

  8. 按一下 [變更]

回復為 Docker 節點映像檔

如果節點已自動或手動遷移至 containerd 節點,且工作負載發生問題,請按照下列步驟還原為 Docker 節點映像檔:

  1. 根據作業狀態選擇下列步驟:
  2. 設定維護作業排除時段,暫時禁止 GKE 重試遷移作業。
  3. 調查問題的根本原因,以便從 Docker 遷移,並確保叢集執行的是支援的 GKE 版本。
  4. 請再次嘗試將節點映像檔變更為 containerd 映像檔。如果移除維護排除項目,GKE 會再次觸發作業。

更新基礎架構即程式碼 (IaC) 工具設定

如果您使用 Terraform、Ansible 或 Pulumi 等 IaC 工具管理 GKE 叢集,請務必更新設定,改用 containerd 節點映像檔,避免工具將先前所需的狀態與新的實際狀態進行比對。舉例來說,GKE Terraform 供應商支援可設定的映像檔類型

更新所有設定,確保工具不會在您遷移至 containerd 節點映像檔後,將節點映像檔更新回以 Docker 為基礎的節點映像檔。

變更節點自動佈建功能的預設節點映像檔

如果叢集使用節點自動佈建,請將預設映像檔類型變更為 containerd 節點映像檔。變更預設映像檔類型只會套用至新的自動佈建節點集區。您必須手動變更現有自動佈建節點集區的節點映像檔。

您可以使用 gcloud CLI 或設定檔,變更預設的節點自動佈建映像檔類型。

gcloud

執行下列指令:

gcloud container clusters update CLUSTER_NAME \
    --enable-autoprovisioning \
    --autoprovisioning-image-type=IMAGE_TYPE

更改下列內容:

  • CLUSTER_NAME:要更新的叢集名稱。
  • IMAGE_TYPE:節點映像檔類型,可以是下列其中一項:

    • cos_containerd
    • ubuntu_containerd

檔案

您可以透過 YAML 設定檔,變更節點自動佈建功能的預設節點映像檔類型。使用檔案時,您也必須指定 CPU 和記憶體資源的最大值。

  1. 儲存下列 YAML 檔案:

    resourceLimits:
      - resourceType: 'cpu'
          minimum: 4
          maximum: 10
      - resourceType: 'memory'
          maximum: 64
    autoprovisioningNodePoolDefaults:
      imageType: 'IMAGE_TYPE'
    

    IMAGE_TYPE 替換為 containerd 映像檔類型。

  2. 套用設定:

    gcloud container clusters update CLUSTER_NAME \
        --enable-autoprovisioning \
        --autoprovisioning-config-file=FILE_NAME
    

    FILE_NAME 替換為設定檔的路徑。

疑難排解

如要排解問題及瞭解已知問題的解決方法,請參閱「排解容器執行階段問題」。

後續步驟