本文最后更新于145 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1. 创建用户证书和私钥
# 生成私钥
openssl genrsa -out shaman-user.key 2048
# 创建证书签名请求 (CSR)
openssl req -new -key shaman-user.key -out shaman-user.csr \
-subj "/CN=shaman-user/O=shaman-group"
# 使用集群 CA 签署证书 (需要访问集群 CA)
openssl x509 -req -in shaman-user.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial -out shaman-user.crt -days 3650
# 生产环境或者说无法调用/etc/kubernetes/pki/目录下的文件时,推荐使用k8s集群自带的csr
# Base64 编码 CSR
CSR_BASE64=$(cat shaman-user.csr | base64 | tr -d '\n')
# 创建 CSR YAML 文件
cat <<EOF > shaman-csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: shaman-user-csr
spec:
request: $CSR_BASE64
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 2592000 # 30天有效期
usages:
- client auth
EOF
# 应用 CSR
kubectl apply -f shaman-csr.yaml
# 批准 CSR(需要管理员权限)
kubectl certificate approve shaman-user-csr
# 等待证书签发(通常几秒钟)
kubectl get csr shaman-user-csr -w
# 当状态变为 Approved,Issued 时继续
# 获取签发的证书
kubectl get csr shaman-user-csr -o jsonpath='{.status.certificate}' | base64 -d > shaman-user.crt
#如果不执行这个命令:
#无法认证:kubectl 没有证书文件用于 TLS 握手
#API Server 拒绝连接:返回 x509: certificate signed by unknown authority
#RBAC 权限失效:即使用户在 RBAC 中定义,也无法识别身份

在 Kubernetes 中,shaman-user 不是预创建的资源,而是一个在 RBAC 系统中通过证书标识的抽象用户。它的工作原理如下:
subjects:
- kind: User
name: shaman-user # 这个用户名来自证书的 CN (Common Name)
apiGroup: rbac.authorization.k8s.io
认证流程:
-
证书创建:使用 OpenSSL 创建证书时指定用户标识
openssl req -new -key shaman-user.key -out shaman-user.csr \ -subj "/CN=shaman-user/O=shaman-group" # CN 定义用户名 -
API Server 验证:
- 客户端使用证书连接 API Server
- API Server 验证证书签名(使用集群 CA)
- 提取证书中的
CN=shaman-user作为用户名 - 提取证书中的
O=shaman-group作为用户组
关键特点:
- 非存储对象:
User不像 Pod 或 Service 存储在 etcd 中 - 证书绑定:用户身份完全由客户端证书的 CN 字段定义
- 无密码:不需要在集群中创建用户账户
- 即时生效:只要证书有效,用户立即获得权限
也可以给整租授权,而不是单个用户:
subjects:
- kind: Group
name: shaman-group
apiGroup: rbac.authorization.k8s.io
2. 创建 RBAC 配置
# shaman-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: shaman
namespace: backend
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["autoscaling"]
resources: ["horizontalpodautoscalers"]
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
# shaman-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: shaman-binding
namespace: backend
subjects:
- kind: User
name: shaman-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: shaman
apiGroup: rbac.authorization.k8s.io
3. kubeconfig 文件脚本
# 查看当前上下文配置
kubectl config current-context
# 查看上下文详细信息
kubectl config get-contexts
# 查看所有集群定义
kubectl config get-clusters
# 查看完整配置
kubectl config view
# 设置变量
CLUSTER_NAME=$(kubectl config view --minify -o jsonpath='{.clusters[0].name}')
CONTEXT_NAME="shaman-backend-context"
USER_NAME="shaman-user"
NAMESPACE="backend"
# 获取集群信息
CLUSTER_SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
CLUSTER_CA_CERT=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
# 创建 kubeconfig
kubectl config set-cluster $CLUSTER_NAME \
--server=$CLUSTER_SERVER \
--certificate-authority=<(echo $CLUSTER_CA_CERT | base64 -d) \
--embed-certs=true \
--kubeconfig=shaman-config
kubectl config set-credentials $USER_NAME \
--client-certificate=shaman-user.crt \
--client-key=shaman-user.key \
--embed-certs=true \
--kubeconfig=shaman-config
kubectl config set-context $CONTEXT_NAME \
--cluster=$CLUSTER_NAME \
--user=$USER_NAME \
--namespace=$NAMESPACE \
--kubeconfig=shaman-config
kubectl config use-context $CONTEXT_NAME \
--kubeconfig=shaman-config
验证:
# 将 shaman 配置合并到默认配置,也可不合并,使用时直接切换,或者linux中创建user,放在他的家目录下
# 1. 备份当前配置文件
cp ~/.kube/config ~/.kube/config.backup-$(date +%Y%m%d)
# 2. 合并配置文件(使用临时文件)
KUBECONFIG=~/.kube/config:shaman-config kubectl config view \
--merge --flatten > config.tmp
# 3. 验证新配置
kubectl --kubeconfig=config.tmp config view
# 4. 替换配置文件
mv config.tmp ~/.kube/config
# 切换上下文
kubectl config use-context shaman-backend-context # 切换到 shaman 用户
注意事项
-
CSR 批准权限:
# 检查批准权限 kubectl auth can-i create certificatesigningrequests kubectl auth can-i approve certificatesigningrequests -
证书自动清理:
-
已批准的 CSR 不会自动删除
-
手动清理旧 CSR:
kubectl delete csr shaman-user-csr
-
-
证书续期:
- 证书到期前需要重新申请
- 自动化脚本示例:
#!/bin/bash
# 续期证书
renew_cert() {
USER=$1
GROUP=$2
# 重新生成 CSR
openssl req -new -key ${USER}.key -out ${USER}.csr -subj "/CN=${USER}/O=${GROUP}"
CSR_BASE64=$(cat ${USER}.csr | base64 | tr -d '\n')
# 创建新 CSR 资源...
}