介绍
K8S(Kubernetes)的RBAC(Role-Based Access Control,基于角色的访问控制)是一种权限控制机制,它允许管理员通过定义角色来限制用户对集群资源的访问权限。RBAC是Kubernetes中一个核心的授权策略,通过它,管理员可以实施精细化的权限管理,确保只有经过授权的用户或用户组才能执行特定的操作。
RBAC在Kubernetes中主要由四个关键组件构成:Role、ClusterRole、RoleBinding和ClusterRoleBinding。
- Role:用于定义对命名空间内资源的访问权限。Role只能用于授予对某个特定命名空间中资源的访问权限。
- ClusterRole:与Role类似,但用于定义对集群范围内资源的访问权限。ClusterRole可以授予对集群中所有命名空间的资源或非资源端点的访问权限。
- RoleBinding:用于将Role绑定到一个或多个用户、服务账户或用户组,从而控制这些实体对命名空间内资源的访问。
- ClusterRoleBinding:用于将ClusterRole绑定到一个或多个用户、服务账户或用户组,控制这些实体对集群范围内资源的访问。
使用RBAC时,管理员可以定义角色,并为这些角色分配适当的权限。然后,通过RoleBinding或ClusterRoleBinding将角色绑定到特定的用户或用户组。这样,用户只能执行其角色所允许的操作,而无法访问或修改未授权的资源。
Role 和 ClusterRole
Role 举例
下面是一个位于 "default" 名字空间的 Role 的示例,可用来授予对 Pod 的读访问权限:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
resources: ["pods"]
verbs: ["get", "watch", "list"]
字段解释
- apiVersion 指定了 Kubernetes API 的版本,这里是 rbac.authorization.k8s.io/v1,表示使用了 Kubernetes 的 RBAC API 版本
- kind 指定了 Kubernetes 资源的类型,这里是 Role,表示定义了一个角色。
- rules 指定了角色的权限规则。
- apiGroups 指定了 API 组,这里是 [""],表示核心 API 组。
- resources 指定了资源类型,这里是 ["pods"],表示 Pods 资源。
- verbs 指定了允许的操作,这里是 ["get", "watch", "list"],表示允许执行 get、watch 和 list 操作。
apiGroups 介绍
核心 API 组:
- pods: Pod 是 Kubernetes 中最小的可部署对象,代表集群中的一个运行中的应用程序实例。
- services: Service 定义了一组Pod的逻辑集合以及访问这些Pod的策略,通常用于创建应用程序的网络端点。
- nodes: Node 是 Kubernetes 集群中的一个工作节点,可以是虚拟机或物理机器。
- namespaces: Namespace 是 Kubernetes 中用于多租户的虚拟集群的一种方式。它允许将 Kubernetes 集群划分为多个虚拟集群,以便在同一集群中运行多个团队或用户的应用程序。
- persistentvolumes: PersistentVolume(PV)是 Kubernetes 中的一种 API 对象,它抽象了存储系统,为用户提供了一种将存储挂载到 Pod 中的方式。
- persistentvolumeclaims: PersistentVolumeClaim(PVC)是 Kubernetes 中的一种 API 对象,它是 Pod 中对存储资源的一种请求。
describe 查看
yaml
[root@master01 yaml]# kubectl describe role pod-reader
Name: pod-reader
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get watch list]
apiGroups 组查看
bash
kubectl api-resources --verbs list
列举几种用法
在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,可以这样写:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
也可以通过 resourceNames 列表按名称引用资源。 在指定限制为资源的单个实例。 下面的例子中限制可以 get 和 update 一个名为 my-configmap 的 ConfigMap:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
使用通配符 * 批量引用所有的 resources、apiGroups 和 verbs 对象,无需逐一引用。
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example.com-superuser # 此角色仅作示范,请勿使用
rules:
- apiGroups: ["example.com"]
resources: ["*"]
verbs: ["*"]
Role 示例
允许读取在核心 API 组下的 "pods":
yaml
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
resources: ["pods"]
verbs: ["get", "list", "watch"]
允许读取核心 API 组中的 Pod 和读/写 "batch" API 组中的 Job 资源:
yaml
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Pod 资源的名称为 "pods"
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
# 在 HTTP 层面,用来访问 Job 资源的名称为 "jobs"
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允许读取名称为 "my-config" 的 ConfigMap(需要通过 RoleBinding 绑定以限制为某名字空间中特定的 ConfigMap):
yaml
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 ConfigMap 资源的名称为 "configmaps"
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
ClusterRole 示例
Role 和 ClusterRole 的区别就是 Role 有命名空间的概念,ClusterRole 没有,剩下的参数都和 Role 是一样的。
下面是一个 ClusterRole 的示例:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Role 或 ClusterRole 对象的名称必须是合法的路径分段名称。
RoleBinding 和 ClusterRoleBinding
角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干主体(Subject)(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。 RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。
一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果将某 ClusterRole 绑定到集群中所有名字空间,需要使用 ClusterRoleBinding。
RoleBinding 示例
下面的例子中的 RoleBinding 将 "pod-reader" Role 授予在 "default" 名字空间中的用户 "jane"。 这样,用户 "jane" 就具有了读取 "default" 名字空间中所有 Pod 的权限。
yaml
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该名字空间中有一个名为 "pod-reader" 的 Role
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# 你可以指定不止一个"subject(主体)"
- kind: User # 常用 ServiceAccount
name: jane # "name" 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
kind: Role # 此字段必须是 Role 或 ClusterRole
name: pod-reader # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
apiGroup: rbac.authorization.k8s.io
解释 kind: User 可选的参数
- User: 表示一个具体的用户。
- ServiceAccount: 表示一个服务账户。
- Group: 表示一个用户组。
在 Kubernetes 中,使用 ServiceAccount 更为常见,因为它们是与命名空间相关的,并且通常用于为 Pod 提供身份验证和授权。而 User 对象则更适用于基于用户名和密码的身份认证。
RoleBinding 示例
下面示例是 RoleBinding 中的片段,仅展示其 subjects 的部分。
对于名称为 alice@example.com 的用户:
yaml
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
对于名称为 frontend-admins 的用户组:
yaml
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
对于 kube-system 名字空间中的默认服务账户:
yaml
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
对于 "qa" 名称空间中的所有服务账户:
yaml
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
对于在任何名字空间中的服务账户:
yaml
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
serviceaccount 创建方法
bash
kubectl create serviceaccount jane -n default
ClusterRoleBinding 示例
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。 下面的 ClusterRoleBinding 允许 "manager" 组内的所有用户访问任何名字空间中的 Secret。
yaml
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 "manager" 组中的任何人访问任何名字空间中的 Secret 资源
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的 roleRef 将导致合法性检查错误。 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。
这种限制有两个主要原因:
- 将 roleRef 设置为不可以改变,这使得可以为用户授予对现有绑定对象的 update 权限, 这样可以让他们管理主体列表,同时不能更改被授予这些主体的角色。
- 针对不同角色的绑定是完全不一样的绑定。要求通过删除/重建绑定来更改 roleRef, 这样可以确保要赋予绑定的所有主体会被授予新的角色(而不是在允许或者不小心修改了 roleRef 的情况下导致所有现有主体未经验证即被授予新角色对应的权限)。
命令 kubectl auth reconcile 可以创建或者更新包含 RBAC 对象的清单文件, 并且在必要的情况下删除和重新创建绑定对象,以改变所引用的角色。
kubectl auth reconcile 用法
尚不存在的对象会被创建,如果对应的名字空间也不存在,必要的话也会被创建。 已经存在的角色会被更新,使之包含输入对象中所给的权限。如果指定了 --remove-extra-permissions,可以删除额外的权限。
举例:
添加 "--dry-run=client" 输出需要修改的部分,不会真正的执行。
bash
kubectl auth reconcile -f my-rbac-rules.yaml --dry-run=client
保留角色(roles)中的额外权限和绑定(bindings)中的其他主体:
bash
kubectl auth reconcile -f my-rbac-rules.yaml
删除角色(roles)中的额外权限和绑定中的其他主体:
bash
kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
聚合 ClusterRole
配置默认 ClusterRole 规则
举例:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregate-cron-tabs-edit
labels:
# 添加以下权限到默认角色 "admin" 和 "edit" 中
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aggregate-cron-tabs-view
labels:
# 添加以下权限到 "view" 默认角色中
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch"]
下面是一个聚合 ClusterRole 的示例:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels: # 需要添加的标签
rbac.authorization.k8s.io/aggregate-to-view: "true" # 可以添加多组标签,添加那个 ClusterRole 的标签就会拥有谁的权限。
rules: [] # 控制面自动填充这里的规则
注意:
控制平面会覆盖你在聚合 ClusterRole 的 rules 字段中手动指定的所有值。 如果你想更改或添加规则,请在被 aggregationRule 所选中的 ClusterRole 对象上执行变更。
命令行工具创建 RBAC 权限
RBAC 常用权限列表
查看权限
- get:获取指定资源的信息
- list:获取资源列表的信息
- watch:监视资源的变化
创建权限:
- create:创建新资源
- apply:应用资源配置
- patch:部分更新资源
- replace:替换资源
更新权限:
- update:更新现有资源
- edit:编辑资源配置
删除权限:
- delete:删除资源
- evict:驱逐 Pod
执行权限:
- exec:在容器内执行命令
- portforward:端口转发
- attach:附加到容器上
- connect:与容器建立连接
权限操作:
- bind:绑定资源
- use:使用资源
- proxy:代理请求
其他操作:
- watch:监视资源变化
- finalize:完成资源的操作
- approve:批准资源的操作
- suspend:暂停资源的操作