預設將 ComputeClass 套用至 Pod

本文說明如何將 ComputeClass 預設套用至未明確選取 ComputeClass 的 Google Kubernetes Engine (GKE) Pod。您可以將 ComputeClass 設為命名空間或整個叢集的預設值。本文適用於叢集管理員,可協助他們減少因個別工作負載和節點設定而造成的手動負擔。

您應該已熟悉自訂 ComputeClass

關於預設 ComputeClass

您可以將 GKE 叢集或特定命名空間設定為具有預設 ComputeClass。您設定的預設類別會套用至該叢集或命名空間中,未選取其他 ComputeClass 的任何 Pod。部署未選取 ComputeClass 的 Pod 時,GKE 會依下列順序套用預設 ComputeClass:

  1. 如果命名空間有預設的 ComputeClass,GKE 會修改 Pod 規格,選取該 ComputeClass。
  2. 如果命名空間沒有預設的 ComputeClass,系統會套用叢集層級的預設類別。GKE 不會修改 Pod 規格。

為叢集或命名空間設定預設 ComputeClass 時,變更只會套用至新 Pod。現有 Pod 不會受到影響,直到重新建立 Pod 為止。即使 ComputeClass 已啟用主動遷移功能,也會發生這種情況。

如果預設 ComputeClass 的 activeMigration.optimizeRulePriority 欄位設為 true,這項設定可能會影響叢集中的工作負載。詳情請參閱「在預設 ComputeClass 中進行即時遷移」。

事前準備

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

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 擁有 GKE Autopilot 或 Standard 叢集,且執行版本支援在叢集或命名空間層級設定預設 ComputeClass。詳情請參閱「規定」一節。
  • 如果您使用標準模式叢集,請確認符合下列其中一項規定:

  • 如要將自訂 ComputeClass 設為命名空間的預設值,請部署自訂 ComputeClass

需求條件

  • 如要將 ComputeClass 設為叢集層級的預設值,叢集必須執行 GKE 1.33.1-gke.1744000 以上版本。
  • 如要將 ComputeClass 設為命名空間層級的預設值,但僅適用於非 DaemonSet Pod,叢集必須執行 GKE 1.33.1-gke.1788000 以上版本。

必要角色和權限

如要取得設定叢集或命名空間層級預設 ComputeClass 所需的權限,請要求管理員在 Google Cloud 專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

這些預先定義的角色具備設定叢集或命名空間層級預設 ComputeClass 所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

如要設定叢集或命名空間層級的預設 ComputeClass,必須具備下列權限:

  • container.customResourceDefinitions.create
  • container.customResourceDefinitions.update
  • container.customResourceDefinitions.get
  • container.customResourceDefinitions.list
  • container.namespaces.get
  • container.namespaces.list
  • container.pods.get
  • container.nodes.get
  • container.nodes.list
  • container.deployments.create
  • container.deployments.get
  • 為命名空間新增標籤: container.namespaces.update
  • 啟用叢集層級的預設 ComputeClass: container.clusters.update

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

為命名空間設定預設 ComputeClass

您可以在叢集中使用 ComputeClass 名稱註解任何 Kubernetes 命名空間,做為預設值。如果部署到該命名空間的 Pod 尚未選取 ComputeClass,GKE 會修改 Pod 規格,選取命名空間中的預設類別。您可以將任何自訂或內建的 ComputeClass 設為預設值。

  • 如要預設將 ComputeClass 套用至命名空間中的所有 Pod,請將 cloud.google.com/default-compute-class 標籤新增至該命名空間:

    kubectl label namespaces NAMESPACE_NAME \
        cloud.google.com/default-compute-class=COMPUTECLASS_NAME
    

    更改下列內容:

    • NAMESPACE_NAME:要更新的命名空間名稱。
    • COMPUTECLASS_NAME:要設為命名空間預設值的 ComputeClass 名稱。

    如果指令失敗並顯示下列錯誤訊息,表示命名空間已有預設的 ComputeClass:

    error: 'cloud.google.com/default-compute-class' already has a value, and --overwrite is false
    

    如要解決這項錯誤,請更新命名空間的預設 ComputeClass

  • 如要預設將 ComputeClass 套用至命名空間中所有非 DaemonSet 的 Pod,請將 cloud.google.com/default-compute-class-non-daemonset 標籤新增至該命名空間:

    kubectl label namespaces NAMESPACE_NAME \
        cloud.google.com/default-compute-class-non-daemonset=COMPUTECLASS_NAME
    

    如果指令失敗並顯示下列錯誤訊息,表示命名空間已為非 DaemonSet Pod 設定預設 ComputeClass:

    error: 'cloud.google.com/default-compute-class-non-daemonset' already has a value, and --overwrite is false
    

    如要解決這項錯誤,請更新命名空間的預設 ComputeClass

