默认将 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。如需了解详情,请参阅 要求部分。
  • 如果您使用的是 Standard 模式集群,请确保满足以下要求之一:

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

要求

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

所需的角色和权限

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

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

这些预定义角色可提供配置集群级或命名空间级默认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,然后创建一个名为 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。此修改有助于防止以下情况:由于集群级默认 ComputeClass 应用于使用特定硬件的节点选择器的 Pod,因此这些 Pod 仍处于待处理状态。

      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 ComputeClass 设置为集群级默认值后,您可以将这些工作负载移至 Autopilot 模式下运行。如需移动 这些工作负载, 请封锁并排空节点池中的所有节点。GKE 会使用集群级默认 ComputeClass 来调度新的待处理 Pod。

设置集群级默认 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 中的值是以下项之一:

停用默认 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
    

后续步骤