为了让普通用户能够通过认证并调用 API,需要执行几个步骤。 首先,该用户必须拥有 Kubernetes 集群签发的证书, 然后将该证书提供给 Kubernetes API。
创建私钥
下面的脚本展示了如何生成 PKI 私钥和 CSR。 设置 CSR 的 CN 和 O 属性很重要。CN 是用户名,O 是该用户归属的组。 你可以参考 RBAC 了解标准组的信息。
openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
创建 CertificateSigningRequest
创建一个 CertificateSigningRequest, 并通过 kubectl 将其提交到 Kubernetes 集群。 下面是生成 CertificateSigningRequest 的脚本。
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:name: myuser
spec:request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1pUQ0NBVTBDQVFBd0lERVBNQTBHQTFVRUF3d0diWGwxYzJWeU1RMHdDd1lEVlFRS0RBUmhjSEF4TUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeWRKSVc1WUlFV0dnaVZjWE1IWXNFR2dNCmVuSXBDQ3d5RjByNXpaNWdPU3kvUTR6dTFsamFIaFovbGhPMDVOeGUvbnBzMm1QUDdTVWxpOUhCUHlLeXVWdS8KNTIzN2VGQU9XbVhEcjJlOEtEZXkwK05vV0xxTWVRZitjeVlyL3ZmcytPTW50MHJPOFhjdTlSZjJWc2V0VjJ5ZAo4VTlkS2F0R3ZlVk85QVVveUIvRldCRTVTV2h4WmVMQTc5b2d5VGw5amdYK0FvTitmVmVmWUFHb3c4ZURKekliCnIrTTFjM3g5WlcxMlZZNU5qM3hiVXRaSWpoRVRneElvOUU0Sit1ajhub0pHMm5UOXlpQ3k0ZmEvMTg5Y08wS2wKQkZENUNKMjJuNGxNcnpINmxHK0VlRFl1bk5wN3czVWtMeTM0MmVCUTRJT2RxRllueVl3bWxBV2VaUXZ5ZXdJRApBUUFCb0FBd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFJc2szOHlGMnJ3LzBuT0MwZXUxMFZoYWhqcURPWGlmCnZxYm5DK0hjNzB4OGxaZDdFNSs0L1hYVDNhVDloZTVzbU9melFiUHJiYi92QzE3U1JkTjlIM0V3SUJ6WDZvcEoKeWZSQmgwRVEvYmlaRzRnVWFzM3dvcGF4Njk5REdUejRBQ1BDYlV5T1RYaXk0OGN1SWJFbHg0UlhKWXRLVko4VwpUdW5ObXJTU1FabFhKTjNweUlpM0FYVmltNVZaajZUN3FiTHVjRmpBbmcxcG1RM254MDRGdkJpTUxURFUvSDFhCkxtSTdYM3NSeVdQa3FocXh4Z244Rk9POFBTNUlCYUR6SVdBeWxhdktBNUR5WVZLdE5RUVhuYzV3aHorY1o0eEYKNmk4b0dLQVpKUFcvdmxmaWRLaFYzQmdTVXFyd1lHMm81RysweTVvUkg5UUJHc0xwcE9hamwzQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==signerName: kubernetes.io/kube-apiserver-clientexpirationSeconds: 86400 # one dayusages:- client auth
EOF
需要注意的几点:
-
usage
字段必须是 ‘client auth
’ -
expirationSeconds
可以设置为更长(例如864000
是十天)或者更短(例如3600
是一个小时) -
request
字段是 CSR 文件内容的 base64 编码值, 要得到该值,可以执行命令:cat myuser.csr | base64 | tr -d "\n"
批准 CertificateSigningRequest
使用 kubectl 创建 CSR 并批准。
获取 CSR 列表:
kubectl get csr
批准 CSR:
kubectl certificate approve myuser
取得证书
从 CSR 取得证书:
kubectl get csr/myuser -o yaml
证书的内容使用 base64 编码,存放在字段 status.certificate
。
从 CertificateSigningRequest 导出颁发的证书:
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
创建角色和角色绑定
创建了证书之后,为了让这个用户能访问 Kubernetes 集群资源,现在就要创建 Role 和 RoleBinding 了。
下面是为这个新用户创建 Role 的示例命令:
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
下面是为这个新用户创建 RoleBinding 的示例命令:
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
添加到 kubeconfig
最后一步是将这个用户添加到 kubeconfig 文件。
首先,你需要添加新的凭据:
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true --kubeconfig=config
创建对应的集群:
kubectl config set-cluster mycluster --server="https://192.168.188.101:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=config
然后,你需要添加上下文:
kubectl config set-context myuser --cluster=mycluster --user=myuser --kubeconfig=config
来测试一下,把上下文切换为 myuser
:
kubectl config use-context myuser --kubeconfig=config
测试最终效果
[root@k8s-master01 projects]# kubectl get pod --kubeconfig=config
NAME READY STATUS RESTARTS AGE
dapi-test-pod 0/1 Completed 0 2d23h
from-env-file-pod 1/1 Running 0 2d23h
from-file-pod 1/1 Running 0 3d
kubernetes-bootcamp-f95c5b745-7qxbx 1/1 Running 0 10d
kubernetes-bootcamp-f95c5b745-7wfjp 1/1 Running 0 10d
kubernetes-bootcamp-f95c5b745-jwhjl 1/1 Running 0 10d
kubernetes-bootcamp-f95c5b745-rmvjq 1/1 Running 0 10d
nginx-web 1/1 Running 0 7d5h
task-pv-deployment-5866dbb7cc-78mvk 1/1 Running 0 9d
task-pv-deployment-5866dbb7cc-cr5rx 1/1 Running 0 9d
task-pv-deployment-5866dbb7cc-g42bc 1/1 Running 0 9d
task-pv-deployment-5866dbb7cc-nlfnd 1/1 Running 0 9d
task-pv-deployment-5866dbb7cc-p9t29 1/1 Running 0 9d
task-pv-deployment-5866dbb7cc-tbp4v 1/1 Running 0 9d
task-pv-pod 1/1 Running 0 9d
task-pv-pod2 1/1 Running 0 9d
[root@k8s-master01 projects]# kubectl get ns --kubeconfig=config
Error from server (Forbidden): namespaces is forbidden: User "myuser" cannot list resource "namespaces" in API group "" at the cluster scope