Kubernetes 使用 RBAC 鉴权
参考文档:
基于角色的访问控制(Role-Based Access Control, 即 “RBAC”)使用 rbac.authorization.k8s.io
API Group实现授权决策,允许管理员通过Kubernetes API动态配置策略。
基于 RBAC 配置权限,包括操作(get、create、list、delete、update、edit、watch、exec)资源:
- Pods
- PV
- ConfigMaps
- Deployments
- Nodes
- Secrets
- Namespaces
资源与 api group 关联(如 pods 属于 core api group,deployments 属于 apps api group)。
在RBAC中的几个概念:
- Rules: 规定一组可以在不同 api group 上的资源执行的规则(verbs)
- Role 与 ClusterRoles: 都是包括一组规则(rules),两者不同在于,Role 针对的是一个 namespace 中,ClusterRoles针对整个集群
- Subject: 有三种 Subjects,
ServiceAccount
、User
、Groups
,参照官方文档主要区别是 User 针对人,ServiceAccounts 针对运行在 Pods 中运行的进程。 - RoleBindings与ClusterRoleBindins: 将 Subject 绑定到 Role 或 ClusterRoles。其区别在于:RoleBinding 将使规则在命名空间内生效,而ClusterRoleBinding将使规则在所有命名空间中生效。
以下是配置 ClusterRole 或者 role 时的一些帮助信息获取方法
常见的 resources 的类型查看方法
1
kubectl get clusterrole edit -ojson |jq .rules[].resources | grep "pods" |sort | uniq
常见的 verbes 类型查看
1
kubectl get clusterrole edit -ojson |jq .rules[].verbs | sort |uniq
RBAC 授权示例1
创建命名空间以及 developer 用户
创建一个命名空间 kube-users 专门用来存放用户
1
2# kubectl create ns kube-users
namespace/kube-users created在 kube-users 命名空间下新建用户 `developer
1
2# kubectl create sa -n kube-users developer
serviceaccount/developer created新建的用户是没有任何权限的,可以使用新建用户的 token 登录 dashboard 验证其相关权限
1
2# 获取 developer 用户的 token
kubectl describe secrets -n kube-users $(kubectl get sa -n kube-users developer -o json | jq .secrets[].name | tr -d '"')使用该 token 登录kubernetes dashboard,会发现没有任何权限,连切换 namespace 的权限都没
对 developer 用户进行授权
授权对 namespace 具有只读权限
创建一个对所有命名空间具有只读权限的 ClusterRole,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23cat << EOF | kubectl create -f -
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
EOF关于 Metrics API 的说明 Metrics
绑定该 ClusterRole 到用户 developer 上
1
2
3kubectl create clusterrolebinding namespace-readonly \
--clusterrole=namespace-readonly \
--serviceaccount=kube-users:developer再次登录 dashboard,查看用户 developer 是否具有查看所有命名空间的权限
授权 developer 用户对其他资源的权限
此时用户 developer 虽然具有查看命名空间的权限,但是还没有查看其他资源,比如 Pod,deployment,statefulset 等资源的权限,如下
创建一个聚合 ClusterRole,之后通过标签
aggregate-to-developers: "true"
聚合其他具有相同标签的 ClusterRole1
2
3
4
5
6
7
8
9
10
11cat << EOF | kubectl create -f-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: developer-aggregate-privileges
aggregationRule:
clusterRoleSelectors:
- matchLabels:
aggregate-to-developers: "true"
rules: [] # 控制面自动填充这里的规则
EOF绑定该 ClusterRole 到用户 developer 上,并指定命名空间为
bookinfo
1
2
3
4kubectl create rolebinding developer-aggregate-privileges \
--clusterrole=developer-aggregate-privileges \
--serviceaccount=kube-users:developer \
--namespace=bookinfo此时查看该 clusterrole 的权限还是 null,所以用户还是没有任何权限
1
2
3
4
5
6
7
8
9
10
11
12
13# kubectl get clusterrole developer-aggregate-privileges -oyaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
aggregate-to-developers: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2022-03-26T06:13:38Z"
name: developer-aggregate-privileges
resourceVersion: "191043"
uid: 88b42791-7ac1-4809-a934-922d359d9d2b
rules: null创建一个对 pod 资源具有所有权限的 ClusterRole,并通过标签
aggregate-to-developers: "true"
聚合到developers-privileges
ClusterRole 上1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22cat << EOF | kubectl create -f-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: developer-pod-privileges
labels:
aggregate-to-developers: "true"
rules:
- apiGroups:
- ""
resources:
- pods
- pods/exec
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
- pods/log
- pods/status
verbs:
- "*"
EOF注意: 由于 pod 是属于 core apiGroup,所以这里直接留空即可
此时再查看
developer-aggregate-privileges
这个 ClusterRole 所具有的的权限,如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26# kubectl get clusterrole developer-aggregate-privileges -oyaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
aggregate-to-developers: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2022-03-26T06:13:38Z"
name: developer-aggregate-privileges
resourceVersion: "191512"
uid: 88b42791-7ac1-4809-a934-922d359d9d2b
rules:
- apiGroups:
- ""
resources:
- pods
- pods/exec
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
- pods/log
- pods/status
verbs:
- '*'因为是使用的 rolebinding 的方式,并且指定的命名空间为
bookinfo
,所以此时用户 developer 也拥有对命名空间 bookinfo 中 Pod 的相关权限
同理,创建一个对 Deployment,StatefulSet,DaemonSet 具有所有权限的 ClusterRole,并通过标签
aggregate-to-developers: "true"
聚合到developers-privileges
ClusterRole 上1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26cat << EOF | kubectl create -f-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: workload-all-privileges
labels:
aggregate-to-developers: "true"
rules:
- apiGroups:
- apps
resources:
- daemonsets
- daemonsets/status
- deployments
- deployments/rollback
- deployments/scale
- deployments/status
- replicasets
- replicasets/scale
- replicasets/status
- statefulsets
- statefulsets/scale
- statefulsets/status
verbs:
- '*'
EOF注意: daemonset,deployment,statefulset 等属于 apps apiGroup,所以这里要写上 apps,其他的资源可以通过资源的 apiVersion 来确定其属于哪个 apiGroups
更新权限,kubectl 使用
auth reconcile
命令来更新 rbac 的权限规则1
2
3
4
5
6
7
8# 测试应用 RBAC 对象的清单文件,显示将要进行的更改:''
kubectl auth reconcile -f my-rbac-rules.yaml --dry-run
# 应用 RBAC 对象的清单文件,保留角色中的额外权限和绑定中的其他主体
kubectl auth reconcile -f my-rbac-rules.yaml
# 应用 RBAC 对象的清单文件, 删除角色中的额外权限和绑定中的其他主体:
kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
为用户 developer 创建 kubeconfig 文件
设置集群地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19kubectl config set-cluster kubernetes \
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.200.110:8443 \
--kubeconfig=./developer.kubeconfig
# 查看 kubeconfig 信息
# kubectl config view --kubeconfig=./developer.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.200.110:8443
name: kubernetes
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null设置用户凭证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23DEVELOPER_SECRET_NAME=$(kubectl get sa -n kube-users developer -o json | jq .secrets[].name | tr -d '"')
DEVELOPER_TOKEN=$(kubectl get secret -n kube-users ${DEVELOPER_SECRET_NAME} -o jsonpath={.data.token} | base64 -d )
kubectl config set-credentials developer \
--token=${DEVELOPER_TOKEN} \
--kubeconfig=./developer.kubeconfig
# 查看 kubeconfig 信息
# kubectl config view --kubeconfig=./developer.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.200.110:8443
name: kubernetes
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: developer
user:
token: REDACTED设置上下文信息
1
2
3
4kubectl config set-context developer@kubernetes \
--cluster=kubernetes \
--user=developer \
--kubeconfig=./developer.kubeconfig切换上下文
1
kubectl config use-context deployer@kubernetes --kubeconfig=./developer.kubeconfig
测试使用 kubeconfig 文件登录 dashboard