變更會套用至該命名空間中的所有新 Pod。現有的 Pod 不會受到影響。

更新命名空間中現有的預設 ComputeClass

如要覆寫命名空間的現有預設 ComputeClass,請執行下列其中一個指令:

  • 更新命名空間中所有 Pod 的預設 ComputeClass:

    kubectl label namespaces NAMESPACE_NAME   \
        cloud.google.com/default-compute-class=COMPUTECLASS_NAME \
        --overwrite
    

    更改下列內容:

    • NAMESPACE_NAME:要更新的命名空間名稱。
    • COMPUTECLASS_NAME:要設為命名空間新預設值的 ComputeClass 名稱。
  • 覆寫命名空間中非 DaemonSet Pod 的預設 ComputeClass:

    kubectl label namespaces NAMESPACE_NAME \
        cloud.google.com/default-compute-class-non-daemonset=COMPUTECLASS_NAME \
        --overwrite
    

為系統命名空間設定預設 ComputeClass

GKE 會使用系統命名空間執行各種受管理的工作負載,例如監控代理程式。其中有些受管理的工作負載是 DaemonSet,必須在叢集中的每個節點上執行,才能提供重要功能。不過,您可以為系統命名空間中非 DaemonSet 的 Pod 指定預設 ComputeClass,讓這些 Pod 與工作負載分開執行。

如要為系統命名空間設定預設 ComputeClass,請按照下列步驟操作:

  1. 將下列指令碼儲存為 apply-system-cc.sh。這個指令碼可讓您將建議的 ComputeClass 或現有的 ComputeClass 套用至系統命名空間。

    #!/bin/bash
    
    # The recommended default ComputeClass name for system pods.
    DEFAULT_SYSTEM_CC_NAME="system-default-computeclass"
    
    # The YAML manifest for the recommended default ComputeClass for system pods.
    read -r -d '' DEFAULT_CC_YAML << EOF
    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: ${DEFAULT_SYSTEM_CC_NAME}
    spec:
      nodePoolAutoCreation:
        enabled: true
      whenUnsatisfiable: ScaleUpAnyway
      priorities:
      - machineFamily: t2d
    EOF
    
    # The label key to apply to namespaces.
    LABEL_KEY="cloud.google.com/default-compute-class-non-daemonset"
    
    
    # List of GKE system namespaces.
    SYSTEM_NAMESPACES=(
      "kube-system"
      "gke-gmp-system"
      "gmp-system"
      "gke-managed-cim"
      "gke-managed-volumepopulator"
      "gke-managed-checkpointing"
      "gkebackup"
      "gke-managed-lustrecsi"
    )
    
    
    # 1. Ask the user for their choice.
    echo "This script sets a default ComputeClass for GKE system namespaces."
    echo "--------------------------------------------------------------------"
    echo "The following ComputeClass is recommended for system Pods:"
    echo ""
    echo "$DEFAULT_CC_YAML"
    echo "--------------------------------------------------------------------"
    read -p "Do you want to use the recommended ComputeClass? (y/N): " user_choice
    
    CC_TO_APPLY=""
    
    # 2. Process the user's choice.
    if [[ "$user_choice" =~ ^[Yy]$ ]]; then
      # Path 1: User chose YES.
      echo "Installing the recommended default ComputeClass '${DEFAULT_SYSTEM_CC_NAME}'..."
    
      if ! echo "$DEFAULT_CC_YAML" | kubectl apply -f -; then
          # If kubectl apply fails, print an error and exit.
          echo "❌ Error: Failed to create the default ComputeClass. An internal error occurred."
          echo "Check for kubectl permissions or other cluster issues and re-run the script."
          exit 1
      fi
      # If the command succeeded, set the name to be used for labeling.
      CC_TO_APPLY="$DEFAULT_SYSTEM_CC_NAME"
    
    else
      read -p "Specify the name of an existing ComputeClass to set as the default for system Pods: " custom_cc_name
    
      # Validate that the user entered a name.
      while [[ -z "$custom_cc_name" ]]; do
        echo "Error: Name cannot be empty."
        read -p "Specify the name of an existing ComputeClass: " custom_cc_name
      done
    
      # Check if the specified ComputeClass actually exists in the cluster.
      echo "--> Verifying that ComputeClass '${custom_cc_name}' exists..."
      if kubectl get computeclass "$custom_cc_name" > /dev/null 2>&1; then
        echo "Verified."
        CC_TO_APPLY="$custom_cc_name"
      else
        echo "Error: ComputeClass '${custom_cc_name}' doesn't exist in the cluster."
        echo "Create the ComputeClass, and then then re-run this script."
        exit 1
      fi
    fi
    
    echo ""
    echo "Labelling system namespaces with ComputeClass: '${CC_TO_APPLY}'"
    echo "--------------------------------------------------------------------"
    
    # 3. Apply the label to all system namespaces.
    for ns in "${SYSTEM_NAMESPACES[@]}"; do
      # Gracefully handle namespaces that don't exist on this specific cluster.
      if kubectl get namespace "${ns}" > /dev/null 2>&1; then
        echo "--> Applying label to namespace: ${ns}"
        kubectl label namespace "${ns}" \
          "${LABEL_KEY}=${CC_TO_APPLY}" --overwrite
      else
        echo "--> Skipping namespace ${ns} (does not exist)"
      fi
    done
    
    echo ""
    echo "✅ Script finished successfully."

    這個指令碼使用 cloud.google.com/default-compute-class-non-daemonset 標籤,只會影響系統命名空間中非 DaemonSet 的 Pod。

  2. 執行指令碼:

    ./apply-system-cc.sh
    

