摘要:RBAC(基于角色的访问控制)是 Kubernetes 安全体系的核心,用于控制主体(用户、组、ServiceAccount)对哪些资源可执行哪些操作。本文详解 RBAC 四大资源、内置角色、ServiceAccount 机制、Token 安全、ClusterRole 聚合、Pod Security Context 及生产实践 FAQ。
一、为什么需要 RBAC?
未启用 RBAC 时,集群默认可能允许过宽权限,导致任意用户可删除生产 Pod、读取 Secret 或拥有管理员权限。RBAC 通过细粒度授权,将权限限定在必要范围内。
使用 RBAC
开发者 A
仅 dev 命名空间 Pod
实习生 B
仅查看 default
CI/CD
特定命名空间部署
无 RBAC
开发者 A
可删除生产 Pod
实习生 B
可读取所有 Secret
CI/CD
集群管理员权限
说明:无 RBAC 时权限不受控;启用 RBAC 后可按主体、命名空间和资源类型限制权限。
二、RBAC 四大资源完整对比
RBAC 由四类对象组成:Role/ClusterRole 定义权限,RoleBinding/ClusterRoleBinding 将权限绑定到主体。
Role 命名空间级
RoleBinding
ClusterRole 集群级
ClusterRoleBinding
Subject: User/Group/SA
| 对象 | 作用范围 | 说明 |
|---|---|---|
| Role | 单个命名空间 | 定义该命名空间内的权限,不可跨命名空间复用 |
| ClusterRole | 整个集群 | 定义集群级或可复用的权限,可被多个 RoleBinding 引用 |
| RoleBinding | 单个命名空间 | 将 Role 或 ClusterRole 绑定到主体,仅在该命名空间生效 |
| ClusterRoleBinding | 整个集群 | 将 ClusterRole 绑定到主体,全集群生效 |
2.1 主体(Subject)
| 类型 | 说明 |
|---|---|
| User | 外部认证系统提供的用户标识,如 OIDC、x509 |
| Group | 用户组,用于批量授权 |
| ServiceAccount | Pod 使用的身份,用于应用访问 API |
2.2 组合规则
| 组合 | 生效范围 |
|---|---|
| Role + RoleBinding | 仅 RoleBinding 所在命名空间 |
| ClusterRole + RoleBinding | 仅 RoleBinding 所在命名空间(复用 ClusterRole) |
| ClusterRole + ClusterRoleBinding | 全集群 |
三、权限模型
RBAC 权限由主体(Subject)、操作(Verb)和资源(Resource)组成。
Subject 谁
权限
Verb 什么操作
Resource 什么资源
3.1 Verbs(操作)
| Verb | 说明 |
|---|---|
| get | 获取单个资源 |
| list | 列出资源 |
| watch | 监听资源变化 |
| create | 创建资源 |
| update | 更新资源 |
| patch | 部分更新资源 |
| delete | 删除资源 |
| deletecollection | 批量删除 |
| * | 所有操作 |
3.2 Resources(资源)
常见资源包括:pods、services、deployments、configmaps、secrets、nodes、namespaces、persistentvolumes、pods/log、pods/exec 等。子资源用 / 表示,如 pods/status。
四、Role 与 RoleBinding
4.1 创建 Role
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: dev
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
| 字段 | 说明 |
|---|---|
| apiGroups | 空字符串表示 core API 组 |
| resources | 资源类型复数形式 |
| verbs | 允许的操作列表 |
4.2 创建 RoleBinding
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: dev
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
| 字段 | 说明 |
|---|---|
| subjects | 被授权的主体列表 |
| roleRef | 引用的 Role/ClusterRole,创建后不可修改 |
用户 alice
RoleBinding
Role: pod-reader
允许: get/list/watch pods
说明 :alice 在 dev 命名空间可执行 kubectl get pods -n dev、kubectl logs <pod> -n dev,但不能删除 Pod 或访问其他命名空间。
五、ClusterRole 与 ClusterRoleBinding
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-viewer
rules:
- apiGroups: [""]
resources: ["pods", "services", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: viewer-binding
subjects:
- kind: Group
name: developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-viewer
apiGroup: rbac.authorization.k8s.io
说明 :cluster-viewer 为集群级只读角色,绑定到 developers 组后,组内用户可在任意命名空间查看 pods、services、nodes、deployments、statefulsets。
六、ClusterRole + RoleBinding 复用
ClusterRole 可被 RoleBinding 引用,从而在指定命名空间内生效,实现跨命名空间复用同一角色定义。
yaml
# 使用内置 view ClusterRole,在 dev 命名空间绑定给 alice
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: alice-view-dev
namespace: dev
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
ClusterRole view
RoleBinding dev
alice
仅 dev 命名空间
七、内置 ClusterRole 详解
| 内置角色 | 说明 | 典型权限 |
|---|---|---|
| cluster-admin | 集群完全管理权限 | 包括 RBAC、Namespace、所有资源 |
| admin | 命名空间内管理权限 | 不含 ResourceQuota、Namespace、RBAC |
| edit | 命名空间内编辑权限 | 可修改大部分资源,不含 RBAC、Namespace |
| view | 命名空间内只读权限 | 不可查看 Secret、少部分只读 |
admin:可创建 RoleBinding、管理大部分资源,适合命名空间管理员。
edit:可创建 Deployment、Service、ConfigMap 等,适合开发者部署应用。
view:仅 get、list、watch,适合运维查看状态。
八、ServiceAccount 与 Pod 关联机制
ServiceAccount 是 Pod 访问 API Server 时使用的身份。未指定时,Pod 使用 default ServiceAccount。
User 人类身份
API Server
ServiceAccount Pod 身份
Pod
关联机制 :Pod 的 spec.serviceAccountName 指定 ServiceAccount,kubelet 创建 Pod 时将 Token 挂载到 /var/run/secrets/kubernetes.io/serviceaccount/token,应用通过该 Token 调用 API。
8.1 Token 挂载与安全
| 配置 | 说明 |
|---|---|
| 默认行为 | 每个 Pod 自动挂载 default SA 的 Token |
| automountServiceAccountToken: false | 禁止自动挂载,提升安全 |
| 按 Pod 配置 | spec.automountServiceAccountToken: false |
| 按 ServiceAccount 配置 | automountServiceAccountToken: false 作用于使用该 SA 的 Pod |
yaml
apiVersion: v1
kind: Pod
metadata:
name: sensitive-app
spec:
serviceAccountName: minimal-sa
automountServiceAccountToken: false # 不需要调用 API 时禁用
containers:
- name: app
image: my-app:v1
8.2 为 CI/CD 创建 ServiceAccount
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: deploy-bot
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployer
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deploy-bot-binding
namespace: production
subjects:
- kind: ServiceAccount
name: deploy-bot
namespace: production
roleRef:
kind: Role
name: deployer
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
name: ci-cd-runner
namespace: production
spec:
serviceAccountName: deploy-bot
containers:
- name: runner
image: ci-runner:v1
九、ClusterRole Aggregation 机制
Kubernetes 内置的 view、edit、admin 等 ClusterRole 通过 aggregation 机制组合多个规则。自定义 ClusterRole 可通过 aggregationRule 和特定 label 被聚合到内置角色:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: custom-metrics-reader
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["custom.metrics.k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
工作原理 :带 rbac.authorization.k8s.io/aggregate-to-view: "true" 的 ClusterRole 会被自动聚合到 view 角色,无需修改内置角色定义。
十、Pod Security Context
Security Context 用于限制 Pod 和容器的安全行为。
10.1 Pod 级别 securityContext
yaml
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: my-app:v1
| 字段 | 说明 |
|---|---|
| runAsNonRoot | 禁止以 root 运行 |
| runAsUser | 运行用户 UID |
| runAsGroup | 运行用户组 GID |
| fsGroup | 挂载卷的组所有权 |
| seccompProfile | 系统调用过滤 |
10.2 容器级别 securityContext
yaml
containers:
- name: app
image: my-app:v1
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
| 字段 | 说明 |
|---|---|
| allowPrivilegeEscalation | 禁止权限提升 |
| readOnlyRootFilesystem | 只读根文件系统 |
| capabilities.drop | 移除 Linux capabilities |
十一、常用命令
bash
# 检查当前用户权限
kubectl auth can-i create pods
kubectl auth can-i delete deployments -n production
kubectl auth can-i '*' '*'
# 以其他主体检查权限
kubectl auth can-i get pods --as=alice -n dev
kubectl auth can-i create deployments --as=system:serviceaccount:production:deploy-bot
# 查看 RBAC 资源
kubectl get roles -n dev
kubectl get rolebindings -n dev
kubectl get clusterroles
kubectl get clusterrolebindings
# 查看详情
kubectl describe role pod-reader -n dev
kubectl describe clusterrole cluster-admin
# 创建 Token(临时)
kubectl create token deploy-bot -n production --duration=1h
十二、安全最佳实践
| 类别 | 建议 |
|---|---|
| RBAC | 最小权限原则;使用 ServiceAccount 而非共享管理员凭证;定期审计;避免滥用 cluster-admin |
| ServiceAccount | 不需要 API 访问的 Pod 设置 automountServiceAccountToken: false |
| Pod 安全 | 非 root 运行;设置 securityContext;只读根文件系统;限制 capabilities |
| 网络安全 | 使用 NetworkPolicy;加密 etcd;启用 API Server 审计 |
| 镜像安全 | 使用可信镜像仓库;扫描漏洞;固定镜像版本 |
十三、FAQ
13.1 权限不足如何排查?
-
使用
kubectl auth can-i模拟目标主体和操作:bashkubectl auth can-i create pods -n dev --as=alice kubectl auth can-i get secrets --as=system:serviceaccount:prod:my-sa -n prod -
检查 RoleBinding/ClusterRoleBinding 是否绑定正确主体
-
确认 Role/ClusterRole 的 rules 是否包含所需 verb 和 resource
-
跨命名空间访问时,确认 RoleBinding 在目标命名空间存在
13.2 最小权限原则如何实践?
- 按命名空间拆分:不同团队使用不同命名空间 + RoleBinding
- 按资源拆分:只读用 view,部署用 edit,避免直接给 admin
- ServiceAccount 单独创建:每个应用/CI 使用独立 SA,权限最小化
- 定期审计:
kubectl get rolebindings,clusterrolebindings -A -o yaml审查
13.3 ServiceAccount 安全建议?
- 不需要调用 API 的 Pod 设置
automountServiceAccountToken: false - 使用
kubectl create token创建短期 Token,而非长期 Secret - 避免在生产环境使用 default SA 部署有权限的应用
- 为不同用途创建专用 SA,如 deploy-bot、monitor-sa
13.4 如何快速赋予某用户某命名空间的管理权限?
bash
kubectl create rolebinding alice-admin \
--clusterrole=admin \
--user=alice \
-n dev
13.5 跨命名空间访问如何配置?
若需让某主体访问多个命名空间,复用同一 ClusterRole,为每个命名空间创建 RoleBinding:
bash
for ns in dev staging prod; do
kubectl create rolebinding alice-view --clusterrole=view --user=alice -n $ns
done
十四、总结
| 对象 | 作用 |
|---|---|
| Role / ClusterRole | 定义权限(谁、对什么资源、做什么操作) |
| RoleBinding / ClusterRoleBinding | 将权限授予主体 |
| ServiceAccount | Pod 访问 API 的身份 |
| SecurityContext | Pod/容器安全配置 |
RBAC 四大对象
Role/ClusterRole
RoleBinding/ClusterRoleBinding
定义权限
授权
最小权限原则