4. Kubernetes 证书体系:核心组件的用途与生命周期
在 Kubernetes 集群中,TLS 证书是保障组件间通信安全的核心机制。当证书轮换引发 CoreDNS 解析超时时,往往是因为证书过期、SAN 不匹配或信任链断裂导致通信中断。本节将系统梳理 kube-apiserver、kubelet、CoreDNS 和 etcd 四大组件的证书用途、签发方式与生命周期管理要点。
4.1 证书体系总览
Kubernetes 采用双向 TLS(mTLS)认证,所有组件之间的通信都需要验证对端身份。证书体系分为两类:
- 服务端证书:用于验证服务端身份,客户端通过 CA 公钥校验服务端证书的合法性。
- 客户端证书:用于验证客户端身份,服务端通过 CA 公钥校验客户端证书的合法性。
下表列出了四大核心组件的证书用途与典型生命周期:
| 组件 | 证书用途 | 签发方式 | 默认有效期 | 轮换触发条件 |
|---|---|---|---|---|
| kube-apiserver | 服务端证书,供 kubelet、kubectl、controller-manager 等客户端验证 API Server 身份 | kubeadm 自动签发 / 手动 CA | 1 年 | 证书过期、SAN 变更、集群升级 |
| kubelet | 服务端证书(kubelet API)+ 客户端证书(向 API Server 注册) | kubeadm 自动签发 / TLS bootstrapping | 1 年 | 证书过期、节点重注册 |
| CoreDNS | 服务端证书(DNS-over-TLS 场景)+ 客户端证书(向 API Server 查询 Service) | kubeadm 自动签发 / 手动管理 | 1 年 | 证书过期、CoreDNS 重启 |
| etcd | 服务端证书(etcd 监听)+ 客户端证书(API Server 连接 etcd)+ 对等证书(etcd 集群内部通信) | kubeadm 自动签发 / 手动 CA | 1 年 | 证书过期、集群扩缩容 |
关键认知:CoreDNS 的证书问题往往不是 CoreDNS 本身证书过期,而是 kube-apiserver 证书轮换后,CoreDNS 未及时更新信任链,导致 DNS 查询时 TLS 握手失败,进而引发解析超时。
4.2 kube-apiserver 证书
kube-apiserver 是集群的“心脏”,其证书用于对外提供 HTTPS 服务。所有客户端(kubelet、kubectl、controller-manager、scheduler、CoreDNS 等)都需要信任签发 API Server 证书的 CA。
证书文件位置
/etc/kubernetes/pki/apiserver.crt # 服务端证书
/etc/kubernetes/pki/apiserver.key # 私钥
/etc/kubernetes/pki/ca.crt # CA 证书(客户端信任锚点)
证书 SAN 要求
API Server 证书的 SAN(Subject Alternative Name)必须包含所有客户端访问的地址:
- kubernetes.default.svc.cluster.local(Service 名称)
- kubernetes.default.svc
- kubernetes.default
- kubernetes
- localhost
- 所有 Master 节点的 IP 地址
- 负载均衡器地址(如果有)
故障案例:某集群在证书轮换时遗漏了
kubernetes.default.svc.cluster.local 这个 SAN,导致 CoreDNS 通过 Service 名称访问 API Server 时 TLS 握手失败,DNS 解析请求无法写入 etcd,最终表现为集群内域名解析超时。
4.3 kubelet 证书
kubelet 证书分为两种角色:
- 服务端证书:kubelet 监听 10250 端口,供 API Server 和 kubectl exec/logs 等操作使用。
- 客户端证书:kubelet 向 API Server 注册节点、上报状态时使用。
TLS Bootstrapping 流程
kubeadm 默认使用 TLS Bootstrapping 自动签发 kubelet 证书:
- kubelet 启动时使用预置的 bootstrap 向 API Server 发起 CSR。
- API Server 自动批准 CSR,签发 kubelet 客户端证书。
- kubelet 使用新证书与 API Server 通信。
- kubelet 服务端证书由 kube-controller-manager 中的
csrapproving控制器自动签发。
证书轮换影响:kubelet 证书过期会导致节点状态变为
NotReady,进而影响 CoreDNS 的 Endpoint 更新。如果 CoreDNS 依赖的 Service 后端 Pod 所在节点 NotReady,DNS 解析可能返回错误 IP 或超时。
4.4 CoreDNS 证书
CoreDNS 证书的使用场景相对特殊:
- 默认场景:CoreDNS 通过 Service 账号(ServiceAccount)访问 API Server,不依赖客户端证书。
- DNS-over-TLS 场景:如果启用了加密 DNS,CoreDNS 需要服务端证书。
- 证书信任链场景:CoreDNS 的 Pod 内挂载了
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt,用于验证 API Server 证书。
证书轮换对 CoreDNS 的影响路径
当 API Server 证书轮换后,CoreDNS 需要重新加载 CA 证书才能继续信任新的 API Server 证书。如果 CoreDNS Pod 未重启或未重新挂载 Secret,会导致以下故障链:
- API Server 证书轮换 → 旧 CA 信任链失效
- CoreDNS 尝试查询 API Server(如
kubernetes.default.svc)→ TLS 握手失败 - CoreDNS 无法获取 Service 和 Endpoint 信息 → DNS 解析失败
- 集群内 Pod 访问 Service 时 DNS 查询超时
排查要点:检查 CoreDNS Pod 日志中是否包含
x509: certificate signed by unknown authority 或 certificate has expired 错误。如果出现,说明证书信任链已断裂。
4.5 etcd 证书
etcd 证书体系最为复杂,包含三种证书:
| 证书类型 | 用途 | 文件位置(kubeadm) |
|---|---|---|
| 服务端证书 | etcd 监听 2379/2380 端口,供 API Server 和其他 etcd 节点连接 | /etc/kubernetes/pki/etcd/server.crt |
| 客户端证书 | API Server 连接 etcd 时使用 | /etc/kubernetes/pki/etcd/client.crt |
| 对等证书 | etcd 集群内部节点间通信(Raft 协议) | /etc/kubernetes/pki/etcd/peer.crt |
证书轮换的连锁反应
etcd 证书轮换需要严格按顺序执行,否则会导致集群分裂:
- 先轮换 etcd 对等证书(所有节点逐一更新)
- 再轮换 etcd 服务端证书
- 最后更新 API Server 使用的 etcd 客户端证书
- 重启 API Server 加载新证书
故障案例:某运维人员直接轮换了 etcd 客户端证书但未更新 API Server 的 etcd 连接配置,导致 API Server 无法连接 etcd,集群进入“脑死亡”状态。CoreDNS 因无法访问 API Server 而完全失效,所有 DNS 解析全部超时。
4.6 证书生命周期管理最佳实践
- 统一 CA 管理:使用 kubeadm 或 cert-manager 统一管理 CA 证书,避免多个 CA 导致信任链混乱。
- 提前轮换:在证书过期前 30 天完成轮换,预留回退时间。
- 验证 SAN:轮换后使用
openssl x509 -in apiserver.crt -text -noout检查 SAN 是否完整。 - 重启 CoreDNS:API Server 证书轮换后,建议滚动重启 CoreDNS Pod 以加载最新 CA 证书。
- 监控证书过期时间:使用
kubelet --rotate-certificates或 Prometheus 证书过期指标进行监控。
4.7 证书轮换与 CoreDNS 解析超时的关联 SVG 图
4.8 证书文件关系与信任链 SVG 图
4.9 证书轮换检查清单
在证书轮换前后,建议按以下清单逐项验证:
- 检查证书过期时间:
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates - 验证 SAN 完整性:
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -ext subjectAltName - 确认 CA 证书一致性:比较
/etc/kubernetes/pki/ca.crt与 CoreDNS 挂载的 CA 是否一致 - 测试 API Server 连接:
curl --cacert /etc/kubernetes/pki/ca.crt https://localhost:6443/healthz - 重启 CoreDNS:
kubectl rollout restart -n kube-system deployment/coredns - 验证 DNS 解析:
kubectl run test-pod --image=busybox --rm -it -- nslookup kubernetes.default.svc
自动化建议:使用
cert-manager 或 kubeadm certs renew 命令自动轮换证书,并配置 pre-hook 和 post-hook 自动重启 CoreDNS 和相关组件,避免人工操作遗漏。