K8S权限管理

一、RBAC的架构与核心组件

1.1 RBAC的授权流程

当用户或服务账户发起API请求时,RBAC的授权流程如下:

  1. 身份认证(Authentication):通过证书、Token或外部IdP(如OIDC)验证请求者身份。
  2. 授权决策(Authorization):
    1. API Server提取请求的操作(Verb)、资源类型(Resource)和命名空间(Namespace)
    2. 遍历所有与主题关联的RoleBinding和ClusterRoleBinding,检查是否存在匹配的权限规则。
  3. 准入控制(Admission Control):执行后续校验(如资源配额、Pod安全策略)

2.2 RBAC 的四层模型

RBAC 通过四类 API 对象实现权限控制:

  1. 角色(Role 和 ClusterRole)
    • Role:定义命名空间内的资源操作权限(如 Pod 的读写)。
    • ClusterRole:定义集群级资源(如 Node、PersistentVolume)或跨命名空间的聚合权限。
  2. 绑定(RoleBinding 和 ClusterRoleBinding)
    • RoleBinding:将 Role 或 ClusterRole 绑定到主体,作用域为单个命名空间。
    • ClusterRoleBinding:将 ClusterRole 绑定到主体,权限全局生效。

2.3 权限规则的组成要素

每个 Role 或 ClusterRole 包含一组规则(Rules),每条规则由以下要素构成:

  • API 组(apiGroups):指定目标资源所属的 API 组(如 apps 对应 Deployment,空字符串代表核心组)。
  • 资源(resources):资源类型(如 podssecrets)。
  • 操作(verbs):允许的 HTTP 方法(如 getlistcreate)。
  • 资源名称(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"