🔒 第11课:RBAC权限

📌 课程阶段:安全与监控(1/5)|预计时间:60分钟|难度:⭐⭐⭐☆☆

一、K8s安全体系概览

RBAC(Role-Based Access Control)是K8s安全的核心机制,控制谁(Subject)可以对什么资源(Resource)执行什么操作(Verb)

┌──────── K8s安全三阶段 ────────┐
│                                 │
│  1️⃣ 认证(Authentication)       │
│     "你是谁?"                  │
│     → X.509证书 / Token / OIDC │
│                                 │
│  2️⃣ 授权(Authorization)        │
│     "你能做什么?"              │
│     → RBAC / ABAC / Node / Webhook │
│                                 │
│  3️⃣ 准入控制(Admission Control) │
│     "这个操作允许吗?"          │
│     → Validating/Mutating Webhook │
│                                 │
│  ┌──── RBAC核心对象 ────┐       │
│  │                      │       │
│  │  Role    → 命名空间级 │       │
│  │  ClusterRole → 集群级 │       │
│  │                      │       │
│  │  RoleBinding         │       │
│  │  ClusterRoleBinding  │       │
│  │  → 绑定Subject到Role │       │
│  └──────────────────────┘       │
└─────────────────────────────────┘

二、Role与ClusterRole

2.1 Role——命名空间级权限

# role-pod-reader.yaml - 只能读取Pod
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
- apiGroups: [""]                   # core API组
  resources: ["pods"]               # 资源类型
  verbs: ["get", "list", "watch"]   # 允许的操作
- apiGroups: [""]
  resources: ["pods/log"]           # 子资源
  verbs: ["get"]
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]
  resourceNames: ["app-config"]     # 限制到特定资源名

# verbs完整列表:
# get      - 获取单个资源
# list     - 列出资源集合
# watch    - 监听变化
# create   - 创建
# update   - 更新
# patch    - 部分更新
# delete   - 删除
# deletecollection - 批量删除
# *        - 所有操作

# ✅ 验证通过
kubectl apply -f role-pod-reader.yaml
kubectl get roles
# NAME         CREATED AT
# pod-reader   2026-01-01T00:00:00Z

2.2 ClusterRole——集群级权限

# clusterrole-node-reader.yaml - 读取节点信息
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
  # ClusterRole没有namespace!
rules:
- apiGroups: [""]
  resources: ["nodes"]              # 节点是集群级资源
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["nodes/proxy"]        # 节点代理子资源
  verbs: ["get"]

