一、Kubernetes节点故障的常见表现

当集群中的节点出现问题时,通常会有一些明显的症状。就像人生病会发烧咳嗽一样,节点故障也有自己的"临床表现"。最常见的情况是节点突然变成NotReady状态,这时候通过kubectl get nodes命令查看,你会看到类似这样的输出:

# 查看节点状态(技术栈:Kubernetes)
kubectl get nodes
# 输出示例:
# NAME       STATUS     ROLES    AGE   VERSION
# node-01    Ready      <none>   15d   v1.22.3
# node-02    NotReady   <none>   15d   v1.22.3

另一个典型表现是Pod被频繁驱逐或无法调度。你可能发现某些Pod一直处于Pending状态,或者看到事件日志中有NodeNotReady的警告信息:

# 查看Pod调度事件(技术栈:Kubernetes)
kubectl get events --field-selector=type=Warning
# 输出示例:
# LAST SEEN   TYPE      REASON      OBJECT               MESSAGE
# 5m          Warning   NodeNotReady node/node-02        Node node-02 status is now: NodeNotReady

二、故障诊断的实用方法

1. 基础检查三板斧

遇到节点故障时,我建议先用这三个基础命令快速定位问题:

# 1. 检查节点详情(技术栈:Kubernetes)
kubectl describe node <故障节点名称>

# 2. 检查系统服务状态(技术栈:Linux)
ssh <节点IP> "systemctl status kubelet docker"

# 3. 查看关键日志(技术栈:Linux)
ssh <节点IP> "journalctl -u kubelet --since '1 hour ago'"

2. 深入诊断工具

对于更复杂的情况,我们需要更专业的工具。比如使用kubelet的调试接口:

# 获取kubelet健康状态(技术栈:Kubernetes)
curl -sSk "https://<节点IP>:10250/healthz"
# 正常应该返回:ok

# 检查节点资源使用情况(技术栈:Kubernetes)
kubectl top node

三、典型故障场景与解决方案

1. 资源耗尽导致故障

这是最常见的故障类型。当节点内存或CPU耗尽时,kubelet会开始驱逐Pod。我们可以通过以下方式确认:

# 检查节点资源分配情况(技术栈:Kubernetes)
kubectl describe node | grep -A 10 "Allocated resources"
# 输出示例:
# Allocated resources:
#   (Total limits may be over 100 percent, i.e., overcommitted.)
#   Resource           Requests     Limits
#   --------           --------     ------
#   cpu                3820m (48%)  6300m (78%)
#   memory             6Gi (23%)    10Gi (39%)

解决方案包括:

  1. 增加节点资源
  2. 优化Pod资源请求和限制
  3. 配置适当的驱逐策略

2. 网络插件问题

Calico、Flannel等网络插件异常会导致节点间通信中断。诊断方法:

# 检查网络Pod状态(技术栈:Kubernetes)
kubectl get pods -n kube-system | grep -E 'flannel|calico|coredns'

# 测试节点间网络连通性(技术栈:Linux)
kubectl get pods -o wide  # 获取Pod分布
ssh <节点IP> "ping <其他节点PodIP>"

常见解决方法:

  1. 重启网络插件Pod
  2. 检查网络插件配置
  3. 验证防火墙规则

四、高级故障处理技巧

1. 节点隔离与恢复

当节点出现严重故障时,可能需要隔离:

# 隔离节点(技术栈:Kubernetes)
kubectl cordon <节点名称>

# 驱逐所有Pod(技术栈:Kubernetes)
kubectl drain <节点名称> --ignore-daemonsets --delete-emptydir-data

# 恢复节点(技术栈:Kubernetes)
kubectl uncordon <节点名称>

2. 使用临时调试容器

Kubernetes的临时容器功能非常适合诊断:

# 创建调试容器(技术栈:Kubernetes)
kubectl debug -it <故障Pod> --image=busybox --target=<容器名称>
# 在容器内可以检查网络、文件系统等

五、预防措施与最佳实践

1. 监控告警配置

建议配置以下监控指标:

  • 节点CPU/Memory/Disk使用率
  • kubelet心跳状态
  • 网络延迟和丢包率

使用Prometheus的示例规则:

# Prometheus告警规则示例(技术栈:Prometheus)
groups:
- name: node-alerts
  rules:
  - alert: NodeNotReady
    expr: kube_node_status_condition{condition="Ready",status="false"} == 1
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Node {{ $labels.node }} is not ready"

2. 自动化修复方案

对于常见故障,可以编写自动化修复脚本:

#!/bin/bash
# 节点自动修复脚本(技术栈:Shell + Kubernetes)
NODE=$1

# 1. 检查节点状态
STATUS=$(kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}')

if [ "$STATUS" == "False" ]; then
    # 2. 尝试重启kubelet
    ssh $NODE "systemctl restart kubelet"
    
    # 3. 等待5分钟
    sleep 300
    
    # 4. 再次检查状态
    STATUS=$(kubectl get node $NODE -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}')
    
    if [ "$STATUS" == "False" ]; then
        # 5. 如果仍然不正常,隔离节点并通知
        kubectl cordon $NODE
        send_alert "Node $NODE is down and couldn't be automatically recovered"
    fi
fi

六、总结与经验分享

在实际运维中,Kubernetes节点故障处理有几个关键点需要注意:

  1. 快速诊断比盲目重启更重要。先收集足够的信息,再决定处理方案。
  2. 建立完善的监控系统,最好能在问题影响业务前发现异常。
  3. 对于生产环境,建议至少保留20%的闲置资源缓冲。
  4. 定期演练故障恢复流程,确保团队熟悉应急操作。
  5. 文档化所有处理过程,形成知识库供团队参考。

记住,节点故障并不可怕,可怕的是没有准备。通过合理的预防措施和科学的处理方法,我们完全可以把故障影响降到最低。