RBAC
RBAC资源
Kubernetes中完成授权工作的就是RBAC机制,RBAC授权规则是通过四种资源来进行配置。
- Role:角色,其实是定义一组对Kubernetes资源(命名空间级别)的访问规则。
- RoleBinding:角色绑定,定义了用户和角色的关系。
- ClusterRole:集群角色,其实是定义一组对Kubernetes资源(集群级别,包含全部命名空间)的访问规则。
- ClusterRoleBinding:集群角色绑定,定义了用户和集群角色的关系。
Role和ClusterRole指定了可以对哪些资源做哪些动作,RoleBinding和ClusterRoleBinding将角色绑定到特定的用户、用户组或ServiceAccount上。如下图所示。
创建Role
Role的定义非常简单,指定namespace,然后就是rules规则。如下面示例中的规则就是允许对default命名空间下的Pod进行GET、LIST操作。
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default # 命名空间 name: role-example rules: - apiGroups: [""] resources: ["pods"] # 可以访问pod verbs: ["get", "list"] # 可以执行GET、LIST操作
创建RoleBinding
有了Role之后,就可以将Role与具体的用户绑定起来,实现这个的就是RoleBinding了。如下所示。
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rolebinding-example namespace: default subjects: # 指定用户 - kind: User # 普通用户 name: user-example apiGroup: rbac.authorization.k8s.io - kind: ServiceAccount # ServiceAccount name: sa-example namespace: default roleRef: # 指定角色 kind: Role name: role-example apiGroup: rbac.authorization.k8s.io
这里的subjects就是将Role与用户绑定起来,用户可以是外部普通用户,也可以是ServiceAccount,这两种用户类型在ServiceAccount有过介绍。绑定后的关系如下图所示。
下面来验证一下授权是否生效。
在前面一个章节使用ServiceAccount中,创建一个Pod,使用了sa-example这个ServiceAccount,而刚刚又给sa-example绑定了role-example这个角色,现在进入到Pod,使用curl命令通过API Server访问资源来验证权限是否生效。
使用sa-example对应的ca.crt和Token认证,查询default命名空间下所有Pod资源,对应创建Role中的LIST。
$ kubectl exec -it sa-pod -- /bin/sh # export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt # TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) # curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pods { "kind": "PodList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/default/pods", "resourceVersion": "10377013" }, "items": [ { "metadata": { "name": "sa-example", "namespace": "default", "selfLink": "/api/v1/namespaces/default/pods/sa-example", "uid": "c969fb72-ad72-4111-a9f1-0a8b148e4a3f", "resourceVersion": "10362903", "creationTimestamp": "2020-07-15T06:19:26Z" }, "spec": { ...
返回结果正常,说明sa-example是有LIST Pod的权限的。再查询一下Deployment,返回如下,说明没有访问Deployment的权限。
# curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/deployments ... "status": "Failure", "message": "deployments is forbidden: User \"system:serviceaccount:default:sa-example\" cannot list resource \"deployments\" in API group \"\" in the namespace \"default\"", ...
Role和RoleBinding作用的范围是命名空间,能够做到一定程度的权限隔离,如下图所示,上面定义role-example就不能访问kube-system命名空间下的资源。
在上面Pod中继续访问,返回如下,说明确实没有权限。
# curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/kube-system/pods ... "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:default:sa-example\" cannot list resource \"pods\" in API group \"\" in the namespace \"kube-system\"", "reason": "Forbidden", ...
在RoleBinding中,还可以绑定其他命名空间的ServiceAccount,只要在subjects字段下添加其他命名空间的ServiceAccount即可。
subjects: # 指定用户 - kind: ServiceAccount # ServiceAccount name: kube-sa-example namespace: kube-system
加入之后,kube-system下kube-sa-example这个ServiceAccount就可以GET、LIST命名空间default下的Pod了,如下图所示。
ClusterRole和ClusterRoleBinding
相比Role和RoleBinding,ClusterRole和ClusterRoleBinding有如下几点不同:
- ClusterRole和ClusterRoleBinding不用定义namespace字段
- ClusterRole可以定义集群级别的资源
可以看出ClusterRole和ClusterRoleBinding控制的是集群级别的权限。
在Kubernetes中,默认定义了非常多的ClusterRole和ClusterRoleBinding,如下所示。
$ kubectl get clusterroles NAME AGE admin 30d cceaddon-prometheus-kube-state-metrics 6d3h cluster-admin 30d coredns 30d custom-metrics-resource-reader 6d3h custom-metrics-server-resources 6d3h edit 30d prometheus 6d3h system:aggregate-customedhorizontalpodautoscalers-admin 6d2h system:aggregate-customedhorizontalpodautoscalers-edit 6d2h system:aggregate-customedhorizontalpodautoscalers-view 6d2h .... view 30d $ kubectl get clusterrolebindings NAME AGE authenticated-access-network 30d authenticated-packageversion 30d auto-approve-csrs-for-group 30d auto-approve-renewals-for-nodes 30d auto-approve-renewals-for-nodes-server 30d cceaddon-prometheus-kube-state-metrics 6d3h cluster-admin 30d cluster-creator 30d coredns 30d csrs-for-bootstrapping 30d system:basic-user 30d system:ccehpa-rolebinding 6d2h system:cluster-autoscaler 6d1h ...
其中,最重要最常用的是如下四个ClusterRole。
- view:拥有查看命名空间资源的权限
- edit:拥有修改命名空间资源的权限
- admin:拥有命名空间全部权限
- cluster-admin:拥有集群的全部权限
使用kubectl describe clusterrole命令能够查看到各个规则的具体权限。
通常情况下,使用这四个ClusterRole与用户做绑定,就可以很好的做到权限隔离。这里的关键一点是理解到Role(规则、权限)与用户是分开的,只要通过Rolebinding来对这两者进行组合就能做到灵活的权限控制。