1. K8s 证书体系概述

Kubernetes 集群的安全通信完全建立在 PKI(公钥基础设施) 之上。每个控制面组件、工作节点和客户端都必须通过 TLS 证书验证身份,才能参与集群操作。证书体系一旦出现过期、签名不匹配或信任链断裂,将直接导致集群不可用——这也是证书轮换成为 SRE 日常高频作业的根本原因。

1.1 证书在 K8s 集群中的核心作用

作用维度 具体说明 影响范围
身份认证 每个组件(apiserver、kubelet、etcd、scheduler、controller-manager)通过 TLS 证书证明自身身份,防止中间人攻击。 所有组件间通信
通信加密 所有 API 请求、etcd 读写、kubelet 与 apiserver 之间的数据流均通过 TLS 加密传输。 控制面 & 数据面
权限绑定 证书中的 CN(Common Name)和 O(Organization)字段映射到 RBAC 用户/组,实现细粒度访问控制。 kubectl、ServiceAccount、kubelet
集群信任锚点 CA 证书作为集群的根信任,所有组件证书必须由集群 CA 签发,形成统一的信任链。 整个集群
排障要点: 证书过期是 K8s 集群最常见的“静默故障”之一。apiserver 日志中频繁出现 x509: certificate has expired or is not yet valid 时,应优先检查证书有效期。

1.2 PKI 体系与证书信任链

K8s 采用 两级 PKI 架构:根 CA 自签名,再由根 CA 签发多个组件证书。信任链如下:

  1. 根 CA 证书(ca.crt) — 集群的信任锚点,所有组件必须信任此 CA。
  2. 中间/组件证书 — 由根 CA 签发,每个组件持有自己的证书和私钥。
  3. 客户端证书 — 用于 kubectl、ServiceAccount 等外部实体访问 apiserver。
K8s 证书信任链(两级 PKI 架构) 根 CA(自签名) apiserver 证书 kubelet 证书 etcd 证书 kubectl 客户端 ServiceAccount 聚合 API 扩展 所有组件证书均由根 CA 签发,客户端证书由 apiserver 或 CA 签发

1.3 主要证书类型与用途

证书类型 持有者 关键用途 默认有效期 常见路径
CA 证书 集群根 CA 签发所有组件证书,验证组件身份 10 年 /etc/kubernetes/pki/ca.crt
apiserver 证书 kube-apiserver 对外提供 HTTPS 服务,客户端验证服务端身份 1 年 /etc/kubernetes/pki/apiserver.crt
kubelet 证书 kubelet(每个节点) kubelet 与 apiserver 双向 TLS 认证 1 年 /var/lib/kubelet/pki/kubelet.crt
etcd 证书 etcd 集群 etcd 节点间通信 & apiserver 访问 etcd 1 年 /etc/kubernetes/pki/etcd/server.crt
kubeconfig 证书 kubectl / 管理员 客户端身份认证,映射 RBAC 权限 1 年 ~/.kube/config 内嵌
ServiceAccount 密钥 Pod / 应用 Pod 内访问 API Server 的凭证 无固定期限 自动挂载到 Pod
SRE 提示: kubeadm 部署的集群默认证书有效期为 1 年(CA 为 10 年)。生产环境建议在证书到期前 90 天启动轮换计划,避免集群“静默失联”。

1.4 证书文件分布与命名规范

以 kubeadm 部署的标准集群为例,证书文件集中在 /etc/kubernetes/pki/ 目录下:

/etc/kubernetes/pki/
├── ca.crt                   # 根 CA 公钥
├── ca.key                   # 根 CA 私钥(极敏感)
├── apiserver.crt            # apiserver 服务端证书
├── apiserver.key            # apiserver 私钥
├── apiserver-kubelet-client.crt   # apiserver 访问 kubelet 的客户端证书
├── apiserver-kubelet-client.key
├── front-proxy-ca.crt       # 前端代理 CA(用于聚合 API)
├── front-proxy-client.crt
├── etcd/
│   ├── ca.crt               # etcd 专用 CA
│   ├── server.crt           # etcd 服务端证书
│   ├── server.key
│   ├── peer.crt             # etcd 节点间通信证书
│   └── peer.key
└── sa.pub / sa.key          # ServiceAccount 签名密钥对
安全警告: ca.key 和 etcd/ca.key 是集群的“根密钥”,一旦泄露,攻击者可签发任意证书。生产环境应使用 HSM 或密钥管理服务保护 CA 私钥。

1.5 证书轮换的触发场景

  • 证书过期: 默认 1 年有效期,到期后组件间 TLS 握手失败。
  • 集群升级: K8s 版本升级可能要求更新证书签名算法或 SAN 条目。
  • 节点扩缩容: 新加入的节点需要重新签发 kubelet 证书。
  • 安全合规: 证书被吊销、私钥泄露或密码学算法升级(如 SHA-1 → SHA-256)。
  • 域名/IP 变更: apiserver 的 SAN 中需要添加新的 DNS 名称或负载均衡 IP。
证书轮换触发场景与影响 证书轮换触发 证书过期 集群升级 节点扩缩容 安全合规 域名/IP 变更 任何触发场景都可能导致集群组件间 TLS 握手失败,需立即执行证书轮换

1.6 证书健康检查常用命令

在进入轮换作业之前,SRE 应掌握以下快速诊断命令:

# 查看 apiserver 证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates

# 查看 kubelet 证书有效期
openssl x509 -in /var/lib/kubelet/pki/kubelet.crt -noout -dates

# 查看 etcd 证书有效期
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates

# 使用 kubeadm 检查所有证书过期时间(kubeadm 集群)
kubeadm certs check-expiration

# 查看 kubeconfig 中嵌入的客户端证书
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | base64 -d | openssl x509 -noout -text | grep -E "Not Before|Not After"
排障实战: 当 kubectl get nodes 返回 Unauthorized 或 certificate signed by unknown authority 时,优先执行 kubeadm certs check-expiration 定位过期证书,再按证书类型执行轮换。