摘要:从 X.509、私钥和 CSR 理解 Kubernetes 客户端证书认证,掌握 CertificateSigningRequest 的创建、审批、签发与证书生命周期管理。
1. 为什么 Kubernetes 需要 CSR?
先看一个实际场景。
假设公司有一个 Kubernetes 集群,现在新加入一名开发人员 Alice。
公司希望:
- Alice 使用自己的身份访问集群。
- Alice 不能使用管理员的证书。
- Alice 只能访问
devNamespace。 - Alice 可以查看和管理指定的业务资源。
- 管理员能够控制证书的签发。
这时候就需要证书签发机制。
传统方式可能是管理员直接使用 CA 私钥签发证书,然后把证书发给 Alice。
但是在 Kubernetes 中,还可以使用内置的 CSR API 对证书申请进行统一管理。
整个流程如下:
flowchart TB
A["Alice 本地生成私钥与 CSR<br/>私钥自行保管"] -->|"只提交 CSR"| C["API Server<br/>CertificateSigningRequest 对象"]
M["管理员审核"] -->|"批准申请"| C
C -->|"获准后由签名控制器处理"| S["Certificate Controller / Signer"]
S -->|"使用 CA 签名并写入 status.certificate"| C
C -->|"读取签发后的证书"| R["Alice 获取客户端证书"]
R --> K["配置 kubeconfig<br/>使用证书和私钥访问 API Server"]
这里有一个核心概念:
CSR 负责申请证书,CA 负责签发证书,kubeconfig 负责使用证书。
注意,CSR 本身不是证书,也不包含客户端私钥。
2. 先理解 X.509 证书的基本原理
2.1 什么是公钥和私钥?
非对称加密体系中有一对密钥:
- Private Key:私钥。
- Public Key:公钥。
它们之间具有数学关联,但不能根据公钥实际推导出私钥。
在 Kubernetes 客户端证书认证中:
- Alice 自己生成私钥。
- Alice 将公钥包含在 CSR 中。
- CA 对 CSR 审核后签发证书。
- Alice 使用私钥和签发证书访问 API Server。
私钥始终由 Alice 自己保管,不需要交给 CA。
2.2 什么是 CSR?
CSR 全称:
Certificate Signing Request它是一份证书签名请求文件,通常采用 PEM 编码。
CSR 主要包含:
| 字段 | 含义 |
|---|---|
| Subject | 申请者身份信息 |
| Public Key | 申请者公钥 |
| Attributes / Extensions | 可选的证书请求扩展 |
| Signature | 申请者对请求内容的签名 |
例如:
Subject: CN=alice O=developers这里:
- CN:Common Name,通常映射为 Kubernetes 用户名。
- O:Organization,通常映射为 Kubernetes 用户组。
因此,当 Alice 的证书被 Kubernetes API Server 接受时,可能被识别为:
username: alice
groups: - developers - system:authenticated注意:证书中的 CN 和 O 是身份声明,证书签发本身不等于授予 RBAC 权限。最终能够做什么仍然由 Kubernetes 授权机制决定。
2.3 什么是 CA?
CA 全称:
Certificate Authority中文叫证书颁发机构。
CA 负责:
- 验证证书申请。
- 使用 CA 私钥对证书签名。
- 生成签发后的客户端证书。
Kubernetes kubeadm 集群通常会有:
/etc/kubernetes/pki/查看:
ls -l /etc/kubernetes/pki/常见文件:
ca.crtca.keyapiserver.crtapiserver.keyapiserver-kubelet-client.crtapiserver-kubelet-client.keyfront-proxy-ca.crtfront-proxy-ca.key重点理解:
| 文件 | 作用 |
|---|---|
| ca.crt | Kubernetes CA 公钥证书 |
| ca.key | Kubernetes CA 私钥 |
| apiserver.crt | API Server 服务端证书 |
| apiserver.key | API Server 服务端私钥 |
其中:
ca.crt可以用于验证由该 CA 签发的证书。ca.key是非常敏感的签名凭据,必须严格保护。
生产环境中绝不能随意复制、分发或暴露 CA 私钥。
3. 私钥与 CSR 示例
3.1 私钥示例
执行:
openssl genrsa -out alice.key 2048这里:
genrsa:生成 RSA 私钥。2048:密钥长度。alice.key:私钥文件。
3.2 生成 CSR
执行:
openssl req -new \ -key alice.key \ -out alice.csr \ -subj "/CN=alice/O=developers"这里:
CN=alice表示 Kubernetes 用户名。
O=developers表示 Kubernetes 用户组。
查看 CSR:
openssl req -in alice.csr -text -noout重点查看:
Subject: CN=alice, O=developers3.3 CSR 签名检查
可以使用:
openssl req -in alice.csr -verify -noout如果输出:
Certificate request self-signature verify OK说明 CSR 自身的签名验证通过。
注意,这只能证明 CSR 的请求签名有效,不能证明申请者身份可信,也不能代表证书已经签发。
4. 将 CSR 提交给 Kubernetes
4.1 CSR 的 Kubernetes API 结构
Kubernetes 使用以下资源:
apiVersion: certificates.k8s.io/v1kind: CertificateSigningRequest创建 CSR 对象需要配置:
| 字段 | 作用 |
|---|---|
| metadata.name | CSR 对象名称 |
| spec.request | Base64 编码的 CSR |
| spec.signerName | 指定证书签名者 |
| spec.usages | 证书用途 |
| spec.expirationSeconds | 请求的证书有效期 |
这里有一个特别重要的字段:
signerName: kubernetes.io/kube-apiserver-client它表示申请的是 Kubernetes API Server 客户端认证证书。
4.2 创建 CSR YAML
首先将 CSR 文件编码为 Base64:
cat alice.csr | base64 -w 0将结果放入 YAML:
apiVersion: certificates.k8s.io/v1kind: CertificateSigningRequestmetadata: name: alice-csrspec: request: BASE64_ENCODED_CSR signerName: kubernetes.io/kube-apiserver-client expirationSeconds: 86400 usages: - client auth注意:
request 必须填写完整的 Base64 编码内容,不能直接填写 CSR 文件路径。
这里:
expirationSeconds: 86400表示请求 24 小时有效期。
实际签发的证书有效期还受签名者及集群配置约束。
5. 批准 CSR 并签发证书
CSR 提交后,默认并不意味着证书已经签发。
管理员需要审核申请,并决定是否批准。
5.1 查看 CSR 详细信息
kubectl describe csr alice-csr可以看到:
Name: alice-csrSignerName: kubernetes.io/kube-apiserver-clientStatus: Conditions: Type: Approved如果尚未批准,通常显示:
Pending5.2 批准证书申请
执行:
kubectl certificate approve alice-csr这里需要区分两个状态:
- Approved:管理员已经批准申请。
- Issued:签名者已经完成证书签发。
批准和签发是两个不同的动作。批准后,配置正确的签名控制器会负责签发证书。
5.3 Kubernetes 如何完成证书签发?
这里涉及 Kubernetes Controller Manager。
在 kubeadm 集群中,可以查看:
cat /etc/kubernetes/manifests/kube-controller-manager.yaml关注证书相关参数:
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key它们分别指定:
- CA 证书。
- CA 私钥。
对于受支持的内置 signer,证书签名控制器会在 CSR 获得批准后,根据签名者策略完成签发。
注意:并非所有 CSR 都会自动批准。普通用户客户端证书通常需要管理员审核。Kubernetes 内置的 CSR 审批控制器对特定类型的节点证书有专门的自动审批逻辑,不能理解为所有申请都会自动通过。
5.4 获取签发后的证书
查看 CSR 对象:
kubectl get csr alice-csr -o yaml重点关注:
status: certificate: LS0tLS1CRUdJTi...这个字段就是 CA 签发后的客户端证书,采用 Base64 编码。
提取证书:
kubectl get csr alice-csr \ -o jsonpath='{.status.certificate}' \ | base64 -d > alice.crt它们的关系:
| 文件 | 来源 | 作用 |
|---|---|---|
| alice.key | Alice 本地生成 | 客户端私钥 |
| alice.csr | Alice 本地生成 | 证书申请 |
| alice.crt | Kubernetes 签发 | 客户端证书 |
其中,真正用于客户端证书认证的是:
alice.crt + alice.keyCSR 在证书签发完成后不需要继续参与日常 API 请求。
5.5 证书信息与信任链检查
使用 OpenSSL 查看证书:
openssl x509 -in alice.crt -text -noout查看身份:
openssl x509 -in alice.crt \ -noout -subject查看有效期:
openssl x509 -in alice.crt \ -noout -dates验证证书是否由 Kubernetes CA 签发:
openssl verify \ -CAfile /etc/kubernetes/pki/ca.crt \ alice.crt如果你不是在控制平面节点上操作,需要先安全地获取对应 CA 公共证书 ca.crt,不需要也不应该获取 CA 私钥。
6. CSR 的生命周期与证书安全管理
证书不是永久有效的,生产环境必须考虑证书生命周期。
6.1 证书过期
查看证书有效期:
openssl x509 -in alice.crt -noout -dates例如:
notBefore=Nov 2 08:00:00 2026 GMTnotAfter=Nov 3 08:00:00 2026 GMT到达 notAfter 后,证书就不再有效。
客户端继续使用过期证书访问 API Server,通常会出现认证失败。
6.2 如何续期或轮换证书?
基本流程:
- Alice 生成新的私钥。
- 使用新私钥生成 CSR。
- 提交新的 Kubernetes CSR。
- 管理员审核批准。
- 获取新证书。
- 更新 kubeconfig。
- 验证新凭据。
- 停止使用旧凭据。
这里建议使用新私钥重新申请,而不是无条件重复使用旧私钥。
6.3 Kubernetes 是否支持直接吊销客户端证书?
这里需要特别注意。
Kubernetes 内置的 X.509 客户端证书认证机制,并没有提供一个通用的 kubectl revoke certificate 命令来即时吊销某张客户端证书。
也就是说:
删除 CSR 对象,并不会让已经签发的证书自动失效。
对于已经泄露的客户端证书,可以考虑:
- 删除或调整对应用户的 RBAC 绑定,立即限制其授权权限。
- 对证书签发体系进行密钥轮换,更新信任链。
- 根据组织的 PKI 架构,通过支持吊销检查的认证基础设施处理证书吊销。
- 对相关身份进行审计,检查是否已经发生异常访问。
还有一个重要区别:
删除 RoleBinding,只是取消对应授权,并不是撤销证书本身。证书仍可能被 API Server 识别为 Alice,但如果没有其他授权,正常资源请求会被拒绝。
6.4 CSR 的删除
查看:
kubectl get csr删除:
kubectl delete csr alice-csr这只是删除 Kubernetes 中的 CSR 申请对象及其保存的签发结果,不等于吊销已经分发出去的证书。
6.5 生产环境的证书管理建议
| 管理项目 | 建议 |
|---|---|
| 私钥 | 由申请者安全生成和保存 |
| CA 私钥 | 严格限制访问,最好独立保护 |
| 证书有效期 | 设置合理的有效期限 |
| CSR 审核 | 普通用户证书实行人工或受控审批 |
| 证书轮换 | 提前规划,避免过期中断 |
| 身份授权 | 通过 RBAC 独立控制 |
| 凭据泄露 | 及时移除权限并处理信任链 |
| 审计 | 记录申请、批准、签发和使用情况 |
7. Kubernetes 内置 CSR Signer
API Server 客户端证书使用:
signerName: kubernetes.io/kube-apiserver-client但 Kubernetes 不只有这一种证书签名类型。
常见内置 Signer:
| SignerName | 用途 |
|---|---|
kubernetes.io/kube-apiserver-client | API Server 客户端认证证书 |
kubernetes.io/kube-apiserver-client-kubelet | kubelet 客户端认证证书 |
kubernetes.io/kubelet-serving | kubelet 服务端证书 |
kubernetes.io/legacy-unknown | 历史签名类型,certificates.k8s.io/v1 不允许使用 |
7.1 kube-apiserver-client
主要用于普通客户端访问 API Server。
例如:
alice.crt它的证书身份可以是:
CN=aliceO=developers7.2 kube-apiserver-client-kubelet
主要用于 kubelet 作为客户端访问 API Server。
例如:
system:node:worker-01通常属于:
system:nodes它与 Kubernetes 的 Node Authorizer、NodeRestriction 等安全机制配合使用。
7.3 kubelet-serving
用于 kubelet HTTPS 服务端认证。
例如:
当其他组件需要通过 HTTPS 访问 kubelet 的服务端口时,需要验证 kubelet 的服务端证书。
它与 kubelet 客户端证书的用途不同:
- Client Certificate:证明客户端是谁。
- Serving Certificate:证明服务器是谁。
7.4 CSR 的 usages
证书用途也很重要。
例如:
usages: - digital signature - key encipherment - client auth常见用途:
| Usage | 含义 |
|---|---|
| digital signature | 数字签名 |
| key encipherment | 密钥加密 |
| client auth | 客户端身份认证 |
| server auth | 服务端身份认证 |
| key agreement | 密钥协商 |
对于普通 Kubernetes API 客户端证书,通常需要:
usages: - digital signature - key encipherment - client auth其中具体允许的用途还受 signer 策略约束,不能随意组合。
8. CSR 常用管理命令
CSR 管理命令:
| 命令 | 作用 |
|---|---|
kubectl get csr | 查看 CSR |
kubectl describe csr | 查看 CSR 详细信息 |
kubectl certificate approve | 批准 CSR |
kubectl certificate deny | 拒绝 CSR |
kubectl delete csr | 删除 CSR |
kubectl get csr -o yaml | 查看 CSR 完整配置 |
注意:批准、拒绝和读取 CSR 都需要相应的 Kubernetes API 权限。普通用户并不天然具有这些操作权限。
参考资料: