排查自定义 ComputeClass 问题

本文档可帮助您排查以下问题:GKE 工作负载无法在由自定义 ComputeClass 定义的节点上调度,或者集群自动扩缩器未预配预期的机器类型。

本文档适用于应用开发者、平台管理员和运维人员,他们使用自定义 ComputeClass 在 GKE 中管理工作负载调度和节点池自动创建。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

主要概念

为帮助您排查问题,请确保您熟悉以下 GKE 组件和机制:

  • 自定义 ComputeClass:一种 GKE 特有的资源,可让您为自动扩缩定义节点配置的优先级列表。如需了解详情,请参阅自定义 ComputeClass 简介

  • 集群自动扩缩器:根据工作负载需求自动在集群中添加或移除节点的组件。 如需了解详情,请参阅 GKE 集群自动扩缩简介

  • 节点池自动创建:GKE 集群自动扩缩器会根据工作负载要求自动创建和管理节点池。如需了解详情,请参阅节点池自动创建简介

  • 回退逻辑:一种机制,集群自动扩缩器会尝试先预配与最高优先级规则匹配的节点。如需了解详情,请参阅选择回退计算优先级

按症状排查问题

本文档按顺序组织了问题排查步骤,从基本检查到更高级的配置。如需更全面地诊断问题,我们建议您按顺序执行以下步骤。或者,如果您遇到特定问题,请参阅下表中的相关链接:

症状 问题排查步骤
请求自定义 ComputeClass 的 Pod 卡在 Pending 状态
集群自动扩缩器未创建与自定义 ComputeClass 匹配的新节点
集群自动扩缩器创建的是默认机器类型,而不是专用类型 分析自动扩缩器的回退行为
kubectl describe computeclass 命令的输出显示健康状况不佳 验证自定义 ComputeClass 配置
工作负载未迁移到优先级更高的节点 验证集群自动扩缩器的一般健康状况
GPU 或 Spot 虚拟机工作负载存在调度问题

范围外问题

本文档未解决以下问题:

  • 常规 GKE 网络问题,例如 Pod 到 Pod 的连接或服务负载均衡。
  • 与 Pod 横向自动扩缩器 (HPA) 或 Pod 纵向自动扩缩器 (VPA) 相关的问题。
  • 与自定义 ComputeClass 机制无关的问题,例如应用级错误或与调度限制无关的 PersistentVolume 问题。
  • 与 ComputeClass 回退逻辑没有直接关联的配额或资源不可用问题。

识别占位变量

如需自定义本文档中的命令,请在 Variable 列中输入具体值。编辑后的值会自动在所有代码块和命令中同步。

变量 说明
PROJECT_ID 您的 Google Cloud 项目 ID。
LOCATION 集群所在的 Compute Engine 区域或可用区。
CLUSTER_NAME 集群的名称。
NODE_POOL_NAME 要检查的节点池的名称(如果适用于 Standard 集群)。
CUSTOM_COMPUTECLASS_NAME Pod 所请求的自定义 ComputeClass 的名称。
NAMESPACE 无法调度的 Pod 的命名空间。
POD_NAME 无法调度的 Pod 的名称。

准备工作

如需获得执行本文档中的任务所需的权限,请让您的管理员为您授予 Google Cloud 项目的以下 IAM 角色:

  • 访问 GKE 集群:Kubernetes Engine Cluster Viewer (roles/container.viewer)。
  • 查看日志:Logs Viewer (roles/logging.viewer)。
  • 管理 GKE 集群: Kubernetes Engine Admin (roles/container.admin)。

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

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

如需配置 kubectl 以与集群通信,请运行以下命令:

  gcloud container clusters get-credentials CLUSTER_NAME
      --location LOCATION
      --project PROJECT_ID

执行基本诊断检查

验证核心组件是否已正确配置,以及集群是否支持自定义 ComputeClass。

验证 Pod 状态和选择器

确认 Pod 处于 Pending 状态,并正确请求了自定义 ComputeClass。

  1. 列出处于 Pending 状态的 Pod:

    kubectl get pods --all-namespaces -o wide | grep Pending
    
  2. 检查 Pod 规范中的 nodeSelector 字段:

    kubectl get pod POD_NAME
        -n NAMESPACE
        -o jsonpath='{.spec.nodeSelector}'
    

