关于 gke-workload-scaling-troubleshooting
用于排查 GKE HorizontalPodAutoscaler 故障和扩缩容异常的技能。它按症状引导运维人员检查问题,并先进行只读诊断,再提出可审查的配置修正方案。
主要功能
- 01按事件和状态分类 HPA 症状
- 02检查目标引用和资源请求
- 03诊断自定义及外部指标管道
- 04排查扩容或缩容异常
- 05先只读诊断再提出修复方案
适用场景
- 01查明 HPA 指标缺失的原因
- 02诊断工作负载未按预期扩缩容
- 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:非交互式上下文发现与试运行回退
-
提取参数:从用户提示、当前的
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)。
- 若未提供
-
集群凭据与回退模式:
- 尝试获取凭据:
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中的最高值),并删除重复对象。
- 将所有指标整合到一个 HPA 对象中(它会采用其
分支 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属于正常情况,问题会自动恢复。
- 为 Pod 规格中的每个容器(包括 sidecar)添加已缩放资源对应的
-
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 事件。
-
适配器是否已注册且可用?
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”错误。 -
直接查询指标 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 . -
解读结果:
- 有效 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 中确认源中确实存在该指标,且名称和标签符合预期。
- 有效 JSON 且包含值 → 管道正常;问题出在 HPA
清单中(指标名称拼写错误或
-
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)应用,或由获授权的运维人员执行。