基于RBAC的k8s集群权限管控案例

在日常的kubernetes集群维护过程中,常常涉及多团队协作,不同的团队有不同的操作和权限需求。比如,运维团队需要有node的所有操作权限,以便对集群进行节点的扩缩容等日常维护工作,但资产运营团队通常只需要node的查看权限,以便完成资产信息的统计分析即可。当然,在实际的业务场景中,一个团队,到底需要操作什么,允许操作什么,往往比上述例子复杂的多。为了应对实际业务场景中的复杂权限管控诉求,kubernetes提供了基于RBAC的权限管控机制。

接下来,将通过一个实践例子,逐步实现一个权限管理目标:资产运营团队仅能查看node信息,不能查看和操作其他对象。

Step1:创建serviceAccount

创建名为serviceAccount.yaml的文件,内容如下:

yaml 复制代码
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test
  namespace: default

创建并查看serviceAccount:

复制代码
$ kubectl create -f serviceAccount.yaml
$ kubectl get serviceAccout | grep test

获取serviceAccount的信息:

复制代码
$ kubectl get serviceAccount test -o yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2023-12-08T03:13:05Z
  name: test
  namespace: default
  resourceVersion: "99773705"
  selfLink: /api/v1/namespaces/default/serviceaccounts/test
  uid: c2db455c-57d4-11ec-b464-848f69e3eeb4
secrets:
- name: test-token-wvmkx

从上述输出的信息中,能够获得其对应的secret名称为test-token-wvmkx。通过secret名称能获得对应的token:

复制代码
$ kubectl describe secret test-token-wvmkx

Name:         test-token-wvmkx
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=test
              kubernetes.io/service-account.uid=c2db455c-57d4-11ec-b464-848f69e3eeb4

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtdG9rZW4td3Zta3giLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImMyZGI0NTVjLTU3ZDQtMTFlYy1iNDY0LTg0OGY2OWUzZWViNCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QifQ.cdzShIX7IJj2sLS8h_LNpIRiDF8mXkex7GgPQUUxTbKFZ0cIZbMt5zDpxH4NN4XFqa4U4EY0KT-3OcVDCM7AtVBzR-3QV0qYB1mNf-A95Jec9woAAqkE7MwV61e2Qptb2XoYX8gjzPUX55IALoT69Oueq6QF-Qmv33htobnqM3hJVQPNihGAzK433ptr7qTcIyJ1cpMlV_vJDA8L5AQYJ7dZgsV7klvg16H0-LXzLm13UqzRvDyJ3oqbFSEatPjbSEbdU5GChorDGLw1R2ftjrS7Egojh3YMjPR-WOrwP_9s6EazMo104DO4Yc4Cujm5SmLyzG16XayiWM5mvJey7Q

此时,token已经可以用于dashboard 的登录认证,但是还无法通过授权,因为还没有对serviceAccount进行角色绑定。

Step2:创建ClusterRole

创建名为clusterRole.yaml的文件,内容如下,我们定义了名为node-get的角色,该角色只允许对nodes资源对象进行getlist操作。如果需要对其他的资源对象权限管控,可以在resources字段下进行添加,verbs字段下定义允许的操作类型。

复制代码
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-get
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list

创建clusterRole:

复制代码
$ kubectl create -f clusterRole.yaml

Step3:ClusterRoleBinding

创建名为clusterRolleBinding.yaml的文件,内容如下。我们绑定了clusterRoleserviceAccount,绑定之后,对应的serviceAccount就拥有了clusterRole中赋予的权限。

复制代码
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-node-get
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: node-get
subjects:
- kind: ServiceAccount
  name: test
  namespace: default
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: test

创建clusterRoleBinding:

复制代码
$ kubectl create -f clusterRoleBinding.yaml

到此,kubernetes集群服务端的设置完成,可以基于Step1中的token进行dashboard或API的登录认证和授权。但如果用户是通过kubectl进行集群操作的话,我们还需要给用户创建kubeconfig文件,以便用户能够方便使用kubectl工具。

Step4:创建用户认证授权的kubeconfig文件

1、CA认证方式

1.1 生成用户证书

创建文件test.config

复制代码
[req]
req_extensions     = v3_req
distinguished_name = req_distinguished_name
prompt             = no

[req_distinguished_name]
CN = test

[ v3_req ]
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = TLS Web Client Authentication
subjectAltName = @alt_names

[alt_names]
IP.1 = 172.31.96.144
IP.3 = 127.0.0.1
IP.4 = 10.96.0.1

创建证书(备注:客户端的证书必须经过集群CA的签署,否则不会被认可):

复制代码
$ openssl genrsa -out test.key 2048
$ openssl req -new -key test.key -out test.csr -config test.config
$ openssl x509 -req -in test.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out test.crt -sha256 -days 3650 -extensions v3_req -extfile test.config