评估结果

  • 输出显示标签nodeSelector 字段已正确配置为 cloud.google.com/compute-class 标签。
  • 输出未显示标签
    • 解读:工作负载的部署配置中可能存在 cloud.google.com/compute-class 标签的 nodeSelector 字段不正确或缺失的情况。
    • 解决方法:修改工作负载的 YAML 文件(例如 Deployment 或 Job),以在 spec.template.spec 部分中添加 nodeSelector 字段。

验证集群版本兼容性

自定义 ComputeClass 需要 GKE 1.30.3-gke.1451000 版或更高版本。验证您的集群是否正在运行支持自定义 ComputeClass 的版本。

检查集群版本:

gcloud container clusters describe CLUSTER_NAME
    --location LOCATION
    --format="value(currentMasterVersion)"

评估结果

  • 版本 1.30.3-gke.1451000 或更高版本:您的集群版本支持自定义 ComputeClass。
  • 低于 1.30.3-gke.1451000 的版本
    • 解读:您的集群尚未升级到支持自定义 ComputeClass 的版本。
    • 解决方法:您必须升级集群才能使用自定义 ComputeClass。

验证自定义 ComputeClass 配置

自定义 ComputeClass 资源中的配置错误可能会阻止 Pod 调度或阻止 GKE 正确预配节点。

检查 ComputeClass 健康状况和状态

验证 GKE 是否将自定义 ComputeClass 报告为健康状况良好。

  1. 列出所有 ComputeClass 资源:

    kubectl get computeclass
    
  2. 描述特定的 ComputeClass 资源:

    kubectl describe computeclass CUSTOM_COMPUTECLASS_NAME
    

评估结果

  • 健康状况显示 True:自定义 ComputeClass 运行正常。以下是运行正常的自定义 ComputeClass 的示例:

    Status:
      Conditions:
        Last Transition Time:  2024-01-19T17:18:48Z
        Message:               CCC is healthy.
        Reason:                Health
        Status:                True
        Type:                  Health
    
  • 健康状况显示为 False

    • 解读:自定义 ComputeClass 处于不健康状态。查看输出中的 MessageReason 字段,以确定问题。
    • 解决方法:执行与输出中的 Reason 字段对应的操作:
      • NodePoolNotExist:确保引用的节点池存在,或更新 ComputeClass 以引用现有节点池。
      • ReservationUnusable:检查所引用预留的配置和使用情况。
      • Invalid machine type:更新 ComputeClass 以使用集群的区域或可用区中支持的机器类型。

验证 unsatisfiable 政策

whenUnsatisfiable 字段用于确定在无法满足任何优先级规则时的行为。

查阅相关政策:

kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml

检查输出中的 spec.whenUnsatisfiable 字段。此字段可使用以下值之一:

  • DoNotScaleUp:如果无法创建首选节点,Pod 将保持 Pending 状态。
  • ScaleUpAnyway:如果首选节点不可用,Pod 可能会在默认节点类型(例如 E2 系列)上运行。

评估结果

whenUnsatisfiable 政策的效果取决于其值:

  • 如果值为 DoNotScaleUp
    • 解读:如果无法满足任何优先级规则,则会出现此预期行为,这可能是因为资源不可用配额限制。如果 Pod 必须等待特定硬件,则此值是正确的。
    • 解决方法:如果运行工作负载比在特定硬件上运行更重要,请将政策更改为 ScaleUpAnyway
  • 如果值为 ScaleUpAnyway
    • 解读:这是预期行为。GKE 正在回退到默认节点类型,因为首选节点不可用。
    • 解决方法:如果 Pod 不得在默认节点类型上运行,请将政策更改为 DoNotScaleUp
  • 默认行为:如果您未为 whenUnsatisfiable 字段指定值,并且使用的是低于 1.33 的 GKE 版本,则政策默认设置为 ScaleUpAnyway

以下示例展示了如何通过修改 ComputeClass 清单中的 whenUnsatisfiable 字段来更新政策:

