4. 证书轮换失败典型场景1:kubelet证书过期导致Node NotReady,调度器无法调度Pod到该节点

4.1 场景概述

在Kubernetes集群中,kubelet使用由集群CA签发的TLS证书与kube-apiserver进行双向认证。当kubelet证书过期且自动轮换机制失效时,kubelet将无法向控制平面发送心跳(NodeLease),导致节点状态在node-monitor-grace-period(默认40秒)后变为NotReady。调度器随后将该节点标记为不可调度,已运行的Pod被驱逐,新Pod无法调度至此节点。

⚠️ 关键影响: 证书过期导致的NotReady与网络分区不同——kubelet进程仍在运行,但所有与APIServer的通信均被TLS拒绝,节点上的Pod状态无法同步,导致调度器做出错误决策。

4.2 故障链路与根因分析

下图展示了从证书过期到调度异常的完整链路:

kubelet证书过期导致Node NotReady故障链路 kubelet证书过期 → Node NotReady → 调度异常 故障链路 kubelet证书过期 TLS握手失败 NodeLease更新失败 心跳中断 Node状态 NotReady node-monitor-grace-period 调度器标记不可调度 Taint: node.kubernetes.io/unreachable 已有Pod被驱逐 tolerationSeconds耗尽 新Pod调度失败 Pending状态 🔍 根因分析 • 直接原因:kubelet证书过期,TLS双向认证失败,NodeLease心跳无法上报 • 触发条件:证书轮换机制失效(证书轮换配置错误、kubelet重启后未触发轮换、CA证书不匹配) • 默认容忍时间:node-monitor-grace-period(40s)+ pod-eviction-timeout(5m) • 调度影响:节点被添加 Taint node.kubernetes.io/unreachable:NoExecute,调度器自动过滤

4.3 关键时间参数与影响

参数 默认值 作用 证书过期后的影响
--node-monitor-grace-period 40s 节点控制器等待心跳的最大时间 超过40秒未收到心跳,节点标记为 NotReady
--node-status-update-frequency 10s kubelet上报节点状态的频率 证书过期后,状态更新立即失败
--pod-eviction-timeout 5m 节点NotReady后驱逐Pod的等待时间 5分钟后,节点上的Pod被标记为Terminating
tolerationSeconds 300s Pod容忍节点不可达的时间 超过容忍时间后,Pod被驱逐

4.4 排查步骤与命令

📋 排查流程: 按照以下步骤快速定位证书过期导致的NotReady问题。
  1. 检查节点状态:
    kubectl get nodes
    # 输出示例:
    # NAME     STATUS     ROLES    AGE   VERSION
    # node-1   NotReady   <none>   30d   v1.28.5
  2. 查看节点详情,确认Taint:
    kubectl describe node node-1 | grep -A5 Taints
    # 输出示例:
    # Taints:             node.kubernetes.io/unreachable:NoExecute
    #                     node.kubernetes.io/unreachable:NoSchedule
  3. 检查kubelet日志,定位证书错误:
    # SSH登录到节点后执行
    journalctl -u kubelet -n 100 --no-pager | grep -i "certificate\|tls\|x509"
    # 典型错误:
    # "x509: certificate has expired or is not yet valid"
    # "failed to get recent kubelet config: failed to get kubelet config from api server"
    # "TLS handshake error from x.x.x.x: remote error: tls: bad certificate"
  4. 检查证书过期时间:
    # 查看kubelet当前使用的证书
    openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text -noout | grep -A2 "Validity"
    # 输出示例:
    # Validity
    #     Not Before: Jan 10 12:00:00 2024 GMT
    #     Not After : Jan 10 12:00:00 2025 GMT  ← 已过期
  5. 验证证书轮换配置:
    # 检查kubelet配置中证书轮换是否启用
    kubectl get nodes node-1 -o yaml | grep -i "rotate"
    # 或SSH到节点检查kubelet配置文件
    cat /var/lib/kubelet/config.yaml | grep -i "rotate"
    # 期望输出:
    # rotateCertificates: true
    # rotateServerCertificates: true

4.5 证书轮换机制对比

轮换类型 触发条件 证书类型 常见失败原因
客户端证书轮换 kubelet启动时检查证书剩余时间 < 80% 有效期 kubelet-client-current.pem CSR审批被拒绝、CA证书不匹配、kubelet无权创建CSR
服务端证书轮换 kubelet启动时检查证书剩余时间 < 80% 有效期 kubelet-server-current.pem kubelet配置中 rotateServerCertificates: false
手动轮换 管理员手动删除旧证书文件并重启kubelet 所有kubelet证书 证书目录权限错误、kubelet无法读取新证书

4.6 快速恢复方案

💡 应急恢复步骤: 当确认是kubelet证书过期导致NotReady时,按以下顺序执行恢复。
  1. 方案一:手动触发证书轮换(推荐)
    # 1. 删除过期证书文件
    rm -f /var/lib/kubelet/pki/kubelet-client-current.pem
    rm -f /var/lib/kubelet/pki/kubelet-server-current.pem
    
    # 2. 重启kubelet服务
    systemctl restart kubelet
    
    # 3. 验证新证书是否生成
    ls -la /var/lib/kubelet/pki/kubelet-client-current.pem
    
    # 4. 确认节点状态恢复
    kubectl get nodes node-1
    # 等待约40秒后状态应变为 Ready
  2. 方案二:手动签发证书(当自动轮换完全失效时)
    # 1. 生成新的CSR
    openssl req -new -key /var/lib/kubelet/pki/kubelet-client.key \
      -out /tmp/kubelet-client.csr \
      -subj "/CN=system:node:node-1/O=system:nodes"
    
    # 2. 使用集群CA签发证书
    openssl x509 -req -in /tmp/kubelet-client.csr \
      -CA /etc/kubernetes/pki/ca.crt \
      -CAkey /etc/kubernetes/pki/ca.key \
      -CAcreateserial -out /var/lib/kubelet/pki/kubelet-client-current.pem \
      -days 365
    
    # 3. 重启kubelet
    systemctl restart kubelet
  3. 方案三:临时容忍Taint(仅用于紧急调度)
    # 为特定Pod添加容忍,使其可以调度到NotReady节点
    kubectl patch pod <pod-name> -p '{"spec":{"tolerations":[{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute"}]}}'

4.7 预防措施与监控建议

⚠️ 长期预防: 证书轮换失败是集群中最容易被忽视的故障之一,建议在集群部署阶段就完成以下配置。
  • 启用自动轮换: 在kubelet配置中设置 rotateCertificates: true 和 rotateServerCertificates: true
  • 监控证书过期时间: 使用Prometheus + Grafana监控kubelet证书剩余天数,建议在证书到期前30天告警
  • 配置CSR自动审批: 部署 kubelet-rubber-stamp 或配置RBAC允许kubelet自动审批自己的CSR
  • 定期巡检: 每月执行证书检查脚本,输出所有节点的证书过期时间
  • 证书有效期规划: 建议将kubelet证书有效期设置为1年,与集群CA证书有效期对齐

4.8 典型错误日志速查表

错误日志 含义 解决方案
x509: certificate has expired or is not yet valid 证书已过期或尚未生效 删除过期证书,重启kubelet触发轮换
failed to get recent kubelet config kubelet无法从APIServer获取配置 检查kubelet证书和APIServer连通性
csr not found or not approved CSR未被审批 检查CSR状态,手动审批或配置自动审批
certificate signed by unknown authority 证书签发者不被信任 检查CA证书是否匹配,重新签发证书
TLS handshake error: bad certificate TLS握手时证书验证失败 检查证书链是否完整,证书格式是否正确