“给新同事发一个 kubectl 账号”在 Kubernetes 里是怎么做的?集群里没有 User 对象,身份就写在证书里。这篇把用户证书从私钥、CSR、批准、签发到写进 kubeconfig、被 RBAC 拦下再放行的全过程真跑了一遍,并看了几种得不到证书的情形。
kubectl create csr jane(openssl 生成的 RSA 2048 密钥,Subject CN=jane,O=devs;signerName=kubernetes.io/kube-apiserver-client,expirationSeconds=3600,usages=[client auth]):certificatesigningrequest.certificates.k8s.io/jane created status:conditions=None;certificate=(空);spec.username=kubernetes-admin;spec.groups=['kubeadm:cluster-admins', 'system:authenticated'] kubectl get csr:NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION | jane 0s kubernetes.io/kube-apiserver-client kubernetes-admin 60m Pending 等 3 秒之后 certificate 仍然是 (空)——没有批准就没有人签发
私钥留在用户手里,只有 CSR 交给集群:CertificateSigningRequest 里是 base64 的 CSR、signerName: kubernetes.io/kube-apiserver-client、usages: [client auth] 和 expirationSeconds: 3600。创建后它只是个对象,status 里什么都没有,kubectl get csr 显示 Pending;spec.username 记着是谁提交的。没人批准,等多久都没有证书。
kubectl certificate approve jane:certificatesigningrequest.certificates.k8s.io/jane approved
0.0 秒后 status.certificate 被填上;conditions=[('Approved', 'KubectlApprove')]
subject=O=devs, CN=jane
issuer=CN=kubernetes
notBefore=Oct 10 09:15:20 2026 GMT
notAfter=Oct 10 10:20:20 2026 GMT
X509v3 Extended Key Usage:
TLS Web Client Authentication
notAfter - notBefore = 3900 秒(请求的 expirationSeconds=3600);notBefore 比签发时刻早 300 秒左右kubectl certificate approve jane 之后,controller-manager 里的签名者用集群 CA 签出证书,几乎立刻出现在 status.certificate。证书里 subject=O=devs, CN=jane、issuer=CN=kubernetes、只有 TLS Web Client Authentication 用途。有效期是 3900 秒,不是请求的 3600:notBefore 比签发时刻早了约 300 秒,防止时钟不同步导致刚签的证书“还没生效”。
用 jane 的 kubeconfig:kubectl auth whoami → jane|["devs","system:authenticated"] kubectl get pods -n k21:Error from server (Forbidden): pods is forbidden: User "jane" cannot list resource "pods" in API group "" in the namespace "k21" 给组 devs 绑定 view(RoleBinding 在 k21 命名空间)之后:No resources found in k21 namespace. 同一个用户看 default 命名空间:Error from server (Forbidden): pods is forbidden: User "jane" cannot list resource "pods" in API group "" in the namespace "default" auth can-i delete pods -n k21:no 集群里有 User 对象吗?kubectl get users:error: the server doesn't have a resource type "users"——用户只存在于证书里
把证书和私钥写进独立的 kubeconfig:whoami 得到 jane,组是 devs(证书的 O)和 system:authenticated。证书只证明身份,权限一点没有:get pods 是 Forbidden。给组 devs 在 k21 命名空间绑定 view 之后才能列出 Pod,到 default 命名空间仍然被拒,can-i delete pods 是 no。kubectl get users 报 the server doesn't have a resource type "users"——集群里没有 User 对象,所以要撤销一个用户只能等证书过期或撤销它的权限。
kubectl certificate deny bob:certificatesigningrequest.certificates.k8s.io/bob denied;conditions=[('Denied', 'KubectlDeny')];certificate=(空)
signerName=example.com/my-signer(没有任何组件负责签)被 approve 之后 5 秒:conditions=['Approved'];certificate=(空)
kubernetes.io/kube-apiserver-client 却申请 usages=[server auth]:创建时退出码 0;certificatesigningrequest.certificates.k8s.io/dave created
approve 之后 4 秒:conditions=[('Approved', 'KubectlApprove', 'This CSR was approved by kubectl certificate approve.'), ('Failed', 'SignerValidationFailure', 'invalid usage for client certificate: server auth')];certificate=(空)
kubectl get csr jane bob carol dave:NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION | jane 13s kubernetes.io/kube-apiserver-client kubernetes-admin 60m Approved,Issued | bob 10s kubernetes.io/kube-apiserver-client kubernetes-admin 60m Denied | carol 9s example.com/my-signer kubernetes-admin 60m Approved | dave 4s kubernetes.io/kube-apiserver-client kubernetes-admin 60m Approved,Faileddeny 的 CSR 变成 Denied,没有证书;signerName 是 example.com/my-signer 的 CSR 即使被 approve 也没有人签(内置签名者只处理 kubernetes.io/*);kube-apiserver-client 却申请 server auth 用途,创建时能通过,approve 之后才出现 Failed: SignerValidationFailure — invalid usage for client certificate: server auth。排查“批准了却没有证书”先看 conditions。