1.2 生成kubeconfig文件

设置集群参数:

复制代码
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://172.31.96.144:6443 \
--kubeconfig=test.kubeconfig

设置客户端认证参数:

复制代码
$ kubectl config set-credentials test \
--client-certificate=test.crt \
--client-key=test.key \
--embed-certs=true \
--kubeconfig=test.kubeconfig

设置上下文参数:

复制代码
$ kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=test \
--namespace=default \
--kubeconfig=test.kubeconfig

设置默认上下文:

复制代码
$ kubectl config use-context kubernetes --kubeconfig=test.kubeconfig

验证:

复制代码
$ kubectl get node --kubeconfig=test.kubeconfig

2、token认证方式

设置集群参数:

复制代码
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://172.31.96.144:6443 \
--kubeconfig=test.token

设置客户端认证参数:

复制代码
$ kubectl config set-credentials test \
--token=eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtdG9rZW4td3Zta3giLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImMyZGI0NTVjLTU3ZDQtMTFlYy1iNDY0LTg0OGY2OWUzZWViNCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QifQ.cdzShIX7IJj2sLS8h_LNpIRiDF8mXkex7GgPQUUxTbKFZ0cIZbMt5zDpxH4NN4XFqa4U4EY0KT-3OcVDCM7AtVBzR-3QV0qYB1mNf-A95Jec9woAAqkE7MwV61e2Qptb2XoYX8gjzPUX55IALoT69Oueq6QF-Qmv33htobnqM3hJVQPNihGAzK433ptr7qTcIyJ1cpMlV_vJDA8L5AQYJ7dZgsV7klvg16H0-LXzLm13UqzRvDyJ3oqbFSEatPjbSEbdU5GChorDGLw1R2ftjrS7Egojh3YMjPR-WOrwP_9s6EazMo104DO4Yc4Cujm5SmLyzG16XayiWM5mvJey7Q \
--kubeconfig=test.token

设置上下文参数:

复制代码
$ kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=test \
--namespace=default \
--kubeconfig=test.token

设置默认上下文:

复制代码
$ kubectl config use-context kubernetes --kubeconfig=test.token

验证:

复制代码
$ kubectl get node --kubeconfig=test.token

Step5:自动化

手动创建kubeconfig文件相对繁琐,一下提供基于token认证方式的自动脚本。

创建文件kubeconfig.sh,内容如下:

复制代码
#!/bin/sh
set -e
echo "input serviceAccount:"
read serviceAccount

if [ "$serviceAccount" == "" ]
then
        echo "serviceAccount is empty"
        exit 1
fi

echo "input namespace:"
read namespace
if [ "$namespace" == "" ]
then
        echo "namespace is empty"
        exit 2
fi

secretName=$(kubectl get serviceAccount $serviceAccount -n $namespace -o jsonpath='{.secrets[0].name}')
token=$(kubectl get secret $secretName -n $namespace -o jsonpath='{.data.token}' | base64 -d)

currentContext=$(kubectl config view -o jsonpath='{.current-context}')
cluster=$(kubectl config view -o jsonpath="{.contexts[?(@.name == \"$currentContext\")].context.cluster}")
apiserver=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"$cluster\")].cluster.server}")

kubectl get secret $secretName -n $namespace -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt

kubectl config set-cluster kubernetes \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=$apiserver \
--kubeconfig=config

kubectl config set-credentials $serviceAccount --token=$token --kubeconfig=config

kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=$serviceAccount \
--kubeconfig=config

kubectl config use-context kubernetes --kubeconfig=config

根据脚本提示输入serviceAccount的信息,完成config的创建,通过如下命令完成验证:

复制代码
kubectl get node --kubeconfig=config
相关推荐
明月_清风8 小时前
K8s 从入门到上手:核心概念+常用工具全解析
后端·kubernetes
阿里云云原生11 小时前
阿里云可观测 2026 年 4 月产品动态
云原生
qq_3643717212 小时前
基于 Docker 容器化环境配置
运维·docker·容器
塔克拉玛攻城狮12 小时前
详解cni插件cilium篇一:它为什么这么快?它还有哪些高级功能?
kubernetes·cilium
阿里云云原生12 小时前
Skills Registry 公测开启:为企业打造私有的 Skill 管理中心
云原生
吃胖点儿13 小时前
DevOps与自动化原理
云原生
GentleDevin13 小时前
Docker 运维常用命令大全
docker·容器·运维命令
运维全栈笔记13 小时前
基于Docker的MinIO单机部署与功能测试指南
运维·docker·容器
阿里云云原生13 小时前
HiClaw 发布 v1.1.0,提供 Kubernetes 集群部署实现,支持 Hermes Worker 运行时
kubernetes
心机之蛙qee14 小时前
docker的安装(RHEL9)
运维·docker·容器