3、kubelet 证书轮换机制

kubelet 与 kube-apiserver 之间的所有通信都依赖 TLS 证书进行身份认证与加密。默认情况下,kubelet 在启动时会生成一个自签名证书或由集群 CA 签发的初始证书,该证书具有固定的有效期(通常为 1 年)。当证书即将过期或已经过期时,kubelet 将无法成功向 apiserver 上报心跳(NodeLease 或 NodeStatus),导致集群将该节点标记为 NotReady。理解证书轮换的完整流程是排查此类故障的前提。

3.1 kubelet 证书签名请求(CSR)流程

kubelet 证书轮换的核心机制基于 Kubernetes 内置的 证书签名请求(CertificateSigningRequest, CSR) 资源。当 kubelet 需要新证书时,它会生成一个私钥和证书签名请求,并将 CSR 对象提交到集群。集群中的证书控制器(kube-controller-manager 中的 csrapproving 和 csrsigning 控制器)负责自动批准和签发证书。

关键流程节点: kubelet 生成密钥对 → 构造 CSR 对象 → 提交至 apiserver → 控制器自动批准 → 控制器签名 → kubelet 拉取并加载新证书。
kubelet 证书签名请求(CSR)完整流程 kubelet 生成私钥 + CSR 提交 CSR 对象 kube-apiserver 证书控制器 自动批准 CSR CA 签名证书 拉取已签名证书 加载新证书 心跳上报恢复 说明: 整个 CSR 流程从 kubelet 发起请求到加载新证书,通常在数十秒内完成。 如果自动批准或签名失败,kubelet 会持续重试,但心跳可能在此期间中断。

3.2 证书轮换触发条件

kubelet 不会等到证书完全过期才发起轮换,而是根据证书剩余有效期提前触发。触发条件由以下参数控制:

触发条件 默认值 说明
证书剩余有效期 < rotate-certificates 阈值 证书总有效期的 20% 例如 1 年有效期的证书,剩余不足 73 天时触发轮换
证书已过期 立即触发 如果证书已过期,kubelet 会立即发起 CSR,但此时心跳可能已失败
kubelet 重启 — 重启时检查证书有效性,若剩余有效期不足则触发轮换
手动触发(证书文件被删除或修改) — 运维人员删除证书文件后,kubelet 自动重新申请
常见陷阱: 如果集群时间不同步(NTP 失效),kubelet 可能错误判断证书剩余有效期,导致提前轮换或延迟轮换。时间偏差超过 5 分钟时,CSR 签名可能因时间校验失败而被拒绝。

3.3 自动轮换配置

kubelet 证书自动轮换功能由两个核心开关控制,需要在 kubelet 配置文件中正确设置:

# kubelet 配置文件片段 (config.yaml)
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
rotateCertificates: true                    # 启用证书轮换功能
serverTLSBootstrap: true                    # 启用服务端证书自动引导
featureGates:
  RotateKubeletServerCertificate: true      # 允许轮换服务端证书(K8s 1.7+ 默认启用)

配置参数详解:

参数 作用域 默认值 说明
rotateCertificates 客户端证书 false 启用后,kubelet 会在客户端证书即将过期时自动申请新证书
serverTLSBootstrap 服务端证书 false 启用后,kubelet 会为 TLS 服务端监听端口申请证书,而非使用自签名证书
RotateKubeletServerCertificate 特性门控 true (K8s 1.7+) 允许 kubelet 服务端证书轮换,需配合 serverTLSBootstrap 使用
最佳实践: 在生产集群中,始终将 rotateCertificates 和 serverTLSBootstrap 设置为 true。同时确保集群的 kube-controller-manager 已启用 --cluster-signing-cert-file 和 --cluster-signing-key-file 参数,并配置了正确的 CA 证书和密钥路径。

3.4 证书轮换状态验证

运维人员可以通过以下命令查看 kubelet 当前的证书状态和轮换历史:

# 查看 kubelet 证书文件信息
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text -noout | grep -E "Not Before|Not After|Subject"

# 查看集群中的 CSR 对象(已批准和待处理的)
kubectl get csr --sort-by=.metadata.creationTimestamp

# 查看特定 CSR 的详细信息
kubectl describe csr <csr-name>

# 查看 kubelet 日志中的证书轮换事件
journalctl -u kubelet -f | grep -i "certificate\|rotation\|csr"

当证书轮换正常工作时,kubectl get csr 的输出应显示最近有 Approved,Issued 状态的 CSR 记录。如果出现大量 Pending 状态的 CSR,说明自动批准机制可能失效,需要检查证书控制器的日志。

证书轮换触发条件与配置决策树 证书轮换触发 剩余有效期 < 20% 证书已过期 kubelet 重启 rotateCertificates=true 心跳可能已中断 检查证书有效期 自动 CSR → 批准 → 签名 → 加载 → 心跳恢复
排查要点: 当 kubelet 心跳上报失败时,应首先检查 /var/lib/kubelet/pki/ 目录下的证书文件是否存在、是否过期。使用 openssl x509 -in kubelet-client-current.pem -noout -dates 查看证书有效期。如果证书已过期且 rotateCertificates 未启用,需要手动删除证书文件并重启 kubelet,或临时调整系统时间以触发轮换。