默认将 ComputeClass 应用于 Pod

本文档介绍了如何默认将 ComputeClass 应用于未明确选择 ComputeClass 的 Google Kubernetes Engine (GKE) Pod。还介绍了如何将某个ComputeClass设置为命名空间和整个集群的默认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。如需了解详情,请参阅要求部分。
  • 如果您使用的是 Standard 模式集群,请确保满足以下要求之一:

  • 如果您想将自定义 ComputeClass 设置为命名空间的默认值,请部署自定义 ComputeClass

要求

  • 如需将ComputeClass设置为集群级默认ComputeClass,集群必须运行 GKE 1.33.1-gke.1744000 版或更高版本。
  • 如需将ComputeClass设置为仅适用于非 DaemonSet Pod 的命名空间级默认ComputeClass,集群必须运行 GKE 1.33.1-gke.1788000 版或更高版本。

所需的角色和权限

如需获得配置集群级或命名空间级默认ComputeClass所需的权限,请让您的管理员为您授予 Google Cloud 项目的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

这些预定义角色可提供配置集群级或命名空间级默认ComputeClass所需的权限。如需查看所需的确切权限,请展开所需权限部分:

所需权限

配置集群级或命名空间级默认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 命名空间添加注解,以将其用作默认ComputeClass。如果部署到该命名空间的 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的名称。

    如果命令失败并显示以下错误消息,则表示命名空间已设置默认 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的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,除非它们已具有 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,请勿为集群中的现有节点池手动指定节点污点和节点标签。 GKE 不会扩缩具有ComputeClass节点污点的节点池。如果您手动为 default ComputeClass添加标签,GKE 就可以扩缩该节点池。不过,您无需进行此手动配置即可使用默认的集群级计算类。

  1. 如需启用为集群设置集群级默认ComputeClass的功能,请在运行 gcloud container clusters update 命令时使用 --enable-default-compute-class 标志

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

    替换以下内容:

    • CLUSTER_NAME:您的集群的名称。
    • CONTROL_PLANE_LOCATION:集群控制平面的位置,例如 us-central1

    您还可以在创建 Autopilot 或 Standard 集群时指定此标志。

  2. 保存以下清单,该清单定义了一个名为 defaultComputeClass

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

    此示例清单请求使用 N4 实例的节点。如果 N4 实例不可用,ComputeClass 会改为请求 N2 实例。您可以使用 ComputeClass CustomResourceDefinition 中的任何可用字段来配置 default ComputeClass。

  3. 将清单应用到您的集群:

    kubectl apply -f PATH_TO_MANIFEST
    

    PATH_TO_MANIFEST 替换为ComputeClass清单的路径。

设置集群级默认ComputeClass后,GKE 会扩缩节点池以满足以下两个要求:

  • 节点配置与 default ComputeClass 的配置相同。
  • 节点池没有其他ComputeClass的污点或标签。 GKE 可以扩缩具有 default ComputeClass的污点和标签的节点池。

例如,如果 default ComputeClass 指定了 N4 机器系列,则 GKE 可以扩缩使用 N4 实例且没有其他 ComputeClass 的污点或标签的现有节点池。

您的更改会应用于集群中所有尚未具有 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 中的值是以下项之一:

    • 集群级默认 ComputeClassdefault,适用于由 GKE Autopilot 创建或通过节点池自动创建创建的节点。现有手动创建的节点池中的节点可能没有 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
    

后续步骤