apiVersion: cloud.google.com/v1
kind: ComputeClass
metadata:
  name: CUSTOM_COMPUTECLASS_NAME
spec:
  # ... other fields
  whenUnsatisfiable: DoNotScaleUp # or ScaleUpAnyway

检查 Pod 调度限制

确保您的 Pod 规范与自定义 ComputeClass 预配的节点的属性兼容。

验证 Pod 资源请求

检查自定义 ComputeClass 的 priorities 字段中定义的至少一种机器类型是否可以满足 Pod 的 CPU、内存和 GPU 请求。

  1. 获取 Pod 资源请求:

    kubectl get pod POD_NAME
        -n NAMESPACE
        -o jsonpath='{.spec.containers[*].resources.requests}'
    

    检查输出中是否存在 cpumemory 和 GPU 请求(例如 nvidia.com/gpu)。

  2. 将这些请求与自定义 ComputeClass 的 priorities 字段中定义的机器类型进行比较:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME
        -o jsonpath='{.spec.priorities}'
    

    检查输出中是否存在 machineTypemachineFamily 字段。对于自定义 ComputeClass 中的每种机器类型,请在机器类型文档中查看其规范,并验证其可分配资源是否大于 Pod 的请求。

评估结果

  • 资源兼容:Pod 的资源请求小于或等于 ComputeClass 中至少一种机器类型的可分配资源。
  • 资源超出容量

    • 解读:无法调度 Pod,因为 ComputeClass 中没有机器类型提供足够的 CPU、内存或 GPU。如果 nodePoolAutoCreation 字段设置为 true,且 Pod 的内存请求超过自动创建的节点池的限制,也会发生这种情况。
    • 解决方案:调整 Pod 的资源请求或自定义 ComputeClass 的机器类型:
      • 减少 Pod 资源请求:如果资源请求较高,请降低工作负载 YAML 文件中的 cpumemorygpu 值。
      • 更改为更大的机器类型:如果 Pod 的请求合理,请修改自定义 ComputeClass 清单中的 spec.priorities 字段,以包含可以满足 Pod 需求的更大的 machineTypemachineFamily 选项。例如:
    spec:
      priorities:
      - machineType: n2d-highmem-96 # A larger machine type
        spot: true
      # ... other priorities
    

检查是否存在冲突的污点和容忍设置

为自定义 ComputeClass 创建的节点具有 cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule 污点。GKE 会自动将此容忍设置添加到 Pod。

不过,GPU 等专用硬件具有额外的污点,例如 nvidia.com/gpu=present:NoSchedule 污点。如果您的 ComputeClass 使用具有专用硬件的节点,则 Pod 必须容忍这些污点,才能在这些节点上进行调度。

检查 Pod 的 tolerations 字段:

kubectl get pod POD_NAME
    -n NAMESPACE
    -o jsonpath='{.spec.tolerations}'

评估结果

  • 正确的容忍:污点和容忍已正确配置。
  • 缺少容忍度

    • 解读:缺少容忍度会导致 Pod 无法调度到具有专用硬件污点的节点上。例如,如果 ComputeClass 使用 GPU 节点,则 Pod 可能缺少 nvidia.com/gpu=present:NoSchedule 容忍度。如需了解 GPU 特有的要求,请参阅验证 GPU 配置
    • 解决方案:在 Pod 规范的 tolerations 字段中,添加必要的容忍,以匹配由 ComputeClass 定义的节点上的污点。例如,对于 GPU 节点,请按如下方式添加对 nvidia.com/gpu=present:NoSchedule 污点的容忍:

      spec:
      template:
      spec:
      tolerations:
      - key: "nvidia.com/gpu"
      operator: "Exists"
      effect: "NoSchedule"
      # ... other tolerations and Pod spec
      

节点池配置(Standard 集群)

在 GKE Standard 集群中,手动创建的节点池必须带有标签和污点,才能与自定义 ComputeClass 搭配使用。

验证节点池标签和污点

  1. 在自定义 ComputeClass 中标识节点池。如果自定义 ComputeClass 使用 nodePools 字段,请记下列出的节点池的名称:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    
  2. 对于您确定的每个节点池,请验证其配置:

    gcloud container node-pools describe NODE_POOL_NAME
        --cluster CLUSTER_NAME
        --location LOCATION
        --format="yaml(config.labels, config.taints)"
    

