K8S权限管理及生产使用
K8S权限管理
一、RBAC的架构与核心组件
1.1 RBAC的授权流程
当用户或服务账户发起API请求时,RBAC的授权流程如下:
- 身份认证(Authentication):通过证书、Token或外部IdP(如OIDC)验证请求者身份。
- 授权决策(Authorization):
- API Server提取请求的操作(Verb)、资源类型(Resource)和命名空间(Namespace)
- 遍历所有与主题关联的RoleBinding和ClusterRoleBinding,检查是否存在匹配的权限规则。
- 准入控制(Admission Control):执行后续校验(如资源配额、Pod安全策略)
2.2 RBAC 的四层模型
RBAC 通过四类 API 对象实现权限控制:
- 角色(Role 和 ClusterRole):
- Role:定义命名空间内的资源操作权限(如 Pod 的读写)。
- ClusterRole:定义集群级资源(如 Node、PersistentVolume)或跨命名空间的聚合权限。
- 绑定(RoleBinding 和 ClusterRoleBinding):
- RoleBinding:将 Role 或 ClusterRole 绑定到主体,作用域为单个命名空间。
- ClusterRoleBinding:将 ClusterRole 绑定到主体,权限全局生效。
2.3 权限规则的组成要素
每个 Role 或 ClusterRole 包含一组规则(Rules),每条规则由以下要素构成:
- API 组(apiGroups):指定目标资源所属的 API 组(如
apps
对应 Deployment,空字符串代表核心组)。 - 资源(resources):资源类型(如
pods
、secrets
)。 - 操作(verbs):允许的 HTTP 方法(如
get
、list
、create
)。 - 资源名称(resourceNames)(可选):限制规则仅适用于特定名称的资源。
- 非资源端点(nonResourceURLs)(仅 ClusterRole):控制对
/healthz
等非资源 API 的访问。
二、RBAC的配置与操作实践
2.1 服务账户ServiceAccount
2.1.1 ServiceAccount增删改查
创建ServiceAccount
root@VM-26-130-ubuntu:~# kubectl create sa dujie
查看ServiceAccount,在k8s 1.24之前,创建serviceaccount会自动创建对应的secret,包含token和ca文件
root@VM-26-130-ubuntu:~# kubectl get sa
NAME SECRETS AGE
default 1 10d
dujie 1 61m
root@VM-26-130-ubuntu:~# kubectl get secrets dujie-token-6gcv7 -o yaml
apiVersion: v1
data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJMU1ETXhPREEwTWpNME9Gb1hEVE0xTURNeE5qQTBNak0wT0Zvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTjM5CjBTMmd2ZU1ISlJHWFV0ZmJEaW43ZlRjSjB4ZWFVbDgvZnAxRnBxaVdOVENVZmdCZVFUSkdxWXBYQmMvM3hzT3AKWjByWDkyTXEzSmRGTDQ5djBXUm81bU85bzB0YWJHTzk4YlM3ZXpkNFllSWhBZjJZUVgxaHRNSVZPTzdvSzY1NwpTcVZhbk1GcWphRERMRmZSMVFkVndlZ2JRbkp2UWJIbFQ1RytpMWNYdk9Hd1NlTUFCNzljUW0vOHpJcG5FNGpyCmpYNjZEbnhMb04wMUU3aHNkWWNEalJEeE9RY0hXVW5NUFlIa2pJTk9GelVIY0pBYWJqNjAwanZNaERWNGNiVkkKeG93Z1Q0U1lHVWxPT2d5d0U1aEJWSTJBSVVRdkp6VlRNUVR6MlFWZys4Vy9FNnI3bFQ2L3VvY0VlNUtFWFBZbwpJVHQxVHpRZW9EL0xINk9mQkxNQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFOdVVwdWhzdlRzSnNEZlpkRUNOcWNJTmhGRHgKTDBMdDhXcTRRQmZFUUNjRFA2cVhLRlY2aVArTWZLWlNWVktSVkhSbmJXYjVDYjZ6SEhOK1d2UGdxWUo3WXZjTQoraUVUSnc2VXM4K3NrNldGYVVwZnY4R1R5VjNpb2gwN2tacGxtekM2YlVzRlRVZXhmeHo2YWhNM2Q5UTJnalJpCjM4OVRoU2N0OFphVXlVbS9XbUpEcFFZdVFpeDdtRGJqVDZOZVQyNFZzN0hRYUFyLzZiWXNvNmxjR1prTGsyMjcKRHpTMGpRUjR6QjRVK1g3d3RKaXZvZll0aXorRmN1azJ6ZDJ1MjVBekhoeVpKY3UvdWJzRmhqQU5leUFMUGZJcQpyak43bTdmaWlGWnJsVnNJSXlqZnVFajBMUXhiT3ZWN1JTVWhrb2E0QXNwQjBFb1lCSlo2bE5zZkxydz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
namespace: ZGVmYXVsdA==
token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkluVnVRbTFPVlZOME1ETXpMVTVtTTNOb01WcFVRWFpEZUhacVVHbHJSMnBxVURWQlZEY3paM0Z5V0ZVaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJbVIxYW1sbExYUnZhMlZ1TFRablkzWTNJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpYSjJhV05sTFdGalkyOTFiblF1Ym1GdFpTSTZJbVIxYW1sbElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVkV2xrSWpvaVkyVm1NR1kwTnpRdE1tRTFZaTAwWW1GaExXSmlOMkV0WkdRM09UZGlNRE13TWpOaUlpd2ljM1ZpSWpvaWMzbHpkR1Z0T25ObGNuWnBZMlZoWTJOdmRXNTBPbVJsWm1GMWJIUTZaSFZxYVdVaWZRLkVhTHRzWXB1dlNQeDJXVFM1NGxKVy1oY0U2alFhT2gyVzRwUXkyOXZOMXJ5dVVlWUM2T1ZGRVp6LW5vUTlDSFQtdFU1Vkp6TmxWVDhlZzZmMW80eFN0ZlZzOHRyaldBUm4xTU1vMW9QcXFjUjh5Y1RhVUgtcUpTSnlPb0FGd2VCaDdSbTVPVGdyZ0U0UW5VY0pUT0p4Wkw2MWNxbkVmcU9hdXlNQWRodE5sTUpXMWhPd1dlNFdkMXlHOTRPM0ZybDNsY1pRUGNJVTVHa0tCSDBQQVVKSGxYb1pIV0g2Vk50RGlTckhOSHY1YnN5MlRwUWRZOG4yakJBcW5TMzNmZVNLajViYXpCLVBaekdGLXM0STJFcnlER0k4cG91eHZRTUR5Z2k4T3VvYUM5Y0dRT3RMLWF4bUNCcG43UHZkMHQtT0J5dU0xSjhCR0xOR1pHcnFzQ0Rzdw==
kind: Secret
metadata:
annotations:
kubernetes.io/service-account.name: dujie
kubernetes.io/service-account.uid: cef0f474-2a5b-4baa-bb7a-dd797b03023b
creationTimestamp: "2025-03-28T06:08:04Z"
name: dujie-token-6gcv7
namespace: default
resourceVersion: "5758518"
selfLink: /api/v1/namespaces/default/secrets/dujie-token-6gcv7
uid: ba717d58-dea4-444d-823a-197dcffbc2df
type: kubernetes.io/service-account-token
1.24版本以后需要手动创建(以下操作是1.24版本以后需要执行)
为某个 ServiceAccount 创建 Token:
# kubectl create token dujie
eyJhbGciOiJSUzI1NiIsImtpZCI6IlRWdXpoRlExMEFL…
创建一个指定过期时间的 Token:
# kubectl create token dujie --duration=99999h
eyJhbGciOiJSUzI1NiIsImtpZCI6IlRWdX…
使用Secret存储ServiceAccount Token
# vim dujie-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: dujie-token-secret
annotations:
kubernetes.io/service-account.name: dujie
type: kubernetes.io/service-account-token
创建该Secret
# kubectl create -f dujie-token-secret.yaml
secret/dujie-token-secret created
查看生成的 Token:
# kubectl get secret dujie-token-secret
NAME TYPE DATA AGE
dukuan-token-secret kubernetes.io/service-account-token 3 71s
# kubectl describe secret dujie-token-secret
Name: dujie-token-secret
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: dujie
kubernetes.io/service-account.uid: 227b46f0-42df-4e8e-bdb9-
6eb23e858f2c
Type: kubernetes.io/service-account-token
Data
====
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlRWd…
2.1.2 基于ServiceAccount生成Kubeconfig
基于ServiceAccount生成Kubeconfig,需要先为ServiceAccount生成一个Token,可以使用保存在Secret中的Token
获取APIServer地址:
root@VM-26-130-ubuntu:~# serverAddr=`kubectl cluster-info | grep --color=never -Eo -m 1 "https://.*" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"`
root@VM-26-130-ubuntu:~# echo $serverAddr
https://xxxxxxxx.bj.xxxxxxx.xxxxxx.cn:6443
获取当前ServiceAccount的CA证书和Token:
root@VM-26-130-ubuntu:~# serviceaccountName="dujie"
root@VM-26-130-ubuntu:~# kubectl get secret |grep dujie
dujie-token-6gcv7 kubernetes.io/service-account-token 3 74m
root@VM-26-130-ubuntu:~# secretName="dujie-token-6gcv7"
root@VM-26-130-ubuntu:~# ca=$(kubectl get secret/$secretName -o jsonpath='{.data.ca\.crt}')
root@VM-26-130-ubuntu:~# token=$(kubectl get secret/$secretName -o jsonpath='{.data.token}' |base64 --decode)
生成kubeconfig的脚本
#!/bin/bash
serviceaccountName="dujie"
secretName="dujie-token-secret"
namespace="kube-users"
serverAddr=`kubectl cluster-info | grep --color=never \
-Eo -m 1 "https://.*" | \
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"`
echo "serverAddr: $serverAddr"
ca=$(kubectl get secret/$secretName -n $namespace -o jsonpath='{.data.ca\.crt}')
token=$(kubectl get secret/$secretName -n $namespace -o jsonpath='{.data.token}' | base64 --decode)
cat <<EOF > ${serviceaccountName}-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
cluster:
server: ${serverAddr}
certificate-authority-data: ${ca}
users:
- name: ${serviceaccountName}
user:
token: ${token}
contexts:
- name: ${serviceaccountName}-context
context:
cluster: default-cluster
user: ${serviceaccountName}
namespace: default
current-context: ${serviceaccountName}-context
EOF
生成后就可以使用新的kubeconfig操作集群
root@VM-26-130-ubuntu:~# kubectl get pods --kubeconfig dujie-kubeconfig.yaml
NAME READY STATUS RESTARTS AGE
gpu-example-6df5c956b8-5wnch 1/1 Running 0 25h
gpu-example-6df5c956b8-6wbjd 1/1 Running 0 25h
gpu-example-6df5c956b8-8dvfk 1/1 Running 1 (25h ago) 25h
gpu-example-6df5c956b8-w6l9d 1/1 Running 0 25h
gpu-example-6df5c956b8-xnnl7 1/1 Running 0 25h
my-app-7c86967899-27jz7 1/1 Running 1 (25h ago) 30h
my-app-7c86967899-z5crp 1/1 Running 0 30h
tolerations-second-574f8dcc68-qbsqp 1/1 Running 0 25h
如果没有权限,可以临时进行授权:
root@VM-26-130-ubuntu:~# kubectl create rolebinding dujie-view --clusterrole=view --serviceaccount=default:dujie
rolebinding.rbac.authorization.k8s.io/dujie-view created
2.2 细粒度权限配置
2.2.1 使用kubectl管理RBAC
创建一个可以查询Pod的Role
root@VM-26-130-ubuntu:~# kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
role.rbac.authorization.k8s.io/pod-reader created
root@VM-26-130-ubuntu:~# kubectl get role pod-reader -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2025-03-28T07:30:32Z"
name: pod-reader
namespace: default
resourceVersion: "5791732"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/pod-reader
uid: 14393739-5638-433b-969e-440a26a8f370
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
指定非核心组
root@VM-26-130-ubuntu:~# kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
role.rbac.authorization.k8s.io/foo created
root@VM-26-130-ubuntu:~# kubectl get role foo -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2025-03-28T07:31:24Z"
name: foo
namespace: default
resourceVersion: "5792083"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/roles/foo
uid: 68a48369-28ad-4410-aa34-8541be9d7d73
rules:
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- list
- watch
创建一个可以查询Pod的ClusterRole
root@VM-26-130-ubuntu:~# kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
clusterrole.rbac.authorization.k8s.io/pod-reader created
root@VM-26-130-ubuntu:~# kubectl get clusterrole pod-reader -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2025-03-28T07:32:30Z"
name: pod-reader
resourceVersion: "5792523"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/pod-reader
uid: eb6761fc-3fee-4bf7-8d24-c5409c1f2739
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
创建一个Rolebinding,把pod-reader 绑定到default空间下的dujie用户
root@VM-26-130-ubuntu:~# kubectl create rolebinding dujie-pod-reader --clusterrole=pod-reader --serviceaccount=default:dujie
rolebinding.rbac.authorization.k8s.io/dujie-pod-reader created
root@VM-26-130-ubuntu:~# kubectl get rolebindings.rbac.authorization.k8s.io dujie-pod-reader -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2025-03-28T07:33:53Z"
name: dujie-pod-reader
namespace: default
resourceVersion: "5793080"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/dujie-pod-reader
uid: cf429661-3263-415c-9acb-de9c77406eda
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-reader
subjects:
- kind: ServiceAccount
name: dujie
namespace: default
创建一个 ClusterRoleBinding,把 admin 权限绑定至 default 空间下的 dotbalo 用户:
root@VM-26-130-ubuntu:~# kubectl get clusterrolebindings.rbac.authorization.k8s.io dujie-pod-reader -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
creationTimestamp: "2025-03-28T07:35:14Z"
name: dujie-pod-reader
resourceVersion: "5793629"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/dujie-pod-reader
uid: a2637330-5c12-4c54-9788-9fe2b9011532
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: ServiceAccount
name: dujie
namespace: default
验证某个用户是否具有某个权限
root@VM-26-130-ubuntu:~# kubectl auth can-i get configmaps -n default --as=system:serviceaccount:default:dujie
yes
root@VM-26-130-ubuntu:~# kubectl auth can-i get configmaps -n default --as=system:serviceaccount:kube-system:dujie
no
2.2.2 通用权限管理
####### 2.2.2.1 Namespace查询权限
创建一个可以查询命名空间的权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat namespace-readonly.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-readonly
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- metrics.k8s.io
resources:
- pods
verbs:
- get
- list
- watch
####### 2.2.2.2 Pod删除权限
创建一个可以删除Pod的权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat pod-delete.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-delete
rules:
- apiGroups:
- ""
resources:
- pods
- pods/status
verbs:
- get
- list
- delete
####### 2.2.2.3 执行命令权限
创建一个可以执行命令的权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat pod-exec.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-exec
rules:
- apiGroups:
- ""
resources:
- pods
- pods/status
verbs:
- get
- list
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
####### 2.2.2.4 查看日志权限
创建一个可以查看日志的权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat pod-log.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-log
rules:
- apiGroups:
- ""
resources:
- pods
- pods/log
- pods/status
verbs:
- get
- list
- watch
####### 2.2.2.5 资源编辑权限
创建一个可以针对指定资源进行编辑的权限:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat configmap-depoyment-manager.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: configmap-deployment-manager
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["apps"]
resources: ["deployments","statefulsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
2.2.3 多租户管理
创建一个专用于存储用户的namespace
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create ns kube-users
namespace/kube-users created
授权kube-users空间下的用户都能看到namespace的权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create clusterrolebinding namespace-readonly --clusterrole=namespace-readonly --group=system:serviceaccounts:kube-users
clusterrolebinding.rbac.authorization.k8s.io/namespace-readonly created
创建多个用户模拟不同的场景
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create sa review-develop -n kube-users
serviceaccount/review-develop created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create sa review-ops -n kube-users
serviceaccount/review-ops created
创建namesapce模拟不同的环境
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create ns review-dev
namespace/review-dev created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create ns review-test
namespace/review-test created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create ns review-prod
namespace/review-prod created
在每个环境下创建一个服务
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create deploy redis --image=registry.cn-beijing.aliyuncs.com/dotbalo/redis:7.2.5 -n review-dev
deployment.apps/redis created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create deploy redis --image=registry.cn-beijing.aliyuncs.com/dotbalo/redis:7.2.5 -n review-test
deployment.apps/redis created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create deploy redis --image=registry.cn-beijing.aliyuncs.com/dotbalo/redis:7.2.5 -n review-prod
deployment.apps/redis created
2.2.4 不同用户授权管理
2.2.4.1 授权测试环境可以查看日志和执行命令
在非生产环境,可以针对开发和测试人员开放查看日志和执行命令的权限,方便排查问题等。
授权 review-develop 用户对 review-dev 和 review-test 两个空间可以有查看日志和执行命令的权限:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-pod-log --clusterrole=pod-log --serviceaccount=kube-users:review-develop -n review-dev
rolebinding.rbac.authorization.k8s.io/develop-pod-log created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-pod-exec --clusterrole=pod-exec --serviceaccount=kube-users:review-develop -n review-dev
rolebinding.rbac.authorization.k8s.io/develop-pod-exec created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-pod-exec --clusterrole=pod-exec --serviceaccount=kube-users:review-develop -n review-test
rolebinding.rbac.authorization.k8s.io/develop-pod-exec created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-pod-log --clusterrole=pod-log --serviceaccount=kube-users:review-develop -n review-test
rolebinding.rbac.authorization.k8s.io/develop-pod-log created
创建token测试(1.24版本一下可直接使用secret中的token):
kubectl create token review-develop -n kube-users
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# cat toconfig.sh
#!/bin/bash
serviceaccountName="review-develop"
secretName="review-develop-token-fdlvt"
namespace="kube-users"
serverAddr=`kubectl cluster-info | grep --color=never \
-Eo -m 1 "https://.*" | \
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"`
echo "serverAddr: $serverAddr"
ca=$(kubectl get secret/$secretName -n $namespace -o jsonpath='{.data.ca\.crt}')
token=$(kubectl get secret/$secretName -n $namespace -o jsonpath='{.data.token}' | base64 --decode)
cat <<EOF > ${serviceaccountName}-kubeconfig.yaml
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
cluster:
server: ${serverAddr}
certificate-authority-data: ${ca}
users:
- name: ${serviceaccountName}
user:
token: ${token}
contexts:
- name: ${serviceaccountName}-context
context:
cluster: default-cluster
user: ${serviceaccountName}
namespace: default
current-context: ${serviceaccountName}-context
EOF
# 执行生成kubeconfig脚本
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# sh toconfig.sh
serverAddr: https://xxxxx.xxxxx.xxxx.xxxxx.cn:6443
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# ll review-develop-kubeconfig.yaml
-rw-r--r-- 1 root root 2698 Mar 28 16:01 review-develop-kubeconfig.yaml
# 可以看到除了review-dev和review-test命名空间,其他空间是没有权限的
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get pods --kubeconfig=review-develop-kubeconfig.yaml
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:kube-users:review-develop" cannot list resource "pods" in API group "" in the namespace "default"
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get pods --kubeconfig=review-develop-kubeconfig.yaml -n review-dev
NAME READY STATUS RESTARTS AGE
redis-6f5456cb76-27s8w 1/1 Running 0 11m
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get pods --kubeconfig=review-develop-kubeconfig.yaml -n review-test
NAME READY STATUS RESTARTS AGE
redis-6f5456cb76-gxhrh 1/1 Running 0 11m
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get pods --kubeconfig=review-develop-kubeconfig.yaml -n review-prod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:kube-users:review-develop" cannot list resource "pods" in API group "" in the namespace "review-prod"
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get pods --kubeconfig=review-develop-kubeconfig.yaml -n kube-system
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:kube-users:review-develop" cannot list resource "pods" in API group "" in the namespace "kube-system"
# 删除测试发现没有权限
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl delete pods --kubeconfig=review-develop-kubeconfig.yaml -n review-test redis-6f5456cb76-gxhrh
Error from server (Forbidden): pods "redis-6f5456cb76-gxhrh" is forbidden: User "system:serviceaccount:kube-users:review-develop" cannot delete resource "pods" in API group "" in the namespace "review-test"
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac#
# 查看日志发现可以
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl logs --kubeconfig=review-develop-kubeconfig.yaml -n review-test redis-6f5456cb76-gxhrh
1:C 28 Mar 2025 07:50:58.497 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 28 Mar 2025 07:50:58.497 * Redis version=7.2.5, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 28 Mar 2025 07:50:58.497 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 28 Mar 2025 07:50:58.497 * monotonic clock: POSIX clock_gettime
1:M 28 Mar 2025 07:50:58.498 * Running mode=standalone, port=6379.
1:M 28 Mar 2025 07:50:58.498 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 28 Mar 2025 07:50:58.498 * Server initialized
1:M 28 Mar 2025 07:50:58.498 * Ready to accept connections tcp
2.2.4.2 授权生产环境只能查看日志
在生产环境,通常不允许其他用户有特别大的权限,此时可以限制只能查看日志。授权开发人员只能查看生产环境的日志权限:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-pod-log --clusterrole=pod-log --serviceaccount=kube-users:review-develop -n review-prod
rolebinding.rbac.authorization.k8s.io/develop-pod-log created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac#
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get rolebindings.rbac.authorization.k8s.io -n review-prod develop-pod-log -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2025-03-28T08:05:45Z"
name: develop-pod-log
namespace: review-prod
resourceVersion: "5806020"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/review-prod/rolebindings/develop-pod-log
uid: cd5ff85f-fb87-40a9-8fcc-7bf44e449d20
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pod-log
subjects:
- kind: ServiceAccount
name: review-develop
namespace: kube-users
2.2.4.3 授权开发人员可以修改非生产环境部分资源
有时候开发人员需要修改程序的配置用来测试新功能或者排查故障,此时可以给开发人员授权可以编辑部分的资源,比如 ConfigMap 和 Deployment。
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding develop-configmap-deployment-manager --clusterrole=configmap-deployment-manager --serviceaccount=kube-users:review-develop -n review-dev
rolebinding.rbac.authorization.k8s.io/develop-configmap-deployment-manager created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get rolebindings.rbac.authorization.k8s.io -n review-dev develop-configmap-deployment-manager -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: "2025-03-28T08:08:04Z"
name: develop-configmap-deployment-manager
namespace: review-dev
resourceVersion: "5806952"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/review-dev/rolebindings/develop-configmap-deployment-manager
uid: c3184db8-48a3-492f-ac7e-a68173a4b9a7
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: configmap-deployment-manager
subjects:
- kind: ServiceAccount
name: review-develop
namespace: kube-users
授权之后,develop 可以修改 project-a-dev 的 ConfigMap 和 Deployment,但是其他环境无法修改。
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl get configmaps --kubeconfig=review-develop-kubeconfig.yaml -n review-dev
NAME DATA AGE
kube-root-ca.crt 1 25m
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl edit deployments.apps --kubeconfig=review-develop-kubeconfig.yaml -n review-dev redis
deployment.apps/redis edited
2.2.4.4 授权多租户场景受限管理员的权限
如果集群中分配了多个租户和 OPS 用户,此时租户和 OPS 用户应当具备指定空间的所有权限,此时可以直接使用 admin 或者 edit 的 ClusterRole 进行授权:
比如授权 review-ops 用户可以操作 review-dev、test、prod 空间下的所有资源:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding ops-edit --clusterrole=edit --serviceaccount=kube-users:review-ops -n review-dev
rolebinding.rbac.authorization.k8s.io/ops-edit created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding ops-edit --clusterrole=edit --serviceaccount=kube-users:review-ops -n review-test
rolebinding.rbac.authorization.k8s.io/ops-edit created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding ops-edit --clusterrole=edit --serviceaccount=kube-users:review-ops -n review-prod
rolebinding.rbac.authorization.k8s.io/ops-edit created
此时使用 project-a-ops 用户登录集群,即可操作上述空间的大部分资源。
2.2.4.5 授权应用程序可以访问集群资源
有时候需要对部署在 Kubernetes 集群中的服务进行授权,使其可以访问资源的某些资源,比如获取集群中的 Pod 状态等,此时可以授权给某个 ServiceAccount,然后让 Pod 用该ServiceAccount 创建 Pod,此时该 Pod 内的程序即可具备相关的权限。
比如要实现某个程序具备 view 的权限,可以用如下方式进行授权。首先创建一个用于该程序的 ServiceAccount:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create sa app-view -n review-dev
serviceaccount/app-view created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac#
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create rolebinding app-view --clusterrole=view --serviceaccount=review-dev:app-view -n review-dev
rolebinding.rbac.authorization.k8s.io/app-view created
创建一个资源并使用该ServiceAccount
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl create deploy app --image=registry.cn-beijing.aliyuncs.com/dotbalo/kubectl -n review-dev -- sleep 36000
deployment.apps/app created
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl edit deployments.apps app -n review-dev
...
serviceAccount: app-view
containers:
- command:
- sleep
- "36000"
image: registry.cn-beijing.aliyuncs.com/dotbalo/kubectl
imagePullPolicy: Always
name: kubectl
resources: {}
terminationMessagePath: /dev/termination-log
...
deployment.apps/app edited
登录至该容器,即可访问该空间下的所有资源:
root@VM-26-130-ubuntu:/usr/local/src/k8s/rbac# kubectl exec -it -n review-dev app-7f9985dc75-42xwp bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
I have no name!@app-7f9985dc75-42xwp:/$
I have no name!@app-7f9985dc75-42xwp:/$ kubectl get po -n review-dev
NAME READY STATUS RESTARTS AGE
app-7f9985dc75-42xwp 1/1 Running 0 82s
redis-6f5456cb76-27s8w 1/1 Running 0 32m
redis-6f5456cb76-9hhm6 1/1 Running 0 7m45s
redis-6f5456cb76-pzs87 1/1 Running 0 7m45s
其他空间未授权无法访问
I have no name!@app-7f9985dc75-42xwp:/$ kubectl get po -n review-test
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:review-dev:app-view" cannot list resource "pods" in API group "" in the namespace "review-test"