在 Kubernetes 集群中创建用户账号时,通常会使用 kubeconfig 文件来进行认证和授权,其中 CertificateSigningRequest 对象提供了一种通过提交证书签名请求并异步批准和颁发 x509 证书的机制。

  • 系统环境:Anolis OS release 8.8
  • 内核版本:Linux Kernel 5.10.134-13.an8.x86_64
  • Kubernetes 版本:v1.28.3

创建证书签名请求

1、创建用户证书私钥

mkdir user1 && cd user1
openssl genrsa -out user1.key 2048
openssl req -new -key user1.key -out user1.csr -subj "/CN=user1/O=xiaomi"

2、创建证书签名请求文件 user1.csr 对应的 k8s 资源

# 对证书签名请求文件 user1.csr 进行 base64 编码
cat user1.csr | base64 | tr -d "\n"

kubectl apply -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: user1
spec:
  groups:
  - system:authenticated
  request:  LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1pqQ0NBVTRDQVFBd0lURU9NQXdHQTFVRUF3d0ZkWE5sY2pFeER6QU5CZ05WQkFvTUJuaHBZVzl0YVRDQwpBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUxkNWpTNDl3eVRxT29DMmpnVnIxM1Y0CktPOVFLR3NaZE1vNGdsTFdTeE81SDJ5VHZFTmxhbmZkUm9QOVprb2k0V0xUbzFKU2VDNnZNRmxKdVoxYlM4dUMKZHBlREZ6LzRHREI4ZThBU1VOSHVDaEh4Zi84dlJLWGFvWS9oS282Lzl3ZVFZd05ZcHM3enBmOHJDN3NLcXc0KwpIYmxvR2V5SHVGaTQ5cmxsYVlISElLRm1IcTgrSTBRbW9hQ0pBOTRIRyt5K2NVZk9xMGVGQkxVbGhrZXlmam1FCmRwUVhSU1lqb21mdXFlOURsQzZmeFRSelBVM2trM0VUNEt0NlhCcmNqQmY4SGlYVUYzWFE3Sisrb044YTkwWWYKemZYVng0dklKTFBJdXoyWHNHYksySWVhVHFpUGJEWUR1YlEvcGs0dS9UOUV2Zy9XMnR4VElLZzFNcDhZdWVFQwpBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQndocU93a1MvQ2NGNS84K2FINXRKOGY4RDZjMEJoCnphTEtJTTdHeCt3WjN4STNZT0IvWFQzVFVHTGNLM2RTT3ZHUmIwZzZ6L0ozMTdKVG15aTNsaWhFNDNSSjkybDAKNEorT1A2Q0lDZXJEZWNhbGo3c3ovdkRLaU8zeEhvbFZUci9Db1FvMXQ1WmlQa1h5UHhiRmpSVUlFcnpJRkVKYQpGL1A0NnhLOHdYSzZlT3RnVnhhTUdyZlR2R3VFQ3NnTncvSlQrY1JEUXZxbWNPK1RJVktJOXZKQzl4RVlxZGRQCnFxNC9EY05CQk1FMTV3cllTVEx4a0dLQzRzaU53VW43OEVXS1dOK000ZFNTemZ5TFJXOGZiSnBEUG5PeFFpMHoKWHpkZGVpOE45d0duRFdvT2hhaVkrS2VqLzQxNjVHTGQyTktEZmpwVndSbW9Eb3lEVjlVdEx3NkUKLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
  usages:
  - client auth
  signerName: kubernetes.io/kube-apiserver-client
EOF

# request 字段值为证书签名请求文件的 base64 编码

spec.signerName 在 certificates.k8s.io/v1 之后的 API 版本是必填项。 在 Kubernetes v1.22 和以后的版本,客户可以可选地设置 spec.expirationSeconds 字段来为颁发的证书设定一个特定的有效期。该字段的最小有效值是 600,也就是 10 分钟

垃圾收集器会清除在一段时间内没有改变过状态的 CertificateSigningRequests: 已批准、拒绝、失败的请求将在 1 小时后自动删除,挂起的请求则在 24 小时后自动删除,所有请求颁发的证书过期后自动删除