评估结果

  • 节点池已正确配置:节点池具有标签 cloud.google.com/compute-class: CUSTOM_COMPUTECLASS_NAME 和污点 cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule
  • 节点池配置错误

    • 解读:节点池未配置与自定义 ComputeClass 关联所需的标签和污点。
    • 解决方案更新节点池以添加标签和污点:

      1. 添加或更新节点标签:

        gcloud container node-pools update NODE_POOL_NAME \
            --cluster=CLUSTER_NAME --location=LOCATION \
            --node-labels=cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME
        
      2. 添加或更新节点污点:

        gcloud container node-pools update NODE_POOL_NAME \
            --cluster=CLUSTER_NAME --location=LOCATION \
            --node-taints=cloud.google.com/compute-class=CUSTOM_COMPUTECLASS_NAME:NoSchedule
        

验证节点池自动创建配置

对于 nodePoolAutoCreation 设置为 true 的 Autopilot 集群和 Standard 集群,必须正确配置节点池自动创建功能。

验证是否已启用节点池自动创建

  1. 检查自定义 ComputeClass 中的 nodePoolAutoCreation.enabled 字段是否已设置为 true

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    
  2. 检查集群上是否启用了节点池自动创建功能:

    gcloud container clusters describe CLUSTER_NAME
        --location LOCATION
        --format="value(autoscaling.enableNodeAutoprovisioning)"
    

如果任一设置处于停用状态,节点池自动创建功能将不会为您的自定义 ComputeClass 创建新的节点池。

评估结果

  • 已启用节点池自动创建:在 ComputeClass 中,nodePoolAutoCreation.enabled 字段设置为 true,并且在集群级启用了节点自动预配。
  • 节点池自动创建已停用

    • 解读:如果 ComputeClass 中 nodePoolAutoCreation.enabled 字段的值为 false 或缺失,或者如果集群级节点自动预配已停用,则节点池自动创建功能处于停用状态。
    • 解决方案:启用节点池自动创建:

      1. 修改自定义 ComputeClass YAML 文件以包含 nodePoolAutoCreation: enabled: true

        spec:
          # ... priorities
          nodePoolAutoCreation:
            enabled: true
        
      2. 在集群级启用节点池自动创建并配置资源限制

        gcloud container clusters update CLUSTER_NAME --location LOCATION \
          --enable-autoprovisioning \
          --autoprovisioning-min-cpu=MIN_CPU \
          --autoprovisioning-max-cpu=MAX_CPU \
          --autoprovisioning-min-memory=MIN_MEMORY \
          --autoprovisioning-max-memory=MAX_MEMORY
        

检查节点池自动创建的资源限制

节点池自动创建功能对 CPU 和内存资源有集群范围的限制。如果集群的当前使用量加上新节点的资源量超过这些限制,节点池自动创建功能将不会预配新节点。

  1. 查看资源限制:

    gcloud container clusters describe CLUSTER_NAME
        --location LOCATION
    --format="value(autoscaling.resourceLimits)"
    

    输出会列出 CPU 和内存(以 GB 为单位)的 resourceTypeminimummaximum 字段。

  2. 查看自定义 ComputeClass 的优先级中的机器类型。您可以在机器类型文档中查看其 CPU 和内存规格。

  3. 确定集群中所有节点的当前 CPU 和内存总容量。当前容量与潜在新节点的资源之和不得超过节点池自动创建的最大限制。

评估结果

  • 容量充足:集群在资源限制范围内具有足够的 CPU 和内存容量,可供节点池自动创建功能预配新节点。
  • 超出限额

    • 解读:节点池自动创建功能无法预配新节点,因为集群已达到 CPU 或内存限制,或者为 ComputeClass 中的机器类型设置的限制过低。
    • 解决方案:增加节点池自动创建的资源限制:

      1. 确定新的上限,其中要考虑到当前使用情况和未来增长,包括自定义 ComputeClass 中的最大机器类型。

      2. 更新节点池自动创建的资源限制。您可以在一个命令中设置多个资源:

        gcloud container clusters update CLUSTER_NAME --location LOCATION \
          --set-nap-resource-limits resourceType=cpu,maximum=NEW_MAX_CPU \
          --set-nap-resource-limits resourceType=memory,maximum=NEW_MAX_GB
        

