By Taahir Ahmed |
Friday, August 28, 2026
Kubernetes 提供丰富的功能,帮助你安全、可靠地运行生产工作负载。调度、健康检查、资源限制可能是最先想到的功能,但还有一个重要方面:生产环境身份,也就是工作负载如何向其他系统证明自身身份,以完成工作。
此前,Kubernetes 内置的主要生产身份机制是服务账号 JWT(JSON Web Token)。这些令牌由集群控制平面签发并进行密码学签名;工作负载使用它们时,接收方可以识别调用者身份。
Kubernetes 1.37 中,一种新的内置生产身份技术,其基础机制已经达到 GA(正式可用)。Pod 证书(Pod Certificates)及紧密相关的集群信任包(Cluster Trust Bundles),把用于 TLS 和双向 TLS(mTLS)的 X.509 证书签发直接纳入 Kubernetes 核心。
为什么需要它?
服务账号 JWT 有很多优点:
- 它们直接集成于 kubelet,使用体验非常自然。工作负载启动前,令牌已经写入容器文件系统,并且自动保持更新。
- 签发系统遵循最小权限原则。节点限制准入插件确保:只有当前实际运行该 Pod 的节点上的 kubelet,才能申请相应令牌。
- 它们可以进行身份联合,让工作负载向 Kubernetes 以外的系统认证。各大云提供商的 Pod 到云身份认证都以服务账号 JWT 为基础,很多其他服务和软件也支持。只要系统理解 JWT,就可以用服务账号令牌向其认证。
但服务账号 JWT 有一个很大的缺点:它们是持有者令牌(bearer token)。只要拥有令牌,就拥有令牌所声明的身份。而认证时,你必须把 JWT 的副本交给对端,因此对端也可能冒用你的身份。
时间绑定、对象绑定、受众绑定等措施能够部分缓解问题,服务账号令牌也采用了它们,但没有一种是完整防御。
解决方向是持有证明凭据(proof-of-possession credentials):不把完整凭据交给对端,只提交自己持有凭据的证明。实践中,这些方案建立在 RSA、ECDSA 等非对称密码签名之上。
标准方法有多种,例如请求签名(AWS SigV4、JWT DPoP、RFC 9421),但部署最广、理解最充分的是 TLS 使用的 X.509 证书。在 TLS 中,凭据分为两部分:
- 私钥。为获得最大安全性,应在工作负载内部或硬件安全模块中生成,并且永远不离开该边界。
- 证书。它描述身份和公钥,由证书颁发机构(CA)签名。
Pod 证书的目标是:让 Kubernetes 工作负载使用 X.509 证书与使用服务账号 JWT 一样容易,同时保持 Kubernetes 的高安全标准。作者认为已经达到了这个目标。
下面的架构和示例部分会展示,服务账号 JWT 签发与 Pod 证书设计之间有很多相似之处。不过,Pod 证书机制灵活得多,这是重要差别。Kubernetes 仅提供一种具有标准化声明的服务账号 JWT。
X.509 生态比 JWT 生态多样得多。不同用途的证书带有不同扩展和信息。因此,Pod 证书在 kubelet 中内置共用机制,同时提供可插拔接口,使同一个集群能够同时签发多种证书。
作者预计,未来 Kubernetes 至少会提供两种内置证书提供者:
- 一种为 Kubernetes Service 使用的 DNS 名称签发服务器 TLS 证书。
- 另一种提供 SPIFFE 客户端证书,承担服务账号 JWT 目前的角色。
本文余下部分介绍 Kubernetes 工作负载使用 Pod 证书的总体架构,并以一个真实但仅供实验的 Pod 证书签名控制器为例,介绍安装和使用方向。
架构
使用 Pod 证书与集群信任包时,主要组件包括:
- 应用:在 Pod 规约中请求证书,从容器文件系统读取密钥、证书和信任包,用于 TLS 或 mTLS。
- kubelet:代表工作负载创建
PodCertificateRequest对象,并读取ClusterTrustBundle对象。 - 签名控制器:响应
PodCertificateRequest,发布ClusterTrustBundle。
使用 Pod 证书的应用架构。
了解各组件职责的最好方式,是按时间顺序追踪签发流程。下列步骤将原文及其官方 Markdown 中错位的句尾归回对应句子,字段名称不变:
- 应用 Pod 调度到节点后,kubelet 识别规约中的全部
podCertificate和clusterTrustBundle投射卷源。 - 对每个
podCertificate卷源:- kubelet 根据
keyType字段生成新的私钥。 - kubelet 创建
PodCertificateRequest,发送给卷源中指定的签名者。 - 签名控制器看到请求后,决定是否签发证书。
- 签名控制器通过填写
status.certificateChain字段签发证书。 - 签名控制器填写
status.beginRefreshAt,告知 kubelet 应从何时开始尝试刷新证书。 - kubelet 取回签发的证书,把私钥与证书写入容器文件系统。
- kubelet 根据
- 对每个
clusterTrustBundle卷源:- kubelet 收集与卷源中签名者名称及标签选择器匹配的全部
ClusterTrustBundle。 - kubelet 合并匹配信任包中的所有证书,并稳定地重新排序,避免应用意外依赖某种特定顺序。
- kubelet 把证书写到卷源指定的文件路径。
- kubelet 收集与卷源中签名者名称及标签选择器匹配的全部
- 应用 Pod 启动,应用从文件系统读取密钥、证书和信任锚。
- 所选信任包内容变化时,kubelet 定期更新
clusterTrustBundle卷源对应的文件。应用必须通过 inotify 或轮询发现变化。 - 每张证书到达
beginRefreshAt时间后,kubelet 重复第2步的流程,刷新证书,并把更新后的私钥和证书链写入文件系统。与第5步一样,应用必须通过 inotify 或轮询发现更新。
几个关键要点:
- 机制内置自动轮换,应用必须正确处理轮换。未来随 Kubernetes 核心提供的签名者将签发最长有效期24小时的证书;其他签名者允许的最长有效期为91天。
- 为简化轮换支持,kubelet 可以把私钥和证书链写到单个凭据包(credential bundle)文件中。应用只需监听该文件的 inotify 事件,或者轮询,读取并使用内容。也支持把私钥和证书链写到不同文件,但应用必须谨慎处理在轮换过程中读取文件的竞态风险。
- 安全检查尽可能内置于 kube-apiserver,减少签名者和应用开发者的负担。例如,内置节点限制准入插件实施节点隔离,确保被攻陷的节点不能通过为不在本节点上的 Pod 申请证书来扩大访问范围。
动手尝试
Kubernetes 项目尚未在核心中提供 Pod 证书签名者,因此尝试这些功能需要在集群里安装第三方签名者。作者编写了 Tinycert,方便把它安装到真实集群或 Kind 集群中。
Tinycert 不是完整的生产方案,但适合开始实验 Pod 证书,也可以作为开发自己签名者的基础。
Tinycert 提供:
- ahmedtd.github.io/tinycert-service 签名者,为 Pod 所属的所有 Kubernetes Service 的 DNS 名称签发带 DNS SAN 的证书。
- ahmedtd.github.io/tinycert-spiffe 签名者,签发兼容 SPIFFE、标识 Pod 命名空间与服务账号的证书。它们既可用于客户端,也可经过适配用于服务器。
- Go 库 github.com/ahmedtd/tinycert/lib/spiffefsd,帮助应用从SPIFFE 文件系统交付草案标准规定的目录加载 SPIFFE 证书和信任包,并正确配置 Go TLS 库的客户端与服务器认证。
- 一个客户端与服务器示例,使用双向 TLS 和 SPIFFE 证书通信。
接下来做什么?
- 阅读Pod 证书和集群信任包文档。
- 审阅并反馈SPIFFE 文件系统交付标准草案,它希望让原生 Kubernetes 中直接使用 SPIFFE 证书变得尽可能简单。
- 参与 Kubernetes SIG Auth,共同塑造未来直接内置于核心的签名者。
- 尝试基于 Tinycert 构建自己的签名者。
祝探索愉快!
来源与版权
原文作者:Taahir Ahmed,Kubernetes Blog,2026-08-28。© 2026 The Kubernetes Authors。文档采用 CC BY 4.0。本文为中文翻译,签发流程错位片段的归位已注明;保留原文与许可链接。 阅读原文。











暂无评论内容