RBAC
基于角色的访问控制 Role-Based Access Contrl
RBAC模型就是平常理解的。 资源-权限-角色-用户。其中「资源」就是k8s的API对象,比如pods、configmaps这一类资源,或者某一个资源,比如某一个pod,某一个configmap。权限也是内置的,权限共有一下几种:
verbs:["get","list","watch","create","update","patch","delete"]
资源和权限的组合关系用Role对象来定义。role是一组规则,他定义了一组对k8s API对象的操作权限。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: mynamespace
name: example-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
2
3
4
5
6
7
8
9
role的作用范围是namespace。
定义好role后,要将role绑定到某一个「被作用者」。被作用者可以是User、也可以是ServiceAccount,一般是ServiceAccount。role和被作用者subject的关系用RoleBinding对象来定义。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: User
name: example-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io
2
3
4
5
6
7
8
9
10
11
12
13
User是一个逻辑上的概念,在k8s中实际上并没有这个API对象,他可以是一个用户名、一个密码文件。我们大部分情况下的用户指的是ServiceAccount。
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: mynamespace
name: example-sa
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: ServiceAccount
name: example-sa
namespace: mynamespace
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ServiceAccount的信息保存在一个特殊的secret对象上。这个对象叫做ServiceAccountToken。pod使用这个token就可以合法的访问API Server。
apiVersion: v1
kind: Pod
metadata:
namespace: mynamespace
name: sa-token-test
spec:
containers:
- name: nginx
image: nginx:1.7.9
serviceAccountName: example-sa
2
3
4
5
6
7
8
9
10
pod运行之后可以查看到ServiceAccount的token被k8s自动挂载到了容器的/var/run/secrets/kubernetes.io/serviceaccount目录下了,进入容器中的这个目录有一个ca.crt文件,这个文件就是token。
$ kubectl describe pod sa-token-test -n mynamespace
Name: sa-token-test
Namespace: mynamespace
...
Containers:
nginx:
...
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from example-sa-token-vmfg6 (ro)
2
3
4
5
6
7
8
9
Role和RoleBingding只可以做单个namespace中的资源权限关系绑定,如果要对namespace外的资源对象做权限绑定,比如Node,或者做不限namespace的绑定,那么可以使用ClusterRole和ClusterRoleBinding。
被作用者除了可以是某个用户(比如ServiceAccount)之外,还可以是一个用户组。
# k8s的内置用户ServiceAccount的用户名是
system:serviceaccount:<namespace名>:<serviceaccount名>
# ServiceAccount对应的用户组名是
system:serviceaccounts:<namespace名>
2
3
4
下边这个定义的意思是被作用者为mynamespace下的所有serviceaccount
subjects:
- kind: Group
name: system:serviceaccounts:mynamespace
apiGroup: rbac.authorization.k8s.io
2
3
4
system开头的用户都是k8s内置的ClusterRole,可以用过 kubectl get clusterroles命令查看。
[root@master1 ~]# kubectl get clusterroles
NAME CREATED AT
...
system:certificates.k8s.io:certificatesigningrequests:nodeclient 2022-10-14T02:15:46Z
system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 2022-10-14T02:15:46Z
system:certificates.k8s.io:kube-apiserver-client-approver 2022-10-14T02:15:46Z
system:certificates.k8s.io:kube-apiserver-client-kubelet-approver 2022-10-14T02:15:46Z
...
[root@master1 ~]# kubectl describe clusterrole system:kube-scheduler
Name: system:kube-scheduler
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
events [] [] [create patch update]
events.events.k8s.io [] [] [create patch update]
bindings [] [] [create]
endpoints [] [] [create]
pods/binding [] [] [create]
tokenreviews.authentication.k8s.io [] [] [create]
subjectaccessreviews.authorization.k8s.io [] [] [create]
leases.coordination.k8s.io [] [] [create]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
总之,最常用的权限控制是Role + RoleBingding + ServiceAccount。