是的,Kubernetes 的 CertificateSigningRequest(CSR)机制可以完全实现为用户生成受限 kubeconfig 的功能,并且是更推荐的做法。相比手动使用 OpenSSL 生成证书的方式,CSR 提供了更安全、更规范的流程,尤其适合生产环境。

✅ 使用 CSR 的优势
无需手动访问 CA 私钥
用户提交 CSR 后,由集群管理员通过 Kubernetes API 审批并签署证书,避免了直接暴露集群的 CA 私钥。

集成 RBAC 和权限管理
CSR 资源本身是 Kubernetes API 的一部分,可以与集群的 RBAC 系统无缝集成。

可审计的证书生命周期
所有 CSR 操作(提交、批准、拒绝)都会记录在 Kubernetes 的事件日志中,方便审计和追踪。

🛠️ 使用 CSR 实现受限 kubeconfig 的步骤

  1. 生成私钥和 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),用于后续权限绑定

  1. 创建 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
  1. 集群管理员批准 CSR
    集群管理员批准请求:
kubectl certificate approve user-csr

查看状态:

kubectl get csr user-csr

等待状态变为 Approved,Issued。

  1. 获取生成的证书
    提取批准后的证书:
kubectl get csr user-csr -o jsonpath='{.status.certificate}' | \
  openssl base64 -d -A -out user.crt
  1. 配置 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
  1. 生成 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