如何配置 RBAC 权限控制限制用户只能访问特定命名空间

文章导读
想要限制用户只能访问特定命名空间,最稳妥的做法是使用命名空间级别的 Role 配合 RoleBinding,将权限绑定到具体的用户或 ServiceAccount 上,避免使用集群级别的 ClusterRoleBinding。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

想要限制用户只能访问特定命名空间,最稳妥的做法是使用命名空间级别的 Role 配合 RoleBinding,将权限绑定到具体的用户或 ServiceAccount 上,避免使用集群级别的 ClusterRoleBinding

先说结论:通过创建命名空间内的 Role 和 RoleBinding,可以将用户权限严格限定在指定命名空间,这是 Kubernetes 原生支持的标准隔离方案。

  • 适合:多租户集群、开发测试环境隔离、最小权限原则场景
  • 先准备:确认目标命名空间已存在,明确用户需要操作的具体资源类型
  • 验收:使用受限账号尝试访问其他命名空间,确认被拒绝

命令速用版

如果你需要快速创建一个只能访问 dev 命名空间的服务账户,可以直接使用以下命令序列。请根据实际需求修改命名空间名称和资源权限。

# 1. 创建命名空间(如果不存在)
kubectl create namespace dev

# 2. 创建服务账户
kubectl create serviceaccount dev-sa -n dev

# 3. 创建角色,允许对 Pod 和 Service 进行读写
kubectl create role dev-role -n dev `--verb`=get,list,create,update,delete `--resource`=pods,services

# 4. 绑定角色到服务账户
kubectl create rolebinding dev-role-binding -n dev `--role`=dev-role `--serviceaccount`=dev:dev-sa

为什么会这样

Kubernetes 的 RBAC(基于角色的访问控制)机制核心在于“角色定义权限”与“绑定赋予用户”分离。要实现命名空间隔离,关键在于理解 RoleClusterRole 的区别。

Role 是命名空间级别的资源,它定义的权限规则仅在该命名空间内生效。而 ClusterRole 是集群级别的,一旦绑定不当,用户可能获得跨命名空间甚至集群范围的权限。因此,限制特定命名空间访问时,必须使用 Role 定义权限规则,并通过 RoleBinding 将该角色绑定到特定用户、用户组或 ServiceAccount 上。这种设计确保了权限的作用域被物理限制在命名空间边界内。

分步处理

以下是完整的配置流程,包含生成用户可用的 kubeconfig 文件的步骤,方便开发人员使用。

1. 创建 ServiceAccount

ServiceAccount 是集群内部进程或外部用户访问 API 的身份标识。在 1.24 版本之前,创建 ServiceAccount 会自动生成包含 Token 的 Secret,新版本可能需要手动创建或获取 Token。

kubectl create serviceaccount dev-sa -n dev

2. 定义精细化的 Role

不要直接赋予 adminedit 权限,建议根据最小权限原则定义。以下 YAML 示例定义了仅对 Pod 和 Service 的读取权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch"]

3. 创建 RoleBinding

如何配置 RBAC 权限控制限制用户只能访问特定命名空间

将上述角色绑定到步骤 1 创建的服务账户。注意 subjects 中的 namespace 必须与 ServiceAccount 所在的命名空间一致。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: dev
subjects:
- kind: ServiceAccount
  name: dev-sa
  namespace: dev
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

4. 生成 kubeconfig(可选)

为了让开发人员能通过 kubectl 访问,需要提取 Token 并生成配置。获取 Token 的命令如下:

kubectl create token dev-sa -n dev

将获取的 Token 填入 kubeconfig 文件的 token 字段,并设置 default-namespacedev

怎么验证是否生效

配置完成后,必须进行双向验证,确保“能访问允许的”且“不能访问禁止的”。

1. 验证允许的操作

使用配置好的 kubeconfig 尝试列出 dev 命名空间下的 Pod:

kubectl get pods -n dev `--kubeconfig`=user-kubeconfig

如果返回资源列表,说明权限生效。

2. 验证禁止的操作

尝试访问其他命名空间(如 default):

kubectl get pods -n default `--kubeconfig`=user-kubeconfig

预期结果应返回 Error from server (Forbidden) 类似错误。

如何配置 RBAC 权限控制限制用户只能访问特定命名空间

3. 使用 auth can-i 检查

管理员可以使用以下命令模拟用户权限检查:

kubectl auth can-i list pods -n dev `--as`=system:serviceaccount:dev:dev-sa

常见坑

1. API Groups 混淆

核心资源(如 Pod、Service)的 apiGroups 为空字符串 [""],而 Deployment 等资源属于 apps 组。如果在 Role 中写错 API 组,权限将不会生效。

2. ServiceAccount Token 变化

在 Kubernetes 1.24 版本之后,ServiceAccount 不再自动创建长期有效的 Secret Token,建议使用 kubectl create token 命令获取有时效性的 Token,或者手动创建 Secret 来存储凭证。

3. 绑定对象错误

RoleBinding 中,roleRefkind 必须与定义的角色类型一致。如果用 RoleBinding 绑定了 ClusterRole,权限范围仍限制在命名空间内;但如果误用 ClusterRoleBinding 绑定了 Role,则配置会报错或无效。

4. 命名空间遗漏

创建 Role 和 RoleBinding 时,必须显式指定 -n 或在 YAML 中写明 namespace。如果遗漏,资源可能默认创建在 default 命名空间,导致目标命名空间下无权限。

参考来源

  • 华为云云容器引擎 CCE 用户指南 - 配置命名空间权限 (Kubernetes RBAC 授权)
  • 阿里云容器服务 ACK 文档 - 使用自定义 RBAC 限制集群内资源操作
  • Kubernetes 官方社区文档 - 使用 RBAC 授权
  • 阿里云服务网格 ASM 文档 - 授予 RAM 用户和 RAM 角色 RBAC 权限