mcpField
G
gke-workload-scaling-troubleshooting

gke-workload-scaling-troubleshooting

github.com/google云与 DevOps21.6k1.6k 次安装今天更新
代码仓库

关于 gke-workload-scaling-troubleshooting

用于排查 GKE HorizontalPodAutoscaler 故障和扩缩容异常的技能。它按症状引导运维人员检查问题,并先进行只读诊断,再提出可审查的配置修正方案。

主要功能

  1. 01按事件和状态分类 HPA 症状
  2. 02检查目标引用和资源请求
  3. 03诊断自定义及外部指标管道
  4. 04排查扩容或缩容异常
  5. 05先只读诊断再提出修复方案

适用场景

  1. 01查明 HPA 指标缺失的原因
  2. 02诊断工作负载未按预期扩缩容
  3. 03排查自定义指标适配器或数据问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/skills --skill gke-workload-scaling-troubleshooting

安装后在 Claude Code 中输入/gke-workload-scaling-troubleshooting确认已加载。

附带文件references/attribution.md

详细介绍

GKE 工作负载扩缩容故障排查技能

使用此技能系统地诊断并解决 GKE 上的 HorizontalPodAutoscaler (HPA) 故障,包括指标显示为 <unknown>、FailedGet* 事件、 缺少资源请求、自定义指标/外部指标流水线故障、HPA 拒绝扩容或缩容、扩缩至/从零副本的问题,以及大型集群上的 HPA 响应迟缓。此技能以非交互方式运行,并会在提出清单或配置修正建议前,严格执行只读诊断流程。

如需配置 HPA/VPA 对象并了解扩缩容最佳实践,请改用 gke-workload-scaling 技能。此技能专注于故障诊断。

归属信息

必须阅读:执行任何 gcloud、REST API 或 MCP 命令前, 必须阅读 使用归属信息。对于直接在终端中执行的命令(绝不在生成的脚本、Terraform 或用户代码中),请在 gcloud 前加上 CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:gke-workload-scaling-troubleshooting)" 并在 User-Agent 标头中追加 agent-skills/1.0 (skill:gke-workload-scaling-troubleshooting)。

🔍 诊断与解决工作流

步骤 0:非交互式上下文发现与试运行回退
  1. 提取参数:从用户提示、当前的 SETTINGS.md 或环境默认值中,以非交互方式提取所需上下文(project_id、 cluster_name、cluster_location、hpa_name、workload_name、 workload_namespace):

    • 若未提供 workload_namespace,则默认为 default。
    • 从当前环境推断缺失的集群参数(kubectl config current-context 或 gcloud config get-value project)。
  2. 集群凭据与回退模式:

    • 尝试获取凭据:gcloud container clusters get-credentials {cluster_name} --location {cluster_location} --project {project_id}。
    • 回退/试运行模式:如果集群无法访问、集群不存在,或实时命令执行失败(例如在沙盒评估、试运行模式或离线分析中):
      • 限制重试次数,避免资源耗尽和上下文溢出。
      • 立即提供供操作人员执行的准确 kubectl/gcloud 诊断命令。
      • 根据已报告的症状综合分析根本原因,并输出建议的 GitOps 修正方案。

步骤 1:检查 HPA 并判定症状

每次排查都从 kubectl describe hpa 开始,然后转到匹配的分支。三个关键部分是 Metrics(值为 <unknown> 表示 HPA 尚未获取指标,或指标管道已中断)、Conditions(AbleToScale、ScalingActive、ScalingLimited——状态为 False 表示存在故障)以及 Events(例如 FailedGetScale 或 FailedGetResourceMetric 等具体原因)。

诊断命令:

kubectl describe hpa {hpa_name} -n {workload_namespace}
kubectl get hpa {hpa_name} -n {workload_namespace} -o yaml

如需查看历史事件,请查询 Cloud Logging(实时 Events 列表滚动更新后,HPA 事件仍会保留):