分析自动扩缩器的回退行为

本部分可帮助您调查外部因素,了解集群自动扩缩器为何可能跳过首选选项并使用后备选项,或无法进行纵向扩容。

自定义 ComputeClass 使用优先级后备逻辑。如果 Pod 未在符合最高优先级规则的节点上进行调度,通常是由于资源不可用或项目配额等限制。如果 GKE 无法预配符合特定优先级规则的节点(例如,由于 Compute Engine 出现 ZONE_RESOURCE_POOL_EXHAUSTEDQUOTA_EXCEEDED 错误),集群自动扩缩器会立即尝试 priorities 列表中的下一个规则。在 GKE 回退到下一个优先级之前,没有等待时间,但使用 TPU 或 Flex Start 预配模型时除外,它们支持可配置的延迟时间。

检查资源是否不可用

通过检查集群自动扩缩器日志或 Compute Engine 托管式实例组 (MIG) 错误,验证指定可用区中的资源是否不可用。

选项 1:检查集群自动扩缩器可见性事件

在 Google Cloud 控制台中,前往 Cloud Logging > Logs Explorer,然后运行以下查询,以查找可能表明资源不可用的自动扩缩器事件:

resource.type="k8s_cluster"
resource.labels.location="LOCATION"
resource.labels.cluster_name="CLUSTER_NAME"
log_id("container.googleapis.com/cluster-autoscaler-visibility")
jsonPayload.noScaleUpReason.messageId="no.scale.up.nap.resource.exhausted"

方法 2:检查 MIG 错误

您可以在 Google Cloud 控制台中或使用 Cloud Logging 查询来检查 MIG 错误。

  • 使用 Google Cloud 控制台

    1. 在 Google Cloud 控制台中,依次前往 Compute Engine > 实例组
    2. 找到与无法扩容的节点池对应的 MIG。
    3. 点击 MIG 名称,然后前往错误标签页。查找指示资源耗尽的消息。
  • 使用 Cloud Logging 查询

    1. 在 Google Cloud 控制台中,前往 Cloud Logging > 日志浏览器
    2. 运行以下查询,检查 MIG 是否出现资源耗尽错误:
    resource.type="gce_instance"
    log_id("cloudaudit.googleapis.com/activity")
    protoPayload.status.message:("ZONE_RESOURCE_POOL_EXHAUSTED" OR "does not have enough resources available to fulfill the request" OR "resource pool exhausted" OR "does not exist in zone")
    

评估结果

  • 资源可用:如果日志未显示 ZONE_RESOURCE_POOL_EXHAUSTED 消息,则资源不可用不太可能是扩容失败的原因。
  • 资源不可用

    • 解读:节点预配失败,原因可能是相应可用区中对特定机器类型(尤其是 Spot 虚拟机或 GPU)的需求暂时较高,也可能是 Pod 受 PersistentVolume 亲和性限制,只能在资源不可用的可用区中运行。
    • 解决方法:资源不可用是暂时性的,但您可以通过在配置中添加灵活性来提高恢复能力:

      • 多样化机器类型:确保自定义 ComputeClass 中的 spec.priorities 字段包含多个机器类型或系列作为后备:

        spec:
          priorities:
          - machineFamily: c3  # Highest priority
          - machineFamily: n2d # Fallback option
          - machineFamily: e2  # Lowest priority
        
      • 使用区域级集群:如果集群是可用区级集群,则很容易受到单个可用区内资源不可用的影响。使用区域性集群可让集群自动扩缩器尝试在区域内可能存在容量的其他可用区中预配节点。

      • 使用 Compute Engine 预留:对于无法容忍延迟的关键工作负载,请创建 Compute Engine 预留,以帮助确保特定机器类型的容量。

验证项目配额

