- 1. 什么是 RBAC
- 2. Role 与 ClusterRole 详解
- 3. RoleBinding 与 ClusterRoleBinding
- 4. ServiceAccount 与 RBAC
- 5. 实战演练:多租户 RBAC 配置
- 6. CKS 考试高频 RBAC 场景
- 7. RBAC 最佳实践 (Best Practices)
- 8. 常见错误与解决办法
- 9. 测验
1. 什么是 RBAC
Kubernetes 的 RBAC(Role-Based Access Control) 是把集群内 API 资源的访问以 基于角色 的方式加以控制的授权(Authorization)机制。只要 kube-apiserver 设置了 --authorization-mode=RBAC 标志就会启用。
RBAC 的核心原则是 最小权限原则(Principle of Least Privilege)。所有用户与服务账户都只应被授予完成工作所必需的最小权限。
1.1 RBAC 的 4 个核心资源
| 资源 | 作用域 | 用途 |
|---|---|---|
Role | 命名空间 | 定义特定命名空间内的资源权限 |
ClusterRole | 整个集群 | 集群范围资源或多个命名空间通用的权限 |
RoleBinding | 命名空间 | 在特定命名空间中把 Role 或 ClusterRole 绑定到 Subject |
ClusterRoleBinding | 整个集群 | 在整个集群范围把 ClusterRole 绑定到 Subject |
2. Role 与 ClusterRole 详解
2.1 创建命名空间级 Role
# dev-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""] # core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
2.2 创建 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-viewer
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["nodes"]
verbs: ["get", "list"]
2.3 Aggregated ClusterRole
CKS 考试中的高频 Aggregated ClusterRole 模式:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
rules:
- apiGroups: [""]
resources: ["services", "endpoints", "pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 会被自动填充
3. RoleBinding 与 ClusterRoleBinding
3.1 RoleBinding:在命名空间内授予权限
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: ci-bot
namespace: development
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
3.2 把 ClusterRole 用于 RoleBinding (重要!)
把 ClusterRole 关联到 RoleBinding 之后,它只在该命名空间中有效。想把一套通用权限复用到多个命名空间时非常好用:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-staging
namespace: staging
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole # 虽然是 ClusterRole
name: pod-reader # 但因为是 RoleBinding,仅在 staging NS 内有效
apiGroup: rbac.authorization.k8s.io
4. ServiceAccount 与 RBAC
4.1 ServiceAccount 令牌 (1.24+)
从 Kubernetes 1.24 开始,SA 不再自动创建 Secret:
# 创建 ServiceAccount
kubectl create serviceaccount monitoring-sa -n monitoring
# 创建短期令牌 (1 小时)
kubectl create token monitoring-sa -n monitoring --duration=3600s
# 长期令牌 (用于兼容旧版)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: monitoring-sa-token
namespace: monitoring
annotations:
kubernetes.io/service-account.name: monitoring-sa
type: kubernetes.io/service-account-token
EOF
4.2 在 Pod 中禁用 SA 令牌挂载
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
automountServiceAccountToken: false
containers:
- name: app
image: nginx:1.27
5. 实战演练:多租户 RBAC 配置
5.1 场景
- frontend-team:
frontendNS — 管理 Deployment、Service、ConfigMap - backend-team:
backendNS — 所有工作负载 + 读取 Secrets - platform-team:整个集群 — 只读 + 管理 Node/PV
5.2 实现
kubectl create ns frontend
kubectl create ns backend
# 1) frontend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: frontend
name: frontend-developer
rules:
- apiGroups: ["", "apps"]
resources: ["deployments", "services", "configmaps", "pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods/log", "pods/exec"]
verbs: ["get", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: frontend
name: frontend-team-binding
subjects:
- kind: Group
name: frontend-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: frontend-developer
apiGroup: rbac.authorization.k8s.io
EOF
# 2) backend-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: backend
name: backend-developer
rules:
- apiGroups: ["", "apps", "batch"]
resources: ["*"]
verbs: ["*"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: backend
name: backend-team-binding
subjects:
- kind: Group
name: backend-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: backend-developer
apiGroup: rbac.authorization.k8s.io
EOF
# 3) platform-team
cat <<'EOF' | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: platform-admin
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes"]
verbs: ["*"]
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
resources: ["*"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: platform-team-binding
subjects:
- kind: Group
name: platform-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: platform-admin
apiGroup: rbac.authorization.k8s.io
EOF
5.3 权限验证
# frontend-team 能在 frontend NS 中列出 pod 吗?
kubectl auth can-i list pods --namespace=frontend --as=jane --as-group=frontend-team
# yes
# frontend-team 能在 backend NS 中删除 pod 吗?
kubectl auth can-i delete pods --namespace=backend --as=jane --as-group=frontend-team
# no
# 全部权限清单 (CKS 考试小技巧!)
kubectl auth can-i --list --as=jane --as-group=frontend-team -n frontend
6. CKS 考试高频 RBAC 场景
6.1 检测危险权限
# 查找 cluster-admin 绑定
kubectl get clusterrolebindings -o json | jq -r '
.items[] |
select(.roleRef.name == "cluster-admin") |
.metadata.name + " -> " +
(.subjects[]? | .kind + "/" + .name)'
# 查找带有通配符(*)权限的 Role
kubectl get roles,clusterroles -A -o json | jq -r '
.items[] |
select(.rules[]?.verbs[]? == "*" or .rules[]?.resources[]? == "*") |
.metadata.namespace + "/" + .metadata.name'
6.2 Secret 访问审计
kubectl get roles,clusterroles -A -o json | jq -r '
.items[] |
select(.rules[]? | .resources[]? == "secrets") |
"\(.metadata.namespace // "cluster")/\(.metadata.name)"'
6.3 Pod Security Standards + RBAC 组合
apiVersion: v1
kind: Namespace
metadata:
name: secure-ns
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
7. RBAC 最佳实践 (Best Practices)
- 最小权限原则:禁止使用通配符(
*),只写明必要的 verb - 尽量少用 ClusterRoleBinding:能用 RoleBinding + ClusterRole 组合就用组合
- 拆分 ServiceAccount:每个 Pod 创建专用 SA,禁止使用 default SA
- 禁用令牌挂载:把
automountServiceAccountToken: false作为默认配置 - 定期审计:用
kubectl auth can-i --list周期性复查权限 - 善用 Aggregated ClusterRole:实现模块化的权限管理
- 善用 Impersonation:先用
--as标志测试权限再落地
8. 常见错误与解决办法
| 错误 | 问题 | 解决 |
|---|---|---|
| 混淆 ClusterRole + RoleBinding 与 ClusterRoleBinding | 作用域不一致 | 由 Binding 类型决定作用域 |
漏掉 apiGroups: [""] | 无法访问 core 资源 | core API = 空字符串 |
| 未包含 subresource | 无法访问 pods/log、pods/exec | 需要单独写明 |
| 没意识到 SA 令牌会过期 | 1.24+ 默认是短期令牌 | 设置 --duration |
9. 测验
Q1. Role 与 ClusterRole 最大的区别是什么?
Role 仅在 特定命名空间 内有效,而 ClusterRole 定义的是 整个集群 范围的权限。ClusterRole 还可以对 Node、PV 这类非命名空间资源授予权限。
Q2. 把 ClusterRole 关联到 RoleBinding 会怎样?
ClusterRole 中定义的权限会变成 仅在该 RoleBinding 所属的命名空间内 有效。
Q3. Kubernetes 1.24+ 之后 ServiceAccount 令牌有哪些变更?
不再自动创建 Secret。需要用 kubectl create token 生成短期令牌(默认 1 小时),或者手动创建 kubernetes.io/service-account-token Secret。
Q4. 为什么要设置 automountServiceAccountToken: false?
防止在 Pod 内挂载不必要的 SA 令牌,从而在容器被攻陷时切断攻击者对 K8s API 的访问。这是最小权限原则的一环。
Q5. kubectl auth can-i delete pods --as=jane -n production 会做什么?
用 Impersonation 功能确认 jane 用户在 production NS 中是否拥有删除 Pod 的权限。
Q6. Aggregated ClusterRole 的工作原理是什么?
与 aggregationRule 中 label selector 匹配的其他 ClusterRole 的 rules 会被自动合并进来。新增 ClusterRole 时会自动生效。
Q7. 怎样找出权限过大(cluster-admin)的绑定?
用 kubectl get clusterrolebindings -o json | jq 过滤出 roleRef.name == "cluster-admin" 的绑定。
Q8. KCSA 考试中 RBAC 的 3 个主要考点是什么?
(1) 最小权限原则 — 避免通配符 (2) SA 安全 — 禁用令牌挂载、不使用 default SA (3) 定期审计 — can-i --list、检测过多的 ClusterRoleBinding
현재 단락 (1/235)
Kubernetes 的 **RBAC**(Role-Based Access Control) 是把集群内 API 资源的访问以 **基于角色** 的方式加以控制的授权(Authorization)...