resource.type="k8s_cluster"
resource.labels.cluster_name="{cluster_name}"
resource.labels.location="{cluster_location}"
logName="projects/{project_id}/logs/events"
jsonPayload.involvedObject.kind="HorizontalPodAutoscaler"

根据迹象选择分支:

  • FailedGetScale、FailedComputeMetricsReplicas、Error 400 ... label is not allowed,或多个 HPA 竞争导致副本数波动 → 分支 A (配置错误)。
  • FailedGetResourceMetric、unable to fetch pod metrics,或 multiple services selecting the same target → 分支 B(工作负载和服务错误)。
  • 自定义/外部指标为 <unknown>、FailedGetExternalMetric / FailedGetCustomMetric,或 no known available metric versions found → 分支 C(指标 API 和数据可用性)。
  • 所有 Conditions 均为 True/没有错误,但工作负载无法扩容或缩容 → 分支 D(运行正常但扩缩容结果异常)。
  • 工作负载配置了 minReplicas: 0,但无法扩缩至零或从零扩缩 → 分支 E(扩缩至零/从零扩缩)。
  • HPA 配置正确,但在 HPA 对象较多的集群上反应缓慢 → 分支 F(大型集群上的重新计算缓慢)。

步骤 2:解决问题——转到匹配的分支

根据你在步骤 1 中判定的迹象,跳转到以下互斥分支之一(A–F)。这些分支是备选方案——不要按顺序逐一执行。应用分支中的修复后,前往步骤 3,将其作为可审查的 GitOps 变更提交。

分支 A:HorizontalPodAutoscaler 配置错误
  • FailedGetScale — unable to get the target's current scale: ... "TARGET" not found:scaleTargetRef 未能解析到现有的可扩缩工作负载。

    • 确认 scaleTargetRef 中的 name、kind 和 apiVersion 与目标工作负载的元数据完全匹配。
    • 确认目标工作负载与 HPA 位于同一命名空间(缺少 -n 会导致对象被放入 default,从而造成不匹配)。
    • 目标必须是可扩缩的类型(Deployment、StatefulSet、ReplicaSet)——无法对 DaemonSet 执行自动扩缩容。
  • FailedComputeMetricsReplicas — invalid metrics (1 invalid out of 1): 指标 type 与 target 不匹配。

    • 如果 type: Utilization,目标必须为 averageUtilization。
    • 如果 type: AverageValue,目标必须为 averageValue。
  • unable to fetch metrics from external metrics API: googleapi: Error 400: Metric label: 'LABEL' is not allowed:metric.selector.matchLabels 中存在无效的键。

    • 移除或更正不允许的标签;请在 Cloud Monitoring 指标文档中查找可用于筛选的有效标签。
  • 副本数波动/来自不同 HPA 的 SuccessfulRescale 事件相互矛盾:多个 HPA 通过 spec.scaleTargetRef 指向同一工作负载,并相互竞争。对此没有专门的 Condition——请使用 kubectl get hpa -n {workload_namespace} -o yaml 确认,并查找重复的 scaleTargetRef 值。

    • 将所有指标整合到一个 HPA 对象中(它会采用其 spec.metrics 中的最高值),并删除重复对象。

分支 B:工作负载和服务错误
  • ScalingActive: False,原因是 FailedGetResourceMetric,消息为 unable to compute the replica count(或持续出现 unable to fetch pod metrics):HPA 会根据容器资源请求计算利用率百分比,但 Pod 中至少有一个容器缺少已缩放资源(cpu 或 memory)对应的 resources.requests 条目。

    • 为 Pod 规格中的每个容器(包括 sidecar)添加已缩放资源对应的 resources.requests。metrics server 启动后短暂出现 unable to fetch pod metrics 属于正常情况,问题会自动恢复。
  • multiple services selecting the same target of HPA_NAME: SERVICE: 基于流量的自动缩放要求 Service 与工作负载之间是一对一关系,但多个 Service 的 selector 都匹配该工作负载的 Pod。

    • 让目标 Service 的 selector 保持唯一(为工作负载和该 Service 添加不同的标签),或收紧其他 Service 的 selector,使其不再匹配该工作负载的 Pod。