创建证书

1、查看证书申请

kubectl get csr -o wide
#> NAME    AGE     SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
#> user1   4m53s   kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Pending

2、集群管理员手动批准证书申请

kubectl certificate approve user1

kubectl get csr -o wide
#> NAME    AGE     SIGNERNAME                            REQUESTOR          REQUESTEDDURATION   CONDITION
#> user1   5m47s   kubernetes.io/kube-apiserver-client   kubernetes-admin   <none>              Approved,Issued

创建完成的 CertificateSigningRequest,要先通过批准,然后才能签名。 根据所选的签名者,CertificateSigningRequest 可能会被 控制器自动批准。 否则,就必须人工批准, 人工批准可以使用 REST API(或 go 客户端),也可以执行 kubectl certificate approve 命令

3、导出证书到文件

kubectl get csr/user1 -o jsonpath='{.status.certificate}' | base64 -d > user1.crt

ls
#> user1.crt  user1.csr  user1.key

对于已批准的证书,下一步是签名。 对应的签名控制器首先验证签名条件是否满足,然后才创建证书。 签名控制器然后更新 CertificateSigningRequest, 将新证书保存到现有 CertificateSigningRequest 对象的 status.certificate 字段中

创建 kubeconfig 文件

# 设置集群字段,--embed-certs=true 把 CA 证书内容写入到此 kubeconfig 文件里
cp /etc/kubernetes/pki/ca.crt .
kubectl config --kubeconfig=kubeconfig-user1 set-cluster cluster-01 --server=https://192.168.31.31:6443 --certificate-authority=ca.crt --embed-certs=true

# 设置用户字段
kubectl config --kubeconfig=kubeconfig-user1 set-credentials user1 --client-certificate=user1.crt --client-key=user1.key --embed-certs=true

# 设置一个名为 context 的上下文字段
kubectl config --kubeconfig=kubeconfig-user1 set-context context --cluster=cluster-01 --namespace=default --user=user1

# 设置当前上下文为 context
kubectl config --kubeconfig kubeconfig-user1 use-context context

添加用户授权

1、为用户 user1 授予集群超级管理员权限 cluster-admin

# 认证通过,但提示无权限
kubectl get nodes --kubeconfig=kubeconfig-user1
#> Error from server (Forbidden): nodes is forbidden: User "user1" cannot list resource "nodes" in API group "" at the cluster scope

# 创建名为 user1 的集群角色绑定,并将集群角色 cluster-admin 绑定到用户 user1 实现授权
kubectl create clusterrolebinding user1 --clusterrole=cluster-admin --user=user1

kubectl get nodes --kubeconfig=kubeconfig-user1  -o wide
#> NAME   STATUS   ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE        KERNEL-VERSION           CONTAINER-RUNTIME
#> c1     Ready    control-plane   3d16h   v1.28.3   192.168.31.31   <none>        Anolis OS 8.8   5.10.134-13.an8.x86_64   containerd://1.7.8
#> c2     Ready    <none>          3d16h   v1.28.3   192.168.31.32   <none>        Anolis OS 8.8   5.10.134-13.an8.x86_64   containerd://1.7.8
#> c3     Ready    <none>          3d16h   v1.28.3   192.168.31.33   <none>        Anolis OS 8.8   5.10.134-13.an8.x86_64   containerd://1.7.8

# 查看集群角色 cluster-admin 具有哪些 kube-apiserver 操作权限
kubectl -n kube-system get clusterrole cluster-admin -o yaml

2、特定权限检测

# 验证 user1 用户是否具有 list 当前命名空间里的 pod 的权限
kubectl auth can-i list pods --as user1
#> yes

# 验证 user1 用户是否具有 list 命名空间 kube-system 里 pod 的权限
kubectl auth can-i list pods -n kube-system --as user1
#> yes

3、取消授权,即删除集群角色绑定 user1

kubectl delete clusterrolebinding user1

参考

证书签名请求 CertificateSigningRequest

码字不易,若觉得本文对你有用,欢迎点赞 👍、分享 🚀 ,相关技术热点时时看🔥🔥🔥​​​…

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