---
# clusterrole-namespace-admin.yaml - 命名空间管理员模板
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: namespace-admin
rules:
- apiGroups: ["", "apps", "batch", "extensions"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses", "networkpolicies"]
  verbs: ["*"]

三、RoleBinding与ClusterRoleBinding

3.1 RoleBinding——绑定Subject到Role

# rolebinding-dev-team.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-team-binding
  namespace: default
subjects:
# User(外部用户)
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
# Group(用户组)
- kind: Group
  name: developers
  apiGroup: rbac.authorization.k8s.io
# ServiceAccount(Pod内使用)
- kind: ServiceAccount
  name: dev-sa
  namespace: default
roleRef:
  kind: Role                       # Role | ClusterRole
  name: pod-reader                 # 引用的Role名
  apiGroup: rbac.authorization.k8s.io

# ✅ 验证通过
kubectl apply -f rolebinding-dev-team.yaml
kubectl get rolebindings
# NAME               ROLE              AGE
# dev-team-binding   Role/pod-reader   5s

3.2 ClusterRoleBinding——集群级绑定

# clusterrolebinding-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-binding
subjects:
- kind: User
  name: admin
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-admin              # K8s内置的超级管理员角色
  apiGroup: rbac.authorization.k8s.io

# ✅ 验证通过 - 检查用户权限
kubectl auth can-i list pods --as=alice -n default
# yes

kubectl auth can-i delete pods --as=alice -n default
# no

kubectl auth can-i list nodes --as=alice
# no

3.3 RoleBinding引用ClusterRole

# 可以用RoleBinding绑定ClusterRole
# 效果:权限限制在特定namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-namespace-reader
  namespace: development          # 只在development命名空间生效
subjects:
- kind: Group
  name: developers
roleRef:
  kind: ClusterRole               # 引用ClusterRole
  name: namespace-admin           # 但权限被限制在development命名空间

# 对比:
# ClusterRole + ClusterRoleBinding → 集群所有命名空间
# ClusterRole + RoleBinding → 仅RoleBinding所在的命名空间

四、ServiceAccount

# ServiceAccount是Pod的身份标识
# 每个Pod自动关联default ServiceAccount

# 创建自定义ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: default
automountServiceAccountToken: true   # 自动挂载Token

---
# Pod使用自定义ServiceAccount
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sa
spec:
  serviceAccountName: app-sa         # 指定ServiceAccount
  automountServiceAccountToken: true
  containers:
  - name: app
    image: nginx:1.25
    # Token自动挂载到 /var/run/secrets/kubernetes.io/serviceaccount/

# ✅ 验证通过 - 检查ServiceAccount
kubectl get sa
# NAME      SECRETS   AGE
# default   0         10d
# app-sa    0         5s

# 查看Token(K8s 1.24+不再自动创建Secret,使用Projected Volume)
kubectl auth resolve --serviceaccount=app-sa

五、RBAC实战场景

5.1 多团队命名空间隔离

# 团队A只能管理team-a命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: team-a
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: team-admin
  namespace: team-a
rules:
- apiGroups: ["", "apps", "batch"]
  resources: ["*"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: team-a-admin-binding
  namespace: team-a
subjects:
- kind: Group
  name: team-a-devs
roleRef:
  kind: Role
  name: team-admin
  apiGroup: rbac.authorization.k8s.io

# ✅ 验证通过 - 团队A可以管理自己的命名空间
kubectl auth can-i create deployments --as=alice --groups=team-a-devs -n team-a
# yes
kubectl auth can-i create deployments --as=alice --groups=team-a-devs -n team-b
# no

5.2 CI/CD ServiceAccount

# ci-cd-rbac.yaml - CI/CD流水线专用权限
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-cd
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ci-cd-role
  namespace: default
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
  resourceNames: ["deploy-key"]     # 只能访问特定Secret
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create", "get", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-cd-binding
  namespace: default
subjects:
- kind: ServiceAccount
  name: ci-cd
roleRef:
  kind: Role
  name: ci-cd-role
  apiGroup: rbac.authorization.k8s.io

六、RBAC故障排查

# 检查权限
kubectl auth can-i list pods --as=alice -n default
kubectl auth can-i list pods --as=system:serviceaccount:default:app-sa

# 查看Subject的所有权限
kubectl auth can-i --list --as=alice -n default

# 检查RoleBinding
kubectl get rolebindings -A -o wide
kubectl describe rolebinding dev-team-binding

# 检查ClusterRoleBinding
kubectl get clusterrolebindings -o wide | grep admin

# 常见问题:
# 1. ServiceAccount没有权限 → 检查RoleBinding
# 2. 跨命名空间访问 → 需要ClusterRole + ClusterRoleBinding
# 3. 权限过于宽泛 → 缩小resourceNames和verbs

七、练习

  1. 创建一个只读Role,允许list/get Pods和Services
  2. 创建ServiceAccount + RoleBinding,让Pod内应用只能读取ConfigMap
  3. 实现多团队命名空间隔离:team-a和team-b互不可见
  4. 创建CI/CD专用ServiceAccount,限制只能部署和管理Deployment
  5. 使用kubectl auth can-i验证各种权限组合

🏆 第11课成就解锁

下一课预告:第12课深入NetworkPolicy——K8s网络隔离与安全策略。

📌 补充知识

11-rbac权限补充要点:K8s生产实践扩展

🔹 资源配额(ResourceQuota):限制命名空间总资源
  apiVersion: v1
  kind: ResourceQuota
  metadata:
    name: compute-quota
    namespace: production
  spec:
    hard:
      requests.cpu: "20"
      requests.memory: 40Gi
      limits.cpu: "40"
      limits.memory: 80Gi
      pods: "50"
      services: "10"

🔹 LimitRange:设置默认资源限制
  apiVersion: v1
  kind: LimitRange
  metadata:
    name: default-limits
  spec:
    limits:
    - type: Container
      default:
        cpu: "200m"
        memory: 256Mi
      defaultRequest:
        cpu: "100m"
        memory: 128Mi
      max:
        cpu: "2"
        memory: 4Gi

🔹 Pod优先级与抢占
  apiVersion: scheduling.k8s.io/v1
  kind: PriorityClass
  metadata:
    name: high-priority
  value: 1000000
  globalDefault: false
  ---
  spec:
    preemptionPolicy: PreemptLowerPriority

🔹 优雅处理Pod中断
  • PDB保证最小可用副本
  • preStop钩子处理连接排空
  • terminationGracePeriodSeconds充足
  • 应用必须处理SIGTERM信号

🔹 生产环境Checklist
  ✅ 设置resources requests/limits
  ✅ 配置liveness/readiness探针
  ✅ 使用PDB保护关键服务
  ✅ 实现优雅关闭(SIGTERM)
  ✅ 配置HPA自动伸缩
  ✅ 使用NetworkPolicy隔离
  ✅ 开启RBAC最小权限
  ✅ 日志结构化输出
  ✅ 指标暴露/metrics端点
  ✅ 配置PVC数据备份

📎 扩展阅读与生产实践

11-rbac权限生产环境进阶要点

🔹 性能优化关键参数
  • kubelet: --max-pods=110 --pods-per-core=10
  • kube-apiserver: --max-requests-inflight=800
  • etcd: --quota-backend-bytes=8589934592
  • kube-scheduler: --percentage-of-nodes-to-score=50

🔹 集群容量规划
  • 控制平面:3节点,8C16G起步
  • Worker节点:按应用类型分组
  • etcd:SSD磁盘,<2ms延迟
  • 网络带宽:10Gbps+集群内互联

🔹 故障自愈最佳实践
  1. Pod: livenessProbe自动重启
  2. Deployment: ReplicaSet保证副本数
  3. Node: kubelet自注册+健康检查
  4. Cluster: Cluster Autoscaler增减节点
  5. Multi-Cluster: Karmada联邦容灾

🔹 K8s版本升级策略
  • 每次只升一个minor版本
  • 先升级控制平面,再升级Worker
  • 使用kubeadm upgrade plan预检
  • 准备回滚方案
  • 在staging环境验证后再升级prod