分支 C:指标 API 与数据可用性(自定义/外部指标)

自定义/外部指标管道为:HPA 控制器 → Kubernetes 指标 API 服务器 → 指标适配器(例如 custom-metrics-stackdriver-adapter)→ 指标 源(Cloud Monitoring/Prometheus)。症状包括指标值为 <unknown>,或 出现 FailedGetExternalMetric/FailedGetCustomMetric 事件。

  1. 适配器是否已注册且可用?

    kubectl get apiservice | grep -E 'NAME|metrics.k8s.io'
    

    预期 v1beta1.custom.metrics.k8s.io 和/或 v1beta1.external.metrics.k8s.io 的 AVAILABLE: True。如果为 False/缺失, 则适配器已崩溃或配置错误——检查其在 custom-metrics 或 kube-system 命名空间中的 Pod 日志,查看是否有权限、连接或 “metric not found”错误。

  2. 直接查询指标 API(绕过 HPA,测试整个 管道;jq 可选):

    kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/{workload_namespace}/{metric_name}" | jq .
    kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/{workload_namespace}/pods/*/{metric_name}" | jq .
    
  3. 解读结果:

    • 有效 JSON 且包含值 → 管道正常;问题出在 HPA 清单中(指标名称拼写错误或 matchLabels 不正确)。
    • Error from server (Service Unavailable) → 网络隔离阻止 控制平面连接适配器。将适配器的 targetPort 添加到控制平面防火墙规则中(除了 现有的 tcp:443 和 tcp:10250)。使用 gcloud compute firewall-rules list --filter="name~gke-{cluster_name}-[0-9a-z]*-master" 查找规则, 并确认没有 NetworkPolicy 阻止流入适配器 Pod 的流量。
    • 空列表 [] → 适配器正在运行,但无法检索指标。 检查适配器 Pod 日志,并在 Metrics Explorer 中确认源中确实存在该指标,且名称和标签符合预期。
  • unable to fetch metrics from custom metrics API: no known available metric versions found:通信中断(升级/修复期间控制平面暂时不可用,或适配器 Pod 不健康或未注册)——不是指标源的问题。检查控制平面 健康状态/通知,确认适配器 Pod 处于 Running 状态且没有重启 (kubectl get pods -n custom-metrics,kube-system -o wide),并再次确认 APIServices 的 AVAILABLE: True。这种情况通常是暂时的。

  • googleapi: Error 400: The supplied filter ... will not return any time series:查询有效,但没有匹配到数据(这与值为 0 不同)——应用在该时间窗口内没有写入指标。确认指标名称/标签与应用发出的内容一致,确认应用具有相应权限且处于活动状态,并检查应用日志中是否有指标发出错误。


分支 D:状态正常,但扩缩容行为与预期不符

HPA 的条件为 True 且没有显示错误,但扩缩容未按预期进行。

  • 无法扩容——按顺序检查:

    • 副本数限制:currentReplicas 已达到 minReplicas / maxReplicas(查看 ScalingLimited 条件);请调整上下限。
    • 容差窗口:当当前值与目标值的比率处于 0.9–1.1 之间时,Kubernetes 会忽略变化(默认容差为 10%)。例如:目标 CPU 使用率为 85%,当前为 93% → 比率约为 1.094 < 1.1, 因此不会扩容。请等待指标超出此范围,或配置其他容差。
    • 未就绪的 Pod:Pending / 未处于 Ready 状态的 Pod 不会纳入计算——请解决底层调度或探针问题。
    • 同步延迟:超过阈值到执行操作之间有 15–30s 的延迟属于正常情况。
  • 无法缩容——按顺序检查:

    • 多个指标:HPA 会采用要求副本数最多的指标,因此只有在所有指标都一致时才会缩容。
    • 指标不可用会阻止缩容:如果任何指标变为 <unknown>,HPA 会出于谨慎拒绝缩容。常见情况是基于速率的 自定义指标在流量为零时停止上报。优先使用计量值指标(例如 num_undelivered_messages),或让来源在无活动时 上报 0,而不是不发送数据。
    • 缩容稳定窗口:默认的 behavior.scaleDown.stabilizationWindowSeconds 为 300s(5 分钟)。 如果必须加快缩容,请缩短此窗口。

分支 E:缩容到零 / 从零扩容(GKE 1.37+)

GKE 1.37 或更高版本支持使用 HPA 将工作负载缩容到零个副本,并从零个副本扩容(minReplicas: 0)。

  • 无法缩容到零:

    • 必须设置 minReplicas: 0。
    • HPA 不能仅使用 Resource(CPU/内存)指标缩容到零——请至少配置一个 External 或 Object 指标。
    • 使用多个指标时,所有指标的计算结果都必须为零。
    • 在需求为零时,GKE 会等待 5 分钟的缩容稳定窗口,然后才会从 1 个副本缩至 0 个。
    • 任何显示为 <unknown> 的指标都会暂停缩容(参见分支 D)。
  • 无法从零扩容:运行 kubectl describe hpa {hpa_name} 并检查:

    • 指标:值必须 > 0 且不能为 <unknown>;如果缺失,请确认外部来源(例如 Pub/Sub)正在发布数据,且 Cloud Monitoring 正在接收数据。
    • 条件:健康的空闲状态会显示 AbleToScale: True、 ScalingActive: True、ScaledToZero: True。如果 ScalingActive: False 的原因是 ScalingDisabledExternalScaleToZero 或 ScalingDisabledReplicaCountZero,则表示工作负载已被手动缩容到零(例如使用 kubectl scale),这会暂停自动扩缩容。请将 Deployment 扩容回 --replicas=1,以恢复自动扩缩容。
    • 节点预配的冷启动延迟可能会增加等待时间;Capacity Buffers 可让备用容量随时就绪。

分支 F:大规模集群中的 HPA 重新计算缓慢

如果 HPA 配置正确,但响应缓慢,集群中的 HPA 对象数量可能超过标准控制器在 15 秒重新计算周期内能够处理的数量。

  • 标准控制器:在 15 秒内处理最多 300 个 HPA 对象(GKE 1.22+)。
  • Performance HPA 配置文件:在 15 秒内处理最多 1,000 个 HPA 对象(GKE 1.31+)或 5,000 个 HPA 对象(GKE 1.33+,符合条件的集群默认启用)。

在符合条件的集群上启用此功能(这会修改集群——请提供命令供运维人员执行,不要自行执行):

gcloud container clusters update {cluster_name} \
    --location {cluster_location} --project {project_id} \
    --hpa-profile=performance

每个 HPA 使用多个指标进行扩缩,以及速度较慢(>~50 ms)的自定义指标适配器,也会延长重新计算周期。要了解扩缩决策,请启用 HPA 事件日志,并查看结构化的 HPA 决策日志。


第 3 步:提出 GitOps 修正方案

遵守只读诊断边界:不要应用实时变更。这包括集群/清单变更(kubectl edit、kubectl patch、kubectl apply、kubectl scale、kubectl delete)以及 Google Cloud / gcloud 变更(集群更新,例如 --hpa-profile,以及 gcloud compute firewall-rules 更新)。请改为将修正后的 HorizontalPodAutoscaler、PodSpec (resources.requests)、Service 选择器、工作负载自动扩缩配置或 gcloud 命令作为可供审核的补丁/命令提供,以便通过用户的 GitOps 流水线(例如 Config Sync、Argo CD 或 Flux)应用,或由获授权的运维人员执行。

参考资料

评论

支持 Markdown