指令碼完成後,所有新的非 DaemonSet 系統 Pod 預設都會使用指定的 ComputeClass,除非這些 Pod 已有 ComputeClass。這些命名空間中的現有 Pod 不會受到影響。如果 GKE 新增了系統命名空間,請再次執行這個指令碼,將變更套用至這些命名空間。

如要取消設定系統命名空間的預設 ComputeClass,請按照下列步驟操作:

  1. 將下列指令碼儲存為 unset-system-cc.sh

    #!/bin/bash
    
    # The recommended default ComputeClass name for system pods.
    DEFAULT_SYSTEM_CC_NAME="system-default-computeclass"
    
    # The YAML manifest for the recommended default ComputeClass for system pods.
    read -r -d '' DEFAULT_CC_YAML << EOF
    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: ${DEFAULT_SYSTEM_CC_NAME}
    spec:
      nodePoolAutoCreation:
        enabled: true
      whenUnsatisfiable: ScaleUpAnyway
      priorities:
      - machineFamily: t2d
    EOF
    
    # The label key to apply to namespaces.
    LABEL_KEY="cloud.google.com/default-compute-class-non-daemonset"
    
    
    # List of GKE system namespaces.
    SYSTEM_NAMESPACES=(
      "kube-system"
      "gke-gmp-system"
      "gmp-system"
      "gke-managed-cim"
      "gke-managed-volumepopulator"
      "gke-managed-checkpointing"
      "gkebackup"
      "gke-managed-lustrecsi"
    )
    
    
    # 1. Ask the user for their choice.
    echo "This script sets a default ComputeClass for GKE system namespaces."
    echo "--------------------------------------------------------------------"
    echo "The following ComputeClass is recommended for system Pods:"
    echo ""
    echo "$DEFAULT_CC_YAML"
    echo "--------------------------------------------------------------------"
    read -p "Do you want to use the recommended ComputeClass? (y/N): " user_choice
    
    CC_TO_APPLY=""
    
    # 2. Process the user's choice.
    if [[ "$user_choice" =~ ^[Yy]$ ]]; then
      # Path 1: User chose YES.
      echo "Installing the recommended default ComputeClass '${DEFAULT_SYSTEM_CC_NAME}'..."
    
      if ! echo "$DEFAULT_CC_YAML" | kubectl apply -f -; then
          # If kubectl apply fails, print an error and exit.
          echo "❌ Error: Failed to create the default ComputeClass. An internal error occurred."
          echo "Check for kubectl permissions or other cluster issues and re-run the script."
          exit 1
      fi
      # If the command succeeded, set the name to be used for labeling.
      CC_TO_APPLY="$DEFAULT_SYSTEM_CC_NAME"
    
    else
      read -p "Specify the name of an existing ComputeClass to set as the default for system Pods: " custom_cc_name
    
      # Validate that the user entered a name.
      while [[ -z "$custom_cc_name" ]]; do
        echo "Error: Name cannot be empty."
        read -p "Specify the name of an existing ComputeClass: " custom_cc_name
      done
    
      # Check if the specified ComputeClass actually exists in the cluster.
      echo "--> Verifying that ComputeClass '${custom_cc_name}' exists..."
      if kubectl get computeclass "$custom_cc_name" > /dev/null 2>&1; then
        echo "Verified."
        CC_TO_APPLY="$custom_cc_name"
      else
        echo "Error: ComputeClass '${custom_cc_name}' doesn't exist in the cluster."
        echo "Create the ComputeClass, and then then re-run this script."
        exit 1
      fi
    fi
    
    echo ""
    echo "Labelling system namespaces with ComputeClass: '${CC_TO_APPLY}'"
    echo "--------------------------------------------------------------------"
    
    # 3. Apply the label to all system namespaces.
    for ns in "${SYSTEM_NAMESPACES[@]}"; do
      # Gracefully handle namespaces that don't exist on this specific cluster.
      if kubectl get namespace "${ns}" > /dev/null 2>&1; then
        echo "--> Applying label to namespace: ${ns}"
        kubectl label namespace "${ns}" \
          "${LABEL_KEY}=${CC_TO_APPLY}" --overwrite
      else
        echo "--> Skipping namespace ${ns} (does not exist)"
      fi
    done
    
    echo ""
    echo "✅ Script finished successfully."
  2. 執行指令碼:

    ./unset-system-cc.sh
    

