RBAC
RBAC(Role-Based Access Control)包含以下几个重要的概念:
-
Subject:代表的是请求 API 资源的实体,包含 User、Group、ServiceAccount 三种类型。
-
角色(Role):Role 定义了一组操作权限,例如对某个命名空间下资源的读取、创建或删除等操作。
-
集群角色(ClusterRole):类似于 Role,但作用范围更广,可以授权对整个集群中资源的操作权限。
-
角色绑定(RoleBinding):RoleBinding 负责将 Role 与 Subject(User、Group 或 ServiceAccount)绑定,从而 Subject 就具有了相应的权限。
-
集群角色绑定(ClusterRoleBinding):ClusterRoleBinding 负责将 ClusterRole 与 Subject(User、Group 或 ServiceAccount)绑定,从而 Subject 就具有了相应的在整个集群范围内的权限。
Subject
Subject 代表了请求 API 资源的实体,它可以是以下三种类型之一:
- User:通常用于集群外部的身份表示。
- Group:一组用户的集合,可以将相同权限授予属于该组的所有用户。对于 ServiceAccount 来说,它的 group 是其所处的 namespace,group 表示某 namespace 下的所有 serviceaccount。
- ServiceAccount:Kubernetes 内部用于使用 Pod 访问 APIServer 的身份。每个 Namespace 中默认都会有一个名为 default 的 ServiceAccount,也可以创建自定义的 ServiceAccount。default ServiceAccount 通常需要给定权限后才能对 APIServer 做写操作。
Subject 通过 RoleBinding/ClusterRoleBinding 与 Role/ClusterRole 进行绑定,绑定之后 Subject 根据其绑定的Role/ClusterRole 来决定它在 Kubernetes 集群中能访问哪些资源以及可以执行的操作。
Role/ClusterRole
Role 是一系列权限的集合,比如包含了读取和列出 Pod 的权限。Role 只能用来给某个特定的 namespace 中的资源作授权,对多 namespace、集群级别的资源或非资源类的 API(如 /healthz)使用 ClusterRole。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
RoleBinding/ClusterRoleBinding
RoleBinding/ClusterRoleBinding 负责建立 Role/ClusterRole 与 Subject 的联系,如图所示,
- 一般来说 RoleBinding 用于绑定 Role 和 Subject。其实,RoleBinding 也是可以绑定 ClusterRole 的,只是绑定之后只有在 RoleBinding 所在 namespace 才有权限。举个例子,read-secrets RoleBinding 绑定的是 ClusterRole,但是它只有 development namespace 的权限。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
-
如何给 Subject 为 Group 的授予权限?分为普通用户的 Group 和 ServiceAccount Group 两种。
给 manager 这个 group 授予权限。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-secrets-global subjects: - kind: Group name: manager apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
给 qa namespace 下所有的 serviceaccount 都赋予权限。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: read-secrets-global subjects: - kind: Group name: system:serviceaccounts:qa apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: secret-reader apiGroup: rbac.authorization.k8s.io
举例
访问 APIServer 时使用较多的两种认证方式,分别是 X509 证书和 ServiceAccount。下面我们介绍在这两种认证的基础之上,进行鉴权的例子。
X509 证书
在介绍 Kubernetes 证书的时候,我们介绍过证书中的 Subject 字段包含了待认证的用户信息,其中 O 表示用户归属的group,CN 表示 user。比如,下图是 /etc/kubernetes/admin.conf 中 client 使用的证书内容,其中 group 是 System:masters,user 是 kubernetes-admin。
那么 group 为 System:masters,user 为 kubernetes-admin 被授予的权限是怎么样的呢?这主要看 cluster-admin 这个 ClusterRoleBinding。可以看到它将 system:masters group 和 cluster-admin ClusterRole 进行了绑定,也就是意味着 cluster-admin ClusterRole 中指定的权限被授予给了 group 为 System:masters 的用户。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-11-14T16:20:28Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "****"
uid: d25006dd-5636-49e0-b29c-6*****41f0e64b
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2023-11-14T16:20:28Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "105"
uid: 94dee698-aec1-45ca-954d-da39590af485
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
- nonResourceURLs:
- '*'
verbs:
- '*'
ServiceAccount
下面是一个 ClusterRoleBinding 将 ClusterRole 授予 ServiceAccount 的例子。那么,使用 calico-kube-controllers ServiceAccount 的 Pod 就具有了 calico-kube-controllers ClusterRole 中包含的权限了。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
...
name: calico-kube-controllers
resourceVersion: "1305"
uid: 6ed06b2f-dba8-40fc-a0cc-**********
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: calico-kube-controllers
subjects:
- kind: ServiceAccount
name: calico-kube-controllers
namespace: kube-system
注意事项
- 防止海量的角色和角色绑定对象,因为大量的对象会导致鉴权效率低,同时给 apiserver 增加负担。
- 如果没有权限的时候怎么办?SSH 到 master 节点,然后开启代理,通过 inscure port 访问 apiserver 可绕过鉴权,当需要做某些管理操作,但是又没有权限的时候可以使用(不推荐)。
相关链接
官方文档:https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/