确认您的项目有足够的配额来支持新节点所需的资源,例如 CPU、GPU 和 IP 地址。

  1. 检查自动扩缩器日志中是否存在配额错误。使用 Cloud Logging 在自动扩缩器可见性事件中搜索与配额相关的错误消息:

    resource.type="k8s_cluster"
    resource.labels.location="LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    log_id("container.googleapis.com/cluster-autoscaler-visibility")
    jsonPayload.noScaleUpReason.messageId="no.scale.up.nap.quota.exceeded"
    

    或者,您也可以使用以下 Cloud Logging 查询来检查 MIG 中与配额相关的错误日志:

    resource.type="gce_instance"
    protoPayload.methodName:"compute.instances.insert"
    protoPayload.status.message:"QUOTA_EXCEEDED"
    severity=ERROR
    
  2. 在 Google Cloud 控制台中查看配额:

    1. 在 Google Cloud 控制台中,前往 IAM 和管理 > 配额
    2. 过滤出 Compute Engine API 服务。
    3. 检查 GKE 集群所在区域的相关指标(例如 CPU、GPU [所有类型] 和正在使用的 IP 地址)的使用情况。验证当前使用量是否未达到上限。

评估结果

  • 配额低于限制:如果配额用量低于配额限制,并且日志中未发现任何 QUOTA_EXCEEDED 错误,则配额限制不会阻止扩容。
  • 超出配额
    • 解读:由于 CPU、GPU、IP 地址或 MIG 等资源的配额不足,节点配置失败。
    • 解决方法:如果您的项目已达到配额限制,请申请提高配额

高级配置

GPU、Spot 虚拟机和 Compute Engine 预留等配置有各自的特定要求和潜在故障点,需要进行检查。

验证 GPU 配置

对于预配 GPU 节点的自定义 ComputeClass,请验证自定义 ComputeClass 中的 GPU 配置,并确保 Pod 具有必需的 nvidia.com/gpu 容忍度。

  1. 检查自定义 ComputeClass 的 YAML 中是否存在优先级规则内的 gpu 块:

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    

    gpu 块应指定 type 字段和 count 字段,例如:

    priorities:
    - machineType: a2-highgpu-1g
      gpu:
        type: nvidia-tesla-a100
        count: 1
    
  2. 检查 Pod 的 GPU 容忍度。任何需要在 GPU 节点上调度的 Pod 必须具有 nvidia.com/gpu 容忍设置,即使该 Pod 本身不请求 GPU。

    kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.tolerations}'
    

    检查 spec.tolerations 字段下的容忍度。

评估结果

  • GPU 配置正确:如果 ComputeClass 定义了 GPU typecount,并且 Pod 包含 nvidia.com/gpu 容忍度,则 GPU 配置正确。以下内容显示了所需的容忍度:

    tolerations:
    - key: "nvidia.com/gpu"
      operator: "Exists"
      effect: "NoSchedule"
    
  • GPU 配置错误

    • 解读:Pod 可能缺少所需的 nvidia.com/gpu 容忍度,ComputeClass 可能因 GPU 字段不匹配而处于不健康状态,或者 GKE 版本可能无法正确处理 GPU 配置。
    • 解决方法:请执行以下操作之一:
      • 修改工作负载的 YAML 文件以包含必需的 GPU 容忍度,然后重新应用该 YAML 文件。
      • 升级 GKE 集群。如果自定义 ComputeClass 不正常,且问题与 GPU 字段相关,请检查是否存在已知问题,并升级到已修复的 GKE 版本,例如 1.31.8-gke.1045000 或更高版本。

验证 Spot 虚拟机配置

如果您使用 Spot 虚拟机,请确保 spot: true 设置位于 ComputeClass 清单中的正确优先级规则中。此外,请务必了解集群自动扩缩器的价格计算逻辑。

检查 ComputeClass 清单:

kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml

在输出中,查找 spec.priorities 字段中的 spot: true,例如:

priorities:
- machineFamily: n2d
  spot: true

在比较不同 Spot 虚拟机类型的费用时,集群自动扩缩器可能会使用 us-central1 中的价格数据作为基准,这可能会导致在其他区域做出看似非最佳的选择。这是已知行为。

