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.crt / ca.key(自签名) 集群主 CA 签发 apiserver / kubelet 证书 front-proxy CA 聚合 API 专用信任域 etcd CA etcd 集群独立信任域 apiserver 服务端 apiserver.crt kubelet 客户端 kubelet-client.crt kubelet 服务端 kubelet.crt admin / 用户 admin.conf front-proxy 客户端 front-proxy-client.crt etcd server / peer / client server.crt · peer.crt · healthcheck-client.crt 证书链验证路径(以 kubelet 访问 apiserver 为例) kubelet 客户端证书 含 SAN: system:node 签名 集群主 CA ca.crt 信任 apiserver 校验 --client-ca-file 认证 通过 建立 TLS

二、根 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 检查。

五、信任模型的实际含义

理解这套信任模型后,可以得出几个对运维有直接指导意义的结论:

  1. 证书过期不是孤立事件。如果集群主 CA 过期,所有由它签发的叶子证书都会验证失败,表现为 apiserver 无法启动、kubelet 无法注册、kubectl 报 x509: certificate has expired。因此 CA 证书的到期时间必须优先监控。
  2. 信任域隔离意味着排障要分域。etcd 连接失败时,应检查 etcd CA 而非集群主 CA;聚合 API 不可用时,应检查 front-proxy CA。混用 CA 文件会导致 x509: certificate signed by unknown authority。
  3. ServiceAccount 不走 X.509 证书链。sa.key/sa.pub 是纯密钥对,用于签发和验证 JWT 令牌,与上述证书体系平行存在,不要混淆。
  4. 轮换必须自顶向下。先轮换根 CA,再轮换中间 CA,最后轮换叶子证书;顺序颠倒会导致新叶子证书无法被旧 CA 验证。