K8s节点NotReady故障深度排查指南:从config.yaml缺失到集群恢复全流程

当你兴冲冲地部署完Kubernetes集群,满心期待地输入kubectl get nodes命令,却看到一个刺眼的"NotReady"状态时,那种感觉就像精心准备的晚宴被泼了一盆冷水。别担心,这几乎是每个Kubernetes运维人员都会经历的"成人礼"。本文将带你深入剖析failed to load Kubelet config.yaml这一经典错误的来龙去脉,并提供一套系统性的排查修复方案。

1. 故障现象与初步诊断

NotReady状态的节点就像罢工的工人,拒绝接受任何工作指令。当你执行kubectl describe node <node-name>时,可能会看到类似这样的关键信息:

Conditions:
  Ready            False   ...   KubeletNotReady

这时候,我们需要像老中医一样"望闻问切"。首先登录问题节点,查看kubelet服务的实时日志:

journalctl -f -u kubelet.service --no-pager | grep -i error

典型的错误日志会包含这样的关键线索:

error: failed to load Kubelet config file /var/lib/kubelet/config.yaml, 
error: open /var/lib/kubelet/config.yaml: no such file or directory

这个报错直指问题核心——Kubelet找不到它的配置文件。但为什么会出现这种情况?让我们深入挖掘可能的原因。

2. 根因分析与排查路径

2.1 配置文件缺失的常见原因

根据多年处理Kubernetes集群故障的经验,config.yaml文件缺失通常源于以下几种情况:

  1. 初始化流程未完成

    • 忘记执行kubeadm init或执行失败
    • Token过期导致节点加入流程中断
    • 网络问题导致配置文件传输失败
  2. 文件系统问题

    • 误删除config.yaml文件
    • 磁盘空间不足导致文件写入失败
    • 文件权限配置错误
  3. 路径配置错误

    • Kubelet启动参数指定了错误的配置文件路径
    • 符号链接失效或指向错误位置

2.2 系统性排查步骤

为了彻底解决问题,建议按照以下顺序进行排查:

  1. 检查kubelet服务状态

    systemctl status kubelet -l
    

    重点关注Active和Loaded状态,以及是否有明显的错误提示。

  2. 验证配置文件路径

    ps -ef | grep kubelet | grep config
    

    确认kubelet是否使用了正确的--config参数。

  3. 检查文件系统状态

    ls -la /var/lib/kubelet/
    df -h /var/lib/kubelet
    

    确认目录存在且有足够的权限和空间。

3. 解决方案与实施步骤

3.1 重新生成配置文件

如果确认是初始化问题导致config.yaml缺失,最彻底的解决方案是重新生成配置文件:

# 在master节点上获取join命令
kubeadm token create --print-join-command

# 在问题节点上执行join命令
kubeadm join <control-plane-host>:<control-plane-port> \
    --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

执行完成后,检查配置文件是否生成:

ls -l /var/lib/kubelet/config.yaml

3.2 手动修复配置文件

在某些情况下,你可能需要手动创建或修复config.yaml文件。以下是典型的内容模板:

apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
serializeImagePulls: false
evictionHard:
  memory.available: "100Mi"
  nodefs.available: "10%"
  nodefs.inodesFree: "5%"
  imagefs.available: "15%"

注意:直接复制此模板可能不完全适合你的环境,建议从正常节点复制或使用kubeadm生成的配置。

3.3 权限与路径修复

如果文件存在但无法读取,可能是权限问题:

chmod 644 /var/lib/kubelet/config.yaml
chown root:root /var/lib/kubelet/config.yaml

对于路径错误的情况,可以检查kubelet服务配置:

systemctl edit kubelet

添加或修改以下参数:

[Service]
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"

4. 网络配置与完整性检查

解决了config.yaml问题后,节点可能仍然处于NotReady状态,这时需要检查CNI网络插件配置。特别是使用flannel时,确保以下文件存在且内容正确:

cat /run/flannel/subnet.env

典型内容应该类似:

FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

如果文件缺失,可以手动创建:

mkdir -p /etc/cni/net.d/
cat <<EOF > /etc/cni/net.d/10-flannel.conf
{
  "name": "cbr0",
  "type": "flannel",
  "delegate": {
    "isDefaultGateway": true
  }
}
EOF

5. 验证与测试

完成所有修复步骤后,按照以下流程验证集群状态:

  1. 重启kubelet服务

    systemctl daemon-reload
    systemctl restart kubelet
    
  2. 检查节点状态

    kubectl get nodes -w
    

    等待状态变为Ready,这可能需要1-2分钟。

  3. 部署测试应用

    kubectl create deployment nginx --image=nginx
    kubectl expose deployment nginx --port=80 --type=NodePort
    kubectl get svc nginx
    
  4. 访问测试: 使用NodePort或ClusterIP验证服务是否可达:

    curl <NodeIP>:<NodePort>
    

6. 预防措施与最佳实践

为了避免类似问题再次发生,建议采取以下预防措施:

  1. 初始化检查清单

    • 确认kubeadm init成功完成
    • 验证所有节点join命令执行成功
    • 检查kubelet服务状态
  2. 配置文件备份策略

    # 定期备份kubelet配置
    cp /var/lib/kubelet/config.yaml /backup/kubelet-config-$(date +%Y%m%d).yaml
    
  3. 监控与告警设置

    • 配置Prometheus监控节点Ready状态
    • 设置kubelet服务异常的告警规则
  4. 文档记录: 维护集群配置文档,记录所有自定义配置和变更历史。

7. 高级排查技巧

当基本方法无法解决问题时,可以尝试以下高级技巧:

  1. 增加kubelet日志级别

    systemctl edit kubelet
    

    添加:

    [Service]
    Environment="KUBELET_LOG_LEVEL=4"
    
  2. 使用crictl检查容器运行时

    crictl ps -a
    crictl logs <container-id>
    
  3. 检查证书有效期

    openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
    
  4. 网络连通性测试

    # 测试与API server的连接
    curl -k https://<API-SERVER-IP>:6443/version
    

记住,Kubernetes故障排查就像侦探破案,需要耐心地收集线索、分析证据。每次解决一个问题,都是对系统理解的一次深化。

更多推荐