一、问题背景与现象描述

在基于Docker和Kubernetes的容器化部署中,节点(Node)突然变成NotReady状态是运维人员最头疼的问题之一。上周我们的生产环境就遇到这样的情况:凌晨3点收到告警,一个工作节点突然失联,导致运行在该节点上的支付服务Pod全部失效。本文将通过真实案例,带您逐步排查和修复这类问题。


二、诊断节点不可用的核心方法

1. 检查节点基础状态

(技术栈:Kubernetes)

# 查看所有节点状态(注意观察READY列和STATUS列)
kubectl get nodes -o wide

# 输出示例:
NAME       STATUS     ROLES    AGE   VERSION   INTERNAL-IP
node-01    NotReady   <none>   35d   v1.24.3   172.18.0.101
node-02    Ready      <none>   35d   v1.24.3   172.18.0.102

# 查看具体节点的详细事件(重点关注Events部分)
kubectl describe node node-01

当发现Conditions中的Ready状态为False时,通常伴随以下关键信息:

  • Kubelet stopped posting node status(kubelet心跳丢失)
  • NetworkUnavailable(网络插件异常)

2. 分析系统资源瓶颈

(技术栈:Linux)

# 通过SSH登录问题节点后执行
top -c  # 查看CPU和内存使用排行
df -h   # 检查磁盘空间(特别是/var/lib/docker目录)
journalctl -u kubelet --since "10 minutes ago"  # 查看kubelet日志

曾遇到因容器日志未配置轮转,导致/var目录被占满的案例:

# 紧急清理脚本示例(需谨慎操作)
find /var/lib/docker/containers -name "*.log" -size +100M -exec truncate -s 0 {} \;

三、典型问题场景与解决方案

场景1:资源不足导致节点被驱逐

现象:节点状态周期性波动,kubelet日志出现Insufficient memory警告

# 解决方案:调整kubelet资源配置(/etc/kubernetes/kubelet.conf)
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
  memory.available: "500Mi"  # 将默认1Gi阈值调整为500Mi
  nodefs.available: "10%"
systemReserved:
  memory: "1Gi"  # 为系统进程保留内存

场景2:CNI网络插件异常

现象:Pod间网络不通,节点状态显示NetworkUnavailable

# 检查Calico网络状态(技术栈:Calico v3.24)
kubectl get pods -n kube-system -l k8s-app=calico-node
calicoctl node status  # 查看BGP连接状态

# 常见修复操作:
systemctl restart calico-node
calicoctl delete felixconfiguration default  # 重置网络配置

场景3:kubelet配置错误

案例:升级Kubernetes版本后节点失联

# 查看kubelet启动参数(关键注意--pod-infra-container-image配置)
ps aux | grep kubelet
# 正确示例:
/usr/bin/kubelet --container-runtime=docker \
                 --pod-infra-container-image=k8s.gcr.io/pause:3.7
                 
# 修复步骤:
sudo sed -i 's/pause:3.6/pause:3.7/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sudo systemctl daemon-reload
sudo systemctl restart kubelet

四、关联技术深度解析

1. 节点自动修复机制

(技术栈:Cluster API)

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineHealthCheck
metadata:
  name: worker-node-healthcheck
spec:
  clusterName: my-cluster
  unhealthyConditions:
  - type: Ready
    status: "False"
    timeout: 5m
  - type: Ready
    status: "Unknown"
    timeout: 5m
  maxUnhealthy: 40%

2. 高级监控方案

(技术栈:Prometheus + Grafana)

# 部署节点监控Exporter
kubectl apply -f https://raw.githubusercontent.com/prometheus/node_exporter/master/examples/kubernetes.yml

# 示例Grafana监控面板配置
- expr: sum(kube_node_status_condition{condition="Ready", status="true"} == 0)
  record: cluster:node_ready:count

五、适用环境分析

场景类型 推荐方案 恢复时间目标
开发测试环境 自动节点替换 <30分钟
生产关键业务 手动干预+蓝绿部署 <5分钟
边缘计算节点 状态缓存+本地恢复机制 <1小时

六、技术方案优缺点对比

Kubernetes节点管理

优势

  • 声明式API简化运维操作
  • 自动健康检查机制(需配合Cloud Provider)
  • 细粒度的资源配额管理

局限

  • 网络问题定位依赖CNI插件能力
  • 裸机环境需要额外配置自愈机制
  • 存储卷迁移存在跨节点限制

七、关键注意事项

  1. 内核参数调优:特别是vm.max_map_countnet.ipv4.ip_forward的配置
  2. 证书有效期管理:kubelet客户端证书过期会导致节点突然离线
  3. 版本兼容矩阵:确保Docker(20.10+)与Kubernetes(1.24+)版本匹配
  4. 灾备策略:至少保留30%的冗余计算资源

八、实战经验总结

通过本文的六个核心场景分析,我们可以总结出节点故障处理的"三板斧":

  1. 快速定位:善用kubectl describe node和日志三剑客(grep/awk/sed)
  2. 精准打击:根据故障类型选择对应修复策略(网络重启/资源清理/配置更新)
  3. 防御加固:建立节点健康度评分机制,提前识别风险节点