关于 gke-node-notready
用于诊断状态为 `NotReady` 或 `Ready: Unknown` 的 GKE 节点并提出修复建议的只读技能。它收集节点、日志和指标证据,所有修复操作均由人工执行。
主要功能
- 01检查节点状况和事件
- 02分析 kubelet 与串行日志
- 03追查常见运行时和资源问题
- 04排查网络与准入问题
- 05提出修复建议但不更改集群
适用场景
- 01调查持续处于 NotReady 的 GKE 节点
- 02结合 kubelet 错误与节点压力分析
- 03为人工处理准备证据和修复方案
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ skills --skill gke-node-notready安装后在 Claude Code 中输入/gke-node-notready确认已加载。
附带文件references/attribution.md
详细介绍
GKE 节点 NotReady 故障排查技能
使用此技能系统地诊断一个或多个 GKE 节点报告 NotReady(或 Ready: Unknown)状态的原因,并提出安全的修复方案。NotReady 状态意味着节点的 kubelet 未能正确向控制平面报告,因此 Kubernetes 会停止在该节点上调度新 Pod,从而降低应用容量并可能导致停机。
此技能以非交互方式运行,并严格遵循只读诊断边界:先收集证据,再提出修复方案(供人工执行的 kubectl/gcloud 命令或 GitOps 清单变更)。绝不自动修改集群、排空、删除或重新创建节点。
重要
首先排除预期情况导致的
NotReady:正在新建、升级、修复、隔离或缩容的节点可能会暂时报告NotReady。只有在超过预期时限后仍持续出现时,才将其视为故障。
归属信息
必须阅读:执行任何 gcloud、REST API 或 MCP 命令前,必须阅读 Usage Attribution。对于直接在终端中执行的命令(绝不能在生成的脚本、Terraform 或用户代码中执行),请在 gcloud 前添加前缀 CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:gke-node-notready)",并将 agent-skills/1.0 (skill:gke-node-notready) 添加到 User-Agent 标头。
🔍 诊断工作流
步骤 0:发现上下文并确定时间范围
- 提取参数 — 从用户提示、当前有效的
SETTINGS.md或环境默认值(kubectl config current-context、gcloud config get-value project)中,以非交互方式获取project_id、cluster_name、cluster_location和node_name。 - 凭据与回退方案 — 尝试执行
gcloud container clusters get-credentials {cluster_name} --location {cluster_location} --project {project_id}。如果无法访问集群或命令失败(沙盒、试运行或离线环境),请提供供人工运行的准确诊断命令,并根据报告的症状继续分析。 - 时间范围 — 确定
{issue_time}(明确指定、相对时间或当前时间),并以其为中心设定 1 小时时间范围(start = issue_time - 30m、end = issue_time + 30m),用于所有日志和指标查询。
步骤 1:识别 NotReady 节点并收集初始状态
# List nodes and spot NotReady status, node IPs, and container-runtime version.
kubectl get nodes -o wide
# Inspect the affected node's Conditions and Events (the primary clues).
kubectl describe node "{node_name}"
也可以通过 Cloud Logging 查询(当 kubectl 访问受限或需要查看历史事件时优先使用)。请将其作为 Logs Explorer 深层链接打开——对查询进行 URL 编码,并附加项目和步骤 0 中的时间范围:
https://console.cloud.google.com/logs/query;query={URL_ENCODED_QUERY};timeRange={start}%2F{end}?project={project_id}
(将 / 编码为 %2F,或使用 ;duration=PT1H 表示滚动的一小时范围):
resource.type="k8s_node"
log_id("events")
resource.labels.node_name="{node_name}"
resource.labels.cluster_name="{cluster_name}"
resource.labels.location="{cluster_location}"
解读 Conditions 表:
Ready: False/Ready: Unknown,且原因是KubeletNotReady/NodeStatusUnknown(“Kubelet stopped posting node status”)→ kubelet 或运行时问题;继续执行步骤 2。MemoryPressure: True、DiskPressure: True、PIDPressure: True→ 资源耗尽;转到步骤 4b。NetworkUnavailable: True→ 网络/CNI 问题;转到步骤 4d。
步骤 2:扫描 kubelet 日志,查找错误特征
使用与步骤 1 相同的 logs/query;query={URL_ENCODED_QUERY};timeRange=...?project=... 模式,将这些 kubelet 日志作为 Logs Explorer 深层链接打开。
resource.type="k8s_node"
resource.labels.node_name="{node_name}"
resource.labels.cluster_name="{cluster_name}"
resource.labels.location="{cluster_location}"
log_id("kubelet")
severity>=WARNING
还要查看节点的串行控制台日志(log_id("serialconsole.googleapis.com/serial_port_1_output") 或 resource.type="gce_instance" 串行日志),查找与 kubelet 故障相关的内核 TaskHung、OOM-killer 或磁盘 I/O 错误。
第 3 步:将特征映射到根因(决策表)
| Kubelet / 事件特征 | 可能的根因 | 转到 |
|---|---|---|
runtime is down、Container runtime not ready、/run/containerd/containerd.sock 上的错误(connection refused / DeadlineExceeded) | 容器运行时(containerd)已停止或无响应 | 第 4a 步 |
Got sys oom event from cadvisor / 串行日志中的内核 OOM-killer | 系统(节点级)OOM 终止了关键进程 | 第 4b 步 |
PLEG is not healthy | PLEG 停滞,通常由节点过载(CPU/磁盘)导致 | 第 4c 步 |
containerd/kubelet 出现 TaskHung,磁盘延迟高 | 磁盘限流 / I/O 资源不足 | 第 4b 步 |
failed to ensure lease、leases.coordination.k8s.io ... namespace kube-node-lease ... terminating | kube-node-lease 终止 → NotReady 状态反复切换 | 第 4f 步 |
| Kubelet 无法访问 API 服务器,出现 TLS/拨号超时 | Kubelet ↔ 控制平面连接问题 | 第 4d 步 |
NetworkPluginNotReady、cni plugin not initialized、NetworkUnavailable | CNI 插件故障 | 第 4d 步 |
| 节点关键 DaemonSet Pod(CNI、kube-proxy、metadata)无法通过准入 | 准入 Webhook 干扰 | 第 4e 步 |
只有通用的 NodeNotReady,没有其他特征 | 原因不明 — 扩大排查范围至第 4d 步,然后升级处理 | 升级处理 |
第 4 步:分支排查
4a. 容器运行时(containerd)已停止
确认 kubelet 无法与 containerd 通信(参见上述套接字错误)。检查串行日志中是否有
containerd 重启/崩溃记录。修复措施(提出建议,不要执行):
重建/修复节点(运行 kubectl drain,然后让节点池重建节点;或运行
gcloud container clusters upgrade/节点自动修复);如果多个节点都反复出现此问题,
则怀疑是节点映像或自定义 DaemonSet 干扰了 containerd。
4b. 资源压力与 OOM
# Node allocatable vs. usage.
kubectl describe node "{node_name}" | sed -n '/Allocated resources/,/Events/p'
要检查的 Cloud Monitoring 指标(只读):kubernetes.io/node/memory/used_bytes、
kubernetes.io/node/cpu/core_usage_time、kubernetes.io/node/ephemeral_storage/used_bytes。
- DiskPressure / 磁盘限流:启动磁盘已满或 PD 速度较慢 → 增大磁盘 容量 / 使用速度更快的 PD 类型;减少映像/日志的频繁变更。
- 系统 OOM:节点内存耗尽 → 设置/提高 Pod 内存
requests/limits, 减少超额分配,或使用更大规格的机器。区分系统 OOM (影响整个节点,会终止 kubelet/运行时)与 cgroup OOM(仅影响单个容器)。 - PIDPressure:进程过多 → 限制 Pod 的 PID 数量 / 降低工作负载密度。
4c. PLEG 不健康
PLEG is not healthy 几乎总是意味着节点过载(CPU 饱和、
磁盘延迟,或每个节点上的 Pod/容器过多),导致运行时无法及时重新列出。
将其与第 4b 步中的指标进行关联。**修复措施:**降低节点密度,增加
CPU/磁盘余量,或分散工作负载。
4d. 网络
# Are node-critical networking Pods healthy on this node?
kubectl get pods -n kube-system -o wide --field-selector spec.nodeName={node_name}
- Kubelet ↔ 控制平面:连接 API 服务器时出现拨号/TLS 超时 → 检查 防火墙规则、Private Google Access、授权网络以及路由/NAT 变更。
- CNI 故障(
NetworkPluginNotReady):节点上的 CNI DaemonSet (netd/calico/dataplane)未运行 → 检查这些 Pod 的日志/事件。
4e. 准入 Webhook 干扰
配置错误或发生故障且作用范围较广的验证型或变更型 Webhook,可能会 阻止节点关键系统 Pod 通过准入,导致节点保持 NotReady 状态。
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
查找拦截 kube-system / 节点关键对象且设置了
failurePolicy: Fail 的 Webhook。**修复措施(提出建议):**将 Webhook 的作用范围排除
kube-system/节点关键命名空间,或设置适当的 namespaceSelector。
4f. kube-node-lease 终止状态反复
如果节点反复变为 NotReady,并出现 leases.coordination.k8s.io ... namespace kube-node-lease ... is being terminated,则 kube-node-lease 命名空间已被删除或正在终止。修复建议: 不要删除
kube-node-lease 命名空间;如果它正在终止,请确定阻止其终止的 finalizer/操作者,并恢复该命名空间。
第 5 步:修复边界与升级处理
- 提供根本原因 + 证据(观察到的确切条件、事件、日志行 或指标)。提供相关条目的 Cloud Logging 深层链接(以及第 4b 步指标对应的 Cloud Monitoring 链接), 使用第 1-2 步中的深层链接格式,方便人工直接打开证据。
- 将修复方案作为命令或 GitOps 清单变更提出,供人工应用 — 绝不要自动应用修复、排空节点或重新创建节点。 以下情况需要升级处理(此时不要再提出自助诊断):
出现以下任一情况时,请升级处理:
- 相关日志不可用 — 已被日志过滤器排除,或超出
日志存储桶的保留期限(
_Default存储桶默认保留 30 天,因此超过该期限的事故日志会被永久删除);或 - kubelet/事件特征不在第 3 步的表格中,且分支调查后仍无法确定根本原因。
在这些情况下,请完成以下三项:
- 明确说明限制(例如:“该日期的 kubelet 日志已超出 30 天的
_Default保留期限窗口,现已永久删除”)。 - 总结已收集的调查结果(节点条件、事件、指标,以及
_Required存储桶中仍可用的任何 Admin Activity 审计日志;默认保留 400 天)。 - 根据这些调查结果转交 GKE 支持团队/升级给工程团队处理。 不要 继续提出更多自助调查,也不要在缺少证据时编造诊断结论。
参考资料
此技能源自 Google Cloud 公开文档:
- 排查状态为 NotReady 的节点
— 节点条件,以及 kubelet / PLEG / system-OOM / containerd /
kube-node-lease/ CNI / admission-webhook 特征及相应修复方法。 - 排查节点注册问题 — 适用于始终无法完成注册的节点的 Node Registration Checker。
- 查看 GKE 日志
和 Cloud Logging 路由概览
— 日志查询(
resource.type="k8s_node"、log_id("kubelet"))以及日志存储桶 的保留期限(_Default为 30 天,_Required为 400 天)。 - Logs Explorer 界面
— 通过 URL 构建和分享查询(上文使用的
logs/query;query=...深层链接 格式)。