3、kubelet 证书轮换机制:TLS Bootstrapping 与自动轮换
kubelet 作为 Kubernetes 集群中直接管理容器的核心组件,其与 API Server 之间的通信必须基于 TLS 加密。为了降低运维复杂度并提升安全性,Kubernetes 设计了 TLS Bootstrapping(TLS 引导)和 证书自动轮换 机制。本章将深入剖析这一流程,并明确证书的存储位置,为后续排查因证书轮换引发的资源争抢问题奠定基础。
3.1 TLS Bootstrapping:从零到可信
TLS Bootstrapping 解决了 kubelet 首次启动时如何获取初始证书的问题。其核心思想是:kubelet 使用一个预先配置的 Bootstrap 向 API Server 发起 CSR(Certificate Signing Request),由集群内的 Controller Manager 自动审批并签发证书。
关键前提: 集群必须预先在 kube-system 命名空间中创建 Bootstrap Secret,并在 kubelet 配置中指定 文件或 bootstrap-kubeconfig 文件。
3.1.1 引导流程步骤
- kubelet 启动:读取 bootstrap-kubeconfig 文件,获取 API Server 地址和 Bootstrap 。
- 发起 CSR:kubelet 使用 Bootstrap 向 API Server 提交一个
CertificateSigningRequest资源,请求签署一个用于 kubelet 身份的客户端证书。 - 自动审批:集群中的
kube-controller-manager内置的 CSR Approving Controller 检测到符合规则的 CSR(如由system:bootstrappers组发起),自动批准该请求。 - 证书签发:Controller Manager 调用 Kubernetes CA 签署证书,并将签名后的证书写入 CSR 对象的
status.certificate字段。 - kubelet 获取证书:kubelet 轮询或通过 Watch 机制获取到已批准的 CSR,提取证书并写入本地磁盘。
- 替换 kubeconfig:kubelet 使用新获取的证书替换原有的 bootstrap-kubeconfig,后续所有与 API Server 的通信均使用该证书。
3.2 证书自动轮换流程
kubelet 证书通常具有较短的有效期(如 1 年)。为了确保集群安全且无需人工干预,kubelet 支持 证书自动轮换。当证书剩余有效期低于阈值时,kubelet 会自动发起新的 CSR 请求,获取新证书并替换旧证书。
3.2.1 轮换触发条件
| 参数 | 默认值 | 说明 |
|---|---|---|
--rotate-certificates |
true | 启用证书自动轮换功能 |
--certificate-renewal-duration-threshold |
30 天 | 证书剩余有效期低于此值时触发轮换 |
--feature-gates=RotateKubeletServerCertificate=true |
默认关闭 | 启用服务端证书轮换(用于 kubelet 的 serving cert) |
3.2.2 轮换流程详解
- 检查有效期:kubelet 定期检查本地客户端证书的
NotAfter字段。 - 发起新 CSR:当剩余有效期低于阈值时,kubelet 使用当前有效的客户端证书(而非 Bootstrap )向 API Server 提交新的 CSR。
- 自动审批:CSR Approving Controller 检测到 CSR 由已认证的 kubelet 发起(通过证书中的 CN 字段,如
system:node:<node-name>),自动批准。 - 签发与获取:CA 签署新证书,kubelet 获取后写入磁盘。
- 热加载:kubelet 自动加载新证书,无需重启进程。旧证书在过期后自动失效。
最佳实践: 建议将 kubelet 证书有效期设置为 1 年,并确保集群时间同步(NTP),避免因时间偏差导致证书验证失败。
3.3 证书存储位置
kubelet 证书及相关文件存储在节点的文件系统中,默认路径由 kubelet 的 --cert-dir 参数指定。了解这些路径对于故障排查至关重要。
3.3.1 默认存储路径
| 文件/目录 | 默认路径 | 说明 |
|---|---|---|
| kubelet 客户端证书 | /var/lib/kubelet/pki/kubelet-client-current.pem |
当前使用的客户端证书(符号链接,指向具体版本文件) |
| kubelet 服务端证书 | /var/lib/kubelet/pki/kubelet-server-current.pem |
当前使用的服务端证书(用于 kubelet 的 HTTPS 端点) |
| kubelet CA 证书 | /var/lib/kubelet/pki/ca.crt |
用于验证 API Server 的 CA 证书 |
| Bootstrap kubeconfig | /etc/kubernetes/bootstrap-kubelet.conf |
包含 Bootstrap 的初始配置文件 |
| kubelet kubeconfig | /etc/kubernetes/kubelet.conf |
轮换后生成的正式 kubeconfig 文件 |
3.3.2 证书文件结构
在 /var/lib/kubelet/pki/ 目录下,kubelet 会维护多个版本的证书文件:
/var/lib/kubelet/pki/
├── kubelet-client-2024-01-01-12-00-00.pem # 具体版本证书
├── kubelet-client-current.pem # 符号链接 -> kubelet-client-2024-01-01-12-00-00.pem
├── kubelet-server-2024-01-01-12-00-00.pem
├── kubelet-server-current.pem # 符号链接
├── ca.crt
└── kubelet.crt # 旧版本遗留文件(可能不存在)
排查要点: 当证书轮换失败时,检查
/var/lib/kubelet/pki/ 目录下的文件数量。如果存在大量过期证书文件未被清理,可能触发磁盘空间不足或 inode 耗尽,进而导致 kubelet 资源争抢。
3.4 证书轮换与资源争抢的关联
证书轮换本身是一个轻量级操作,但在特定场景下可能成为资源争抢的导火索:
- 并发轮换风暴:当集群中大量节点的证书在同一时间段内过期时,所有 kubelet 同时发起 CSR 请求,可能导致 API Server 和 Controller Manager 的 CPU、内存负载飙升。
- 磁盘 I/O 压力:频繁的证书文件写入(尤其是大量节点同时轮换)可能对 etcd 和节点本地磁盘造成 I/O 压力。
- inode 耗尽:如果证书轮换机制存在 bug 或配置不当,导致旧证书文件未被清理,长期运行后可能耗尽文件系统的 inode 资源。