為叢集設定預設 ComputeClass

您可以將任何自訂 ComputeClass 設為整個叢集的預設值。 這個程序包括在叢集中啟用叢集層級的預設 ComputeClass,然後建立名為 default 的 ComputeClass。您甚至可以在名為 default 的 ComputeClass 中指定相同的優先順序規則,取得內建 Autopilot ComputeClass 的行為。

如要在叢集中正確使用預設 ComputeClass,請務必執行下列兩個步驟:

  1. 如要為叢集啟用叢集層級的預設 ComputeClass 設定,請在建立或更新叢集時使用 --enable-default-compute-class 旗標

    • 建立叢集

      gcloud container clusters create CLUSTER_NAME \
          --location=CONTROL_PLANE_LOCATION \
          --enable-default-compute-class
      

      更改下列內容:

      • CLUSTER_NAME:叢集名稱。
      • CONTROL_PLANE_LOCATION:叢集控制層的位置,例如 us-central1
    • 更新叢集

      gcloud container clusters update CLUSTER_NAME \
          --location=CONTROL_PLANE_LOCATION \
          --enable-default-compute-class
      

      更改下列內容:

      • CLUSTER_NAME:叢集名稱。
      • CONTROL_PLANE_LOCATION:叢集控制層的位置,例如 us-central1

    完成這個步驟後,GKE 會在叢集中尋找名為 default 的 ComputeClass。設定 default ComputeClass 前,工作負載不會有任何變更。

  2. 建立名為 default 的 ComputeClass,如下列範例所示:

    • 下列 ComputeClass 會要求特定機器系列:

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: default
      spec:
        priorities:
        - machineFamily: n4
        - machineFamily: n2
        whenUnsatisfiable: ScaleUpAnyway
        nodePoolAutoCreation:
          enabled: true
      

      這個 ComputeClass 會要求使用 N4 執行個體的節點。如果 N4 執行個體無法使用,ComputeClass 會改為要求 N2 執行個體。您可以透過 ComputeClass CustomResourceDefinition 中的任何可用欄位,設定 default ComputeClass。

    • 下列 ComputeClass 會向 Autopilot 容器最佳化運算平台提出要求:

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: default
      spec:
        autopilot:
          enabled: true
        priorities:
        - podFamily: general-purpose
        whenUnsatisfiable: ScaleUpAnyway
      

      這個 ComputeClass 符合 autopilot 內建 ComputeClass 的行為,但 whenUnsatisfiable 欄位除外,該欄位的值為 ScaleUpAnyway,而非 DoNotScaleUp。這項修改有助於避免 Pod 使用特定硬體的節點選取器,但因套用叢集層級的預設 ComputeClass 而處於待處理狀態。

      podFamily優先順序規則會將 Pod 放置在 Autopilot 容器最佳化運算平台上。這項優先順序規則需要 GKE 1.35.2-gke.1485000 以上版本。

  3. 在叢集中建立 default ComputeClass:

    kubectl apply -f PATH_TO_MANIFEST
    

    PATH_TO_MANIFEST 替換為 ComputeClass 的資訊清單路徑。

  4. 選用:如果 Standard 叢集已手動建立節點集區,並做為一般用途工作負載的預設集區,您可以將這些工作負載移至 Autopilot 模式執行,前提是您已將 Autopilot ComputeClass 設為叢集層級的預設值。如要遷移這些工作負載,請封鎖並排除節點集區中的所有節點。GKE 會使用叢集層級的預設 ComputeClass,排定新的待處理 Pod。

