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策略时,应遵循以下核心原则:

  1. 最小权限原则:只授予完成工作所需的最小权限集合。避免使用*通配符授予所有权限。
  2. 职责分离:将管理权限(如创建Role、RoleBinding)与业务操作权限(如管理Pod、Service)分开。
  3. 使用ClusterRole模板:定义通用的ClusterRole作为权限模板,通过RoleBinding在命名空间内复用。
  4. 避免直接使用User:优先使用ServiceAccount作为Pod的身份,结合外部身份提供商(如OIDC)管理用户。
  5. 定期审计:使用kubectl auth can-i命令和审计日志检查权限配置是否符合预期。
  6. 分组管理:利用Group(组)批量管理用户权限,减少单个用户绑定带来的维护成本。
RBAC权限模型架构图 主体 (Subjects) User ServiceAccount Group 绑定 (Binding) RoleBinding ClusterRoleBinding 角色 (Role) Role (命名空间) ClusterRole (集群) 资源 (Resources) 命名空间资源: Pod, Service, ConfigMap, Secret, Deployment 集群资源: Node, PersistentVolume, Namespace, StorageClass 子资源: Pod/log, Pod/exec, Deployment/scale 设计原则 1. 最小权限:只授予必要的 verbs 和 resources 2. 职责分离:管理权限与业务权限分开 3. 模板复用:使用 ClusterRole 作为权限模板,通过 RoleBinding 在命名空间内引用 4. 定期审计:使用 kubectl auth can-i 验证权限配置

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,可以为多租户集群构建细粒度、可审计、易维护的访问控制体系,确保每个租户只能访问其授权范围内的资源。