Skip to content

Kubernetes v1.37:Pod Certificates 与 Cluster Trust Bundles —— 生产级身份认证的范式跃迁

核心摘要:Kubernetes v1.37 将 Pod Certificates(基于 X.509 的 Pod 级 TLS/mTLS 身份)与 ClusterTrustBundle(集群级可信根证书统一分发机制)正式 GA。这并非对 ServiceAccount JWT 的替代,而是补全了 Kubernetes 原生身份栈的关键拼图:从“我能声明我是谁”(JWT bearer token),迈向“我能被密码学证明我是谁”(PKI-based identity with mutual TLS)。对中高级 SRE 而言,这意味着——零信任网络策略可落地、跨集群/跨云服务调用可强验证、Sidecar-less mTLS 成为可能,但同时也引入了证书生命周期管理的新运维面。


背景动机:为什么 JWT 不足以支撑现代零信任架构?

ServiceAccount JWT 自 v1.0 起就是 Kubernetes 的“默认身份”,它简洁、轻量、开箱即用。但正如官方博客所坦诚的:“If you have the token, then you are the identity”——这句话精准点出了其本质缺陷:Bearer Token 天然缺乏绑定性(binding)与抗泄露能力

我们来拆解三个现实中的“JWT 痛点”,这些正是推动 Pod Certificates GA 的真实驱动力:

  1. 容器逃逸后的身份冒用风险
    JWT 文件(如 /var/run/secrets/kubernetes.io/serviceaccount/token)以明文形式挂载在容器内。一旦攻击者突破容器边界(例如通过 runc 漏洞或特权容器),即可直接读取并复用该 token 访问 API Server 或其他依赖 JWT 的外部系统(如云厂商 IAM)。而 X.509 证书若配合私钥硬件保护(如 KMS-backed key store 或 TPM),可实现密钥不可导出(non-exportable private key),从根本上阻断此类横向移动。

  2. 无法满足双向 TLS(mTLS)强制要求
    金融、政务、信创等合规场景普遍要求服务间通信必须启用 mTLS。传统方案需引入 Istio/Linkerd 等 Service Mesh,带来 Sidecar 注入、性能损耗(~10–15% CPU overhead)、可观测性复杂度飙升等问题。Pod Certificates 允许 Kubelet 直接为每个 Pod 签发唯一证书,并自动注入到容器文件系统(如 /var/run/secrets/tls/),使 curl --cert /var/run/secrets/tls/tls.crt --key /var/run/secrets/tls/tls.key https://backend.default.svc.cluster.local 成为原生能力。

  3. 跨集群/跨云身份联邦的信任锚缺失
    JWT 可通过 audienceissuer 实现跨集群验证,但其信任链终点仍是 JWT 签名密钥——该密钥由 kube-apiserver 内部管理,无法被外部系统(如企业 PKI CA 或 HashiCorp Vault)权威背书。而 ClusterTrustBundle 提供了一种声明式、版本化、自动同步的机制,将集群信任锚(root CA)作为 Kubernetes 原生资源(CRD)进行生命周期管理,使得 Vault、SPIFFE Workload API、甚至裸金属节点上的 nginx 都能动态加载同一套可信根。

技术判断:这不是“JWT vs X.509”的二选一,而是构建分层身份体系的必然演进。JWT 仍适用于短时、低敏感度的 API Server 认证;而 Pod Certificates 则承担高保障场景下的工作负载身份——二者共存,恰如 HTTP Basic Auth 与 TLS Client Cert 在 Web 架构中的分工。


核心技术:如何启用与验证?

1. 启用前提(v1.37+ 必须配置)

Pod Certificates 功能依赖 CertificateSigningRequest(CSR)API 和新的 PodSecurityPolicy 替代品 PodSecurityAdmission。需确保以下配置已就绪:

bash
# 检查 CSR API 是否启用(默认开启)
kubectl api-resources | grep certificatesigningrequests

# 确认 kube-controller-manager 启用了相关控制器(v1.37 默认启用)
# --enable-hostpath-provisioner=false \  # 仅示例,非必需
# --cluster-signing-key-file=/etc/kubernetes/pki/ca.key \
# --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt \

2. ClusterTrustBundle:集中分发可信根

ClusterTrustBundle 是一个集群范围的 CRD,用于定义一组受信任的根证书(CA Bundle),并自动同步至所有节点的指定路径(如 /etc/kubernetes/pki/trust-bundle.pem):

yaml
# cluster-trust-bundle.yaml
apiVersion: crypto.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
  name: enterprise-ca
  labels:
    kubernetes.io/cluster-service: "true"
spec:
  signerName: kubernetes.io/kube-apiserver-client
  trustBundle: |
    -----BEGIN CERTIFICATE-----
    MIICqjCCAZICCQDlJw6zO4kWgTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhk
    ...
    -----END CERTIFICATE-----

应用后,Kubelet 会自动将该 bundle 合并写入 /etc/kubernetes/pki/trust-bundle.pem,并触发重启 kubelet(或通过 systemctl reload kubelet 触发重载)。

💡 运维提示ClusterTrustBundle 支持 revision 字段实现灰度更新。SRE 可先创建 enterprise-ca-v2,待 80% 节点完成同步后再删除旧版,避免证书吊销窗口期风险。

