3. 基于角色的访问控制(RBAC)基础:ServiceAccount、Role与ClusterRole、RoleBinding与ClusterRoleBinding、RBAC策略设计原则
在多租户隔离集群中,基于角色的访问控制(RBAC)是Kubernetes内置的授权机制,用于精细控制用户、服务账户对集群资源的操作权限。RBAC通过“主体-角色-资源”三元模型,实现最小权限原则,是构建安全多租户环境的基石。
3.1 核心概念与主体
RBAC体系包含四个核心API对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,以及两个关键主体:User(用户)和ServiceAccount(服务账户)。
| 对象 | 作用域 | 用途 | 绑定对象 |
|---|---|---|---|
| Role | 命名空间 | 定义对特定命名空间内资源的访问权限 | RoleBinding |
| ClusterRole | 集群范围 | 定义集群级别资源(如Node、PV)或跨命名空间资源的权限 | ClusterRoleBinding / RoleBinding |
| RoleBinding | 命名空间 | 将Role或ClusterRole绑定到主体,权限仅限该命名空间 | User / ServiceAccount / Group |
| ClusterRoleBinding | 集群范围 | 将ClusterRole绑定到主体,权限作用于整个集群 | User / ServiceAccount / Group |
| ServiceAccount | 命名空间 | Pod内进程使用的身份,用于调用Kubernetes API | — |
关键区别:Role是命名空间级别的,只能授予对同一命名空间内资源的访问权限;ClusterRole是集群级别的,可以授予对集群范围资源(如Node、PersistentVolume)或所有命名空间资源的访问权限。通过RoleBinding引用ClusterRole,可以实现跨命名空间的权限复用。
3.2 ServiceAccount:Pod的身份凭证
ServiceAccount是Kubernetes中为Pod提供的身份标识。每个命名空间会自动创建一个名为default的ServiceAccount。当Pod启动时,可以指定使用哪个ServiceAccount,其对应的认证令牌()会被自动挂载到Pod的文件系统中。
# 创建自定义ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
# Pod引用自定义ServiceAccount
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
namespace: production
spec:
serviceAccountName: app-sa
containers:
- name: app-container
image: my-app:latest
安全提示:避免使用默认的
default ServiceAccount运行生产工作负载。应为每个微服务或租户创建独立的ServiceAccount,并授予最小必要权限。同时,建议禁用自动挂载API凭据(automountServiceAccountToken: false),除非明确需要。
3.3 Role与ClusterRole:定义权限集合
Role和ClusterRole使用相同的规则格式,通过apiGroups、resources、verbs三个维度定义权限。
# Role示例:授予对Pod和Deployment的只读权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""] # 核心API组
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
# ClusterRole示例:授予对集群级别资源的只读权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-reader
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes", "namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
权限粒度控制:可以使用
resourceNames字段将权限限制到特定资源实例。例如,只允许对名为my-config的ConfigMap进行更新操作:resourceNames: ["my-config"]。
3.4 RoleBinding与ClusterRoleBinding:将权限授予主体
绑定操作将角色与主体关联起来,使主体获得角色中定义的权限。
# RoleBinding:将pod-reader角色授予ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: ServiceAccount
name: app-sa
namespace: development
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
# ClusterRoleBinding:将cluster-reader角色授予用户
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-reader-binding
subjects:
- kind: User
name: "ops-admin@example.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-reader
apiGroup: rbac.authorization.k8s.io
绑定技巧:通过RoleBinding引用ClusterRole,可以在命名空间内复用集群级别的权限模板。例如,创建一个名为
namespace-admin的ClusterRole,然后在每个租户命名空间中通过RoleBinding引用它,即可实现一致的权限管理。
3.5 RBAC策略设计原则
设计多租户RBAC策略时,应遵循以下核心原则:
- 最小权限原则:只授予完成工作所需的最小权限集合。避免使用
*通配符授予所有权限。 - 职责分离:将管理权限(如创建Role、RoleBinding)与业务操作权限(如管理Pod、Service)分开。
- 使用ClusterRole模板:定义通用的ClusterRole作为权限模板,通过RoleBinding在命名空间内复用。
- 避免直接使用User:优先使用ServiceAccount作为Pod的身份,结合外部身份提供商(如OIDC)管理用户。
- 定期审计:使用
kubectl auth can-i命令和审计日志检查权限配置是否符合预期。 - 分组管理:利用Group(组)批量管理用户权限,减少单个用户绑定带来的维护成本。
3.6 多租户场景下的RBAC最佳实践
| 场景 | 推荐做法 | 示例 |
|---|---|---|
| 租户管理员 | 创建ClusterRole授予命名空间管理权限,通过RoleBinding绑定到租户ServiceAccount | kubectl create rolebinding tenant-admin --clusterrole=namespace-admin --serviceaccount=tenant-a:admin-sa -n tenant-a |
| 只读用户 | 使用ClusterRole定义只读权限,通过RoleBinding绑定到用户组 | kubectl create rolebinding read-only --clusterrole=view --user=dev@example.com -n tenant-a |
| Pod间通信 | 为每个微服务创建独立ServiceAccount,结合NetworkPolicy实现网络隔离 | ServiceAccount: frontend-sa, backend-sa |
| 跨命名空间访问 | 使用ClusterRole授予跨命名空间资源访问权限,通过ClusterRoleBinding绑定 | kubectl create clusterrolebinding cross-ns-reader --clusterrole=namespace-reader --user=auditor@example.com |
聚合ClusterRole:Kubernetes 1.9+支持通过
aggregationRule将多个ClusterRole合并为一个。例如,创建一个admin ClusterRole,自动聚合所有带有rbac.authorization.k8s.io/aggregate-to-admin: "true"标签的ClusterRole。这种方式简化了权限的模块化管理。
3.7 验证与调试RBAC配置
使用以下命令验证RBAC配置是否生效:
# 检查当前用户是否有权限创建Pod
kubectl auth can-i create pods
# 以特定ServiceAccount身份检查权限
kubectl auth can-i list pods --as=system:serviceaccount:production:app-sa
# 检查特定命名空间内的权限
kubectl auth can-i delete deployments --namespace=tenant-a
# 查看RoleBinding的详细信息
kubectl describe rolebinding read-pods -n development
# 查看ServiceAccount的权限
kubectl get rolebindings,clusterrolebindings --all-namespaces | grep app-sa
常见陷阱:
- RoleBinding只能引用同一命名空间内的ServiceAccount,跨命名空间绑定需要使用ClusterRoleBinding。
- 删除Role或ClusterRole不会自动删除已存在的RoleBinding,但绑定会失效。
- 避免在ClusterRole中使用
verbs: ["*"],这会授予所有操作权限,违背最小权限原则。
通过合理设计RBAC策略,结合ServiceAccount、Role、ClusterRole、RoleBinding和ClusterRoleBinding,可以为多租户集群构建细粒度、可审计、易维护的访问控制体系,确保每个租户只能访问其授权范围内的资源。