是的,Kubernetes 的 CertificateSigningRequest(CSR)机制可以完全实现为用户生成受限 kubeconfig 的功能,并且是更推荐的做法。相比手动使用 OpenSSL 生成证书的方式,CSR 提供了更安全、更规范的流程,尤其适合生产环境。
✅ 使用 CSR 的优势
无需手动访问 CA 私钥
用户提交 CSR 后,由集群管理员通过 Kubernetes API 审批并签署证书,避免了直接暴露集群的 CA 私钥。
集成 RBAC 和权限管理
CSR 资源本身是 Kubernetes API 的一部分,可以与集群的 RBAC 系统无缝集成。
可审计的证书生命周期
所有 CSR 操作(提交、批准、拒绝)都会记录在 Kubernetes 的事件日志中,方便审计和追踪。
🛠️ 使用 CSR 实现受限 kubeconfig 的步骤
- 生成私钥和 CSR 文件
用户在本地生成私钥和 CSR 文件:
openssl genrsa -out user.key 2048
openssl req -new -key user.key -out user.csr -subj "/CN=user-name/O=group-name"
CN:用户名(例如 user1)
O:用户所属的组(例如 dev-team),用于后续权限绑定
- 创建 Kubernetes CSR 资源
将 CSR 文件转换为 Kubernetes 的 CertificateSigningRequest 资源:
kubectl create -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: user-csr
spec:
request: $(cat user.csr | base64 | tr -d '\n')
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 36000 # 有效期(秒)
usages:
- digital signature
- key encipherment
- client auth
EOF
- 集群管理员批准 CSR
集群管理员批准请求:
kubectl certificate approve user-csr
查看状态:
kubectl get csr user-csr
等待状态变为 Approved,Issued。
- 获取生成的证书
提取批准后的证书:
kubectl get csr user-csr -o jsonpath='{.status.certificate}' | \
openssl base64 -d -A -out user.crt
- 配置 RBAC 权限
创建 Role 和 RoleBinding,限制用户只能访问特定 namespace:
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: your-namespace
name: namespace-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "create", "delete"]
# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: your-namespace
name: namespace-rolebinding
subjects:
- kind: User
name: user-name # 与 CSR 中的 CN 字段一致
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: namespace-role
apiGroup: rbac.authorization.k8s.io
应用配置:
kubectl apply -f role.yaml
kubectl apply -f rolebinding.yaml
- 生成 kubeconfig 文件
将证书、私钥和集群信息整合为 kubeconfig 文件:
kubectl config set-cluster k8s-cluster \
--server=https://<master-ip>:6443 \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true
kubectl config set-credentials user-name \
--client-certificate=./user.crt \
--client-key=./user.key \
--embed-certs=true
kubectl config set-context user-context \
--cluster=k8s-cluster \
--user=user-name \
--namespace=your-namespace
kubectl config use-context user-context
kubectl config view --minify --flatten > user-kubeconfig.yaml