3. Pod Certificate:为 Pod 自动生成 TLS 凭据

只需在 Pod spec 中添加 securityContext 声明,Kubelet 即自动为其申请并注入证书:

yaml
# pod-with-cert.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-backend
  annotations:
    # 可选:指定证书有效期(默认 24h,最小 1h)
    kubernetes.io/certificate-expiration: "48h"
spec:
  serviceAccountName: backend-sa
  securityContext:
    # 关键:启用 Pod Certificate
    seccompProfile:
      type: RuntimeDefault
    # 新增字段:请求 TLS 证书
    certificate:
      request:
        commonName: "secure-backend.default.svc.cluster.local"
        usages:
        - client auth
        - server auth
        - digital signature
        - key encipherment
  containers:
  - name: app
    image: nginx:alpine
    volumeMounts:
    - name: tls-certs
      mountPath: /var/run/secrets/tls
      readOnly: true
  volumes:
  - name: tls-certs
    projected:
      sources:
      - serviceAccountToken:
          path: token
          expirationSeconds: 3600
      - configMap:
          name: ca-bundle  # 可选:注入 ClusterTrustBundle 内容
          items:
          - key: ca-bundle.pem
            path: ca-bundle.pem

Kubelet 会:

  • certificates.k8s.io/v1 API 创建 CertificateSigningRequest(CSR)
  • 使用集群 CA 签发证书(含 SAN secure-backend.default.svc.cluster.local
  • tls.crt / tls.key / ca.crt 自动注入到 /var/run/secrets/tls/

验证方式(进入容器):

bash
$ kubectl exec -it secure-backend -- sh
/ # openssl x509 -in /var/run/secrets/tls/tls.crt -text -noout | grep -E "(Subject|Issuer|DNS)"
        Subject: CN = secure-backend.default.svc.cluster.local
        Issuer: CN = kubernetes
                DNS:secure-backend.default.svc.cluster.local
/ # curl -v --cert /var/run/secrets/tls/tls.crt --key /var/run/secrets/tls/tls.key \
         --cacert /var/run/secrets/tls/ca.crt \
         https://kubernetes.default.svc.cluster.local:443/version

运维建议:从 GA 到生产就绪的 5 条实战守则

  1. 绝不关闭 CSR 审批自动化
    默认 csrapproving controller 会自动批准 kubernetes.io/kube-apiserver-client 类型 CSR。若你使用自定义 CA 或需人工审计,请部署 cert-managerCertificateRequest + Approval Policy,而非禁用 controller——否则 Pod Certificates 将永久 Pending。

  2. 监控 CSR 状态与证书续期延迟
    建议 Prometheus 抓取指标:

    promql
    kube_certificate_signing_request_condition{condition="Approved"} == 0
    histogram_quantile(0.95, rate(kube_certificate_signing_request_duration_seconds_bucket[1h]))

    若 P95 续期耗时 > 30s,需检查 kube-controller-manager 负载及 etcd 延迟。

  3. ClusterTrustBundle 版本必须与业务发布流水线对齐
    ClusterTrustBundle YAML 纳入 GitOps 工具链(Argo CD / Flux),并与企业 PKI 的证书轮换计划联动。避免出现“新服务用新根证书签名,但旧节点尚未同步 bundle”的信任断裂。

  4. Sidecar 场景下需显式挂载证书路径
    若你仍使用 Istio,需在 Sidecar resource 中显式声明挂载:

    yaml
    spec:
      template:
        spec:
          volumes:
          - name: pod-tls
            projected:
              sources:
              - secret:
                  name: istio-token  # 保留 JWT
              - downwardAPI:
                  items:
                  - path: "certs"
                    fieldRef:
                      fieldPath: metadata.annotations['kubernetes.io/pod-certificate-path']
  5. 审计所有使用 hostNetwork: true 的 Pod
    HostNetwork Pod 无法获得 Pod-level 证书(因无独立 network namespace),必须改用 Node CSR 或明确标记 securityContext.certificate.disabled: true,避免误配导致启动失败。


延伸阅读:超越 v1.37 的演进路线图

  • v1.38(规划中):支持 CertificateSigningRequestspec.signerName 引用 ClusterTrustBundle,实现多 CA 签发策略(如:内部服务用 Let’s Encrypt,对外 API 用企业 CA)。
  • SIG Auth 正在推进:将 Pod Certificates 与 SPIFFE ID (spiffe://cluster.example.com/ns/default/sa/backend-sa) 深度集成,打通 Kubernetes 与零信任中间件生态。
  • 生产警示:当前 ClusterTrustBundle 不支持 OCSP Stapling 或 CRL 分发点(CRL Distribution Points),如需实时吊销能力,仍需依赖外部证书管理平台(如 Smallstep 或 HashiCorp Vault)。

🌐 最后结语:Kubernetes 正从“容器编排平台”加速蜕变为“云原生身份基础设施”。Pod Certificates 的 GA,不是终点,而是 SRE 团队重构安全边界的起点——你的下一个 CI/CD 流水线,是否已准备好用 kubectl get clustetrustbundle 替代 openssl s_client?答案,就在你明天的 kubectl apply -f 命令里。