一、问题背景与现象描述
在基于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插件能力
- 裸机环境需要额外配置自愈机制
- 存储卷迁移存在跨节点限制
七、关键注意事项
- 内核参数调优:特别是
vm.max_map_count
和net.ipv4.ip_forward
的配置 - 证书有效期管理:kubelet客户端证书过期会导致节点突然离线
- 版本兼容矩阵:确保Docker(20.10+)与Kubernetes(1.24+)版本匹配
- 灾备策略:至少保留30%的冗余计算资源
八、实战经验总结
通过本文的六个核心场景分析,我们可以总结出节点故障处理的"三板斧":
- 快速定位:善用
kubectl describe node
和日志三剑客(grep/awk/sed) - 精准打击:根据故障类型选择对应修复策略(网络重启/资源清理/配置更新)
- 防御加固:建立节点健康度评分机制,提前识别风险节点