設定叢集層級的預設 ComputeClass 後,GKE 會擴充符合下列兩項條件的節點集區:

  • 節點設定與 default ComputeClass 的設定相同。
  • 節點集區沒有其他 ComputeClass 的汙點或標籤。 GKE 可以擴充具有汙點和 default ComputeClass 標籤的節點集區。

舉例來說,如果 default ComputeClass 指定 N4 機器系列,GKE 可以調整現有節點集區的資源配置,該集區使用 N4 執行個體,且沒有其他 ComputeClass 的 taint 或標籤。

變更會套用至叢集中所有沒有 ComputeClass 的新 Pod。現有 Pod 可能會受到影響,具體情況取決於叢集層級預設 ComputeClass 的有效遷移設定。詳情請參閱「預設 ComputeClass 中的主動遷移」。

驗證預設 ComputeClass 行為

如要檢查為命名空間或叢集設定的預設 ComputeClass 是否正常運作,請按照下列步驟操作:

  1. 請查看下列 Deployment 範例:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloweb
      labels:
        app: hello
    spec:
      selector:
        matchLabels:
          app: hello
          tier: web
      template:
        metadata:
          labels:
            app: hello
            tier: web
        spec:
          containers:
          - name: hello-app
            image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
            ports:
            - containerPort: 8080
            resources:
              requests:
                cpu: 200m

    這個 Deployment 並未明確要求 ComputeClass。

  2. 建立 Deployment:

    kubectl apply --namespace=NAMESPACE_NAME \
        -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/quickstarts/hello-app/manifests/helloweb-deployment.yaml
    

    視要驗證的項目而定,將 NAMESPACE_NAME 替換為下列其中一個值:

    • 具有預設 ComputeClass 的命名空間名稱。
    • 沒有預設 ComputeClass 的命名空間名稱。

    GKE 可能需要一些時間才能建立新節點來執行 Pod。

  3. 找出執行範例 Deployment 中 Pod 的節點:

    kubectl get pods --namespace=NAMESPACE_NAME \
        --selector=app=hello -o=wide
    

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

    NAME                        READY   STATUS    RESTARTS   AGE     IP          NODE                                                  NOMINATED NODE   READINESS GATES
    helloweb-7795fbf856-58n5l   1/1     Running   0          9m21s   10.52.2.3   gke-cluster-1-nap-n2-highcpu-2-3muqi8-f213e529-rx7d   <none>           <none>
    
  4. 取得節點標籤:

    kubectl get node NODE_NAME --show-labels \
        | grep "cloud.google.com/compute-class"
    

    NODE_NAME 替換為上一步輸出內容中的節點名稱。

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

    NODE_NAME   Ready    <none>   22m   v1.32.4-gke.1236007
    # lines are omitted from this output
    cloud.google.com/compute-class=COMPUTECLASS_NAME,cloud.google.com/gke-boot-disk=pd-balanced,cloud.google.com/gke-container-runtime=containerd
    

    COMPUTECLASS_NAME 中的值為下列其中之一:

    • 叢集層級的預設 ComputeClass:適用於由 GKE Autopilot 或節點集區自動建立的節點。default手動建立的現有節點集區中,節點可能沒有 cloud.google.com/compute-class 標籤。
    • 命名空間層級的預設 ComputeClass:您設定為命名空間預設值的 ComputeClass 名稱。

停用預設的 ComputeClass

如要在命名空間或叢集中停用預設 ComputeClass,請執行下列其中一項操作:

  • 如要為所有 Pod 停用命名空間層級的預設 ComputeClass,請從命名空間移除 cloud.google.com/default-compute-class 標籤:

    kubectl label namespaces NAMESPACE_NAME \
      cloud.google.com/default-compute-class-
    

    標籤鍵結尾的 - 字元會從 Kubernetes API 的 Namespace 物件中移除具有該鍵的所有標籤。

  • 如要為非 DaemonSet Pod 停用命名空間層級的預設 ComputeClass,請從命名空間移除 cloud.google.com/default-compute-class-non-daemonset 標籤:

    kubectl label namespaces NAMESPACE_NAME \
      cloud.google.com/default-compute-class-non-daemonset-
    
  • 如要停用叢集層級的預設 ComputeClass,請使用 gcloud container clusters update 指令並加上 --no-enable-default-compute-class 旗標:

    gcloud container clusters update CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --no-enable-default-compute-class
    

後續步驟