评估结果

  • Spot 虚拟机配置正确:如果指定了 spot: true 字段,并且集群自动扩缩器预配了 Spot 虚拟机,则配置会按预期运行。
  • Spot 虚拟机无法调度

    • 解读:需要 Spot 虚拟机的 Pod 可能因目标可用区中的资源不可用而无法在 Spot 虚拟机上进行调度,或者集群自动扩缩器可能基于其 us-central1 定价模型选择其他虚拟机类型。
    • 解决方法

      • 如果您怀疑资源不可用,请参阅检查资源是否不可用
      • 如需控制 Spot 虚拟机的选择,请在 priorities 字段中明确列出 machineType 条目,并按从最便宜到最昂贵的区域排列。这种方法可让您直接控制回退顺序。例如:

        spec:
          priorities:
          - machineType: t2d-standard-48 # Cheapest in this region
            spot: true
          - machineType: n2d-standard-48 # Fallback Spot option
            spot: true
          - machineType: n2d-standard-48 # On-demand fallback
            spot: false
        

集群自动扩缩器的总体运行状况

本部分可帮助您检查可能与自定义 ComputeClass 配置没有直接关系但可能会影响其运行的问题。

检查是否存在并发操作

验证是否没有其他集群或节点池操作正在并发进行。GKE 通常一次只允许执行一项操作,这可能会阻止自动扩缩。

列出未处于 DONE 状态的正在进行的操作:

gcloud container operations list \
    --location=LOCATION \
    --filter='targetLink~"/clusters/CLUSTER_NAME" AND status!=DONE'

如果该命令返回任何操作,则可能正在进行集群升级、节点池创建或其他修改等操作。在完成此操作之前,自动扩缩事件可能会被阻止。

评估结果

  • 没有并发操作:如果 list 命令返回一个空列表,则表示集群自动扩缩器未受到任何操作的阻止。
  • 找到的并发操作次数

    • 解读:如果该命令列出了状态为 RUNNINGPENDING 的操作,则可能正在进行并发操作(例如集群升级或节点池修改),从而阻止自动扩缩。
    • 解决方法:等待正在进行的操作完成。您可以使用操作 ID 监控状态,方法如下:

      gcloud container operations wait OPERATION_ID --location LOCATION
      

      OPERATION_ID 替换为 list 命令输出中的 ID。阻塞操作完成后,集群自动扩缩器应恢复正常功能。

查看活跃迁移

如果您发现在优先级更高的节点可用时,工作负载仍停留在优先级较低的节点上,请验证是否已启用主动迁移。如果 ComputeClass 中的 activeMigration.optimizeRulePriority 字段设置为 false 或被省略,则当优先级更高的节点可用时,GKE 不会自动将工作负载移至这些节点。

  1. 如需检查 Pod 容忍度,请查看 spec.tolerations 字段。如果 Pod 具有与多个不同优先级的节点池上的污点相匹配的容忍度,则调度器可能会将其放置在先可用的较低优先级节点上。

    kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.tolerations[*]}{"\n"}'
    
  2. 如需检查是否已启用主动迁移,请检查 ComputeClass 清单中是否包含 spec.activeMigration.optimizeRulePriority 字段。

    kubectl get computeclass CUSTOM_COMPUTECLASS_NAME -o yaml
    

评估结果

  • 已启用主动迁移:如果 activeMigration.optimizeRulePriority 字段为 true,GKE 会尝试在优先级更高的节点可用时将工作负载迁移到这些节点。
  • 有效迁移已停用或无效

    • 解读:如果 activeMigration.optimizeRulePriority 字段为 false 或被省略,或者 Pod 容忍度过高,则在有更高优先级的节点可用时,工作负载仍会留在较低优先级的节点上。这种方法允许将工作负载调度到最先可用的低优先级节点上。
    • 解决方法:如果您希望工作负载移至优先级更高的节点,请执行以下操作之一:

      • 使用更具体的调度限制条件(例如 nodeAffinity)来优先选择优先级较高的节点池。
      • 修改 ComputeClass 清单以设置 activeMigration.optimizeRulePriority: true 并应用 YAML 文件:

        spec:
          activeMigration:
            optimizeRulePriority: true
        

获取支持

后续步骤