2. Kubernetes证书体系与信任模型
Kubernetes 集群本质上是一个由多个独立进程通过 TLS 相互通信的分布式系统。kube-apiserver、kubelet、etcd、controller-manager、scheduler 以及各类客户端(kubectl、ServiceAccount、聚合 API)之间,几乎每一次请求都建立在证书验证之上。理解这套 PKI(Public Key Infrastructure,公钥基础设施)的层次结构,是后续做证书轮换、过期排障和自动化治理的前提。
一、集群 PKI 的整体架构
Kubernetes 的 PKI 是一棵典型的树形信任结构:最顶层是自签名的根 CA(Root CA),根 CA 之下签发若干中间 CA(Intermediate CA),中间 CA 再签发各组件实际使用的叶子证书(Leaf Certificate)。这种分层并非 Kubernetes 独创,而是遵循 X.509 的最佳实践——根 CA 的私钥可以离线保存、极少使用,日常签发由中间 CA 承担,一旦中间 CA 泄露,只需吊销该中间 CA 而无需重建整个信任体系。
在 kubeadm 部署的集群中,默认会在 /etc/kubernetes/pki/ 下生成如下结构:
/etc/kubernetes/pki/
├── ca.crt / ca.key # 集群根 CA(自签名)
├── apiserver.crt / apiserver.key # apiserver 服务端证书(由 ca 签发)
├── apiserver-kubelet-client.crt # apiserver 访问 kubelet 的客户端证书
├── front-proxy-ca.crt / .key # 聚合层专用 CA
├── front-proxy-client.crt / .key # 聚合层客户端证书
├── etcd/
│ ├── ca.crt / ca.key # etcd 独立根 CA
│ ├── server.crt / server.key # etcd 服务端证书
│ ├── peer.crt / peer.key # etcd 节点间通信证书
│ └── healthcheck-client.crt # etcd 健康检查客户端证书
└── sa.key / sa.pub # ServiceAccount 令牌签名密钥对
可以看到,kubeadm 实际上维护了三套彼此独立的信任域:集群主 CA、front-proxy CA 和 etcd CA。它们互不签发、互不信任,这是有意为之的隔离设计——etcd 的证书泄露不应波及 apiserver,聚合 API 的扩展组件也不应持有集群主 CA 的信任。
二、根 CA 与中间 CA 的职责划分
根 CA 的核心职责只有一件事:签发中间 CA 证书。它的私钥应当被严格保护,理想情况下离线存放,仅在需要新增或轮换中间 CA 时才启用。根 CA 证书本身是自签名的,其有效期通常设置得很长(kubeadm 默认 10 年),因为一旦根 CA 过期,整个集群的信任基础就会崩塌。
中间 CA 承担日常签发工作。以集群主 CA 为例,它需要签发 apiserver 服务端证书、apiserver 访问 kubelet 的客户端证书、kubelet 服务端证书、controller-manager 和 scheduler 的客户端证书、admin 用户证书以及各类 ServiceAccount 之外的组件证书。中间 CA 的有效期通常短于根 CA(kubeadm 默认同样为 10 年,但生产环境常缩短至 3~5 年),以便在私钥泄露时缩小影响窗口。
需要特别注意的是,Kubernetes 默认并不使用真正的“中间 CA”层级——kubeadm 生成的 ca.crt 直接签发叶子证书,中间 CA 的概念更多体现在 etcd 与 front-proxy 的独立信任域上。如果企业已有自己的 PKI 体系,可以将 Kubernetes 的根 CA 替换为由企业根 CA 签发的中间 CA,从而把集群纳入统一信任管理。
三、证书链与信任分发
证书链(Certificate Chain)是验证方从叶子证书逐级向上追溯至受信任根证书的路径。以 kubelet 访问 apiserver 为例:kubelet 出示自己的客户端证书,apiserver 用 --client-ca-file 指定的 CA 证书验证该叶子证书的签名,若签名有效且证书未过期、未被吊销,则认证通过。这条链是:kubelet 客户端证书 → 集群主 CA → 集群根 CA。
信任分发的关键在于:每个组件都必须持有验证对方证书所需的 CA 证书。具体来说:
- apiserver 需要
--client-ca-file(验证客户端)、--tls-cert-file与--tls-private-key-file(自身服务端证书)、--kubelet-client-certificate(访问 kubelet 时出示); - kubelet 需要
--client-ca-file(验证 apiserver 客户端证书)、--tls-cert-file与--tls-private-key-file(自身服务端证书); - etcd 需要独立的
--trusted-ca-file、--cert-file、--key-file以及 peer 证书; - controller-manager 与 scheduler 通过 kubeconfig 中的
certificate-authority字段信任 apiserver。
这些 CA 证书通过 kubeconfig 文件、静态 Pod 清单的挂载卷或 Secret 分发到各组件。kubeadm 生成的 /etc/kubernetes/*.conf 文件内嵌了 CA 证书的 base64 编码,组件启动时直接读取即可完成信任建立。
四、各组件证书角色与用途
下表汇总了集群中主要证书的角色、签发者与典型用途,可作为日常巡检和排障的对照参考:
| 证书 | 签发者 | 角色 | 典型用途 |
|---|---|---|---|
| ca.crt | 自签名 | 根 CA | 签发集群内所有主 CA 叶子证书 |
| apiserver.crt | 集群主 CA | 服务端 | apiserver 对外提供 HTTPS 服务 |
| apiserver-kubelet-client.crt | 集群主 CA | 客户端 | apiserver 访问 kubelet 的 10250 端口 |
| kubelet.crt | 集群主 CA | 服务端 | kubelet 暴露 HTTPS 端点供 apiserver 调用 |
| admin.conf 内证书 | 集群主 CA | 客户端 | kubectl 以 cluster-admin 身份访问 apiserver |
| front-proxy-client.crt | front-proxy CA | 客户端 | apiserver 访问聚合 API 扩展组件 |
| etcd/server.crt | etcd CA | 服务端 | etcd 对外提供客户端访问 |
| etcd/peer.crt | etcd CA | 服务端+客户端 | etcd 节点间 raft 通信 |
| sa.key / sa.pub | 非证书 | 密钥对 | ServiceAccount 令牌签名与验证 |
kubeadm certs check-expiration 可以一次性列出所有由 kubeadm 管理的证书及其剩余有效期。该命令会区分“CA 证书”和“叶子证书”,并标注哪些证书已过期或即将过期。对于非 kubeadm 管理的证书(如手动签发的 kubelet 证书),需要单独用 openssl x509 -in <cert> -noout -dates 检查。
五、信任模型的实际含义
理解这套信任模型后,可以得出几个对运维有直接指导意义的结论:
- 证书过期不是孤立事件。如果集群主 CA 过期,所有由它签发的叶子证书都会验证失败,表现为 apiserver 无法启动、kubelet 无法注册、kubectl 报
x509: certificate has expired。因此 CA 证书的到期时间必须优先监控。 - 信任域隔离意味着排障要分域。etcd 连接失败时,应检查 etcd CA 而非集群主 CA;聚合 API 不可用时,应检查 front-proxy CA。混用 CA 文件会导致
x509: certificate signed by unknown authority。 - ServiceAccount 不走 X.509 证书链。sa.key/sa.pub 是纯密钥对,用于签发和验证 JWT 令牌,与上述证书体系平行存在,不要混淆。
- 轮换必须自顶向下。先轮换根 CA,再轮换中间 CA,最后轮换叶子证书;顺序颠倒会导致新叶子证书无法被旧 CA 验证。