1. Kubernetes RBAC基础概念解析

在Kubernetes集群中管理权限就像给不同部门的员工发放门禁卡——你需要精确控制谁能进哪个房间、能操作哪些设备。RBAC(基于角色的访问控制)就是这套门禁系统的核心机制。

RBAC的核心组件就像一套权限管理的乐高积木:

  • Role:相当于部门内部的权限清单,比如"研发部权限"包含代码库读写、测试环境部署等
  • ClusterRole:则是全公司通用的权限模板,比如"财务权限"可以跨部门使用
  • ServiceAccount:就像员工工牌,代表Pod中运行的应用身份
  • Binding:就是把权限清单和工牌绑定的过程

我刚开始接触时经常混淆Role和ClusterRole,直到有一次把该用Role的地方误用了ClusterRole,导致某个测试命名空间的Pod被意外删除。这个教训让我明白:Role就像房间里的抽屉(命名空间内有效),而ClusterRole是整个大楼的公共区域(集群范围有效)。

2. ServiceAccount深度实践

2.1 创建与配置ServiceAccount

先来看个实际案例:为监控系统Prometheus创建专用账号

# prometheus-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: monitoring

应用配置后,可以检查SA是否创建成功:

kubectl get sa -n monitoring

关键细节

  1. 每个SA会自动生成一个token secret,挂载到Pod的/var/run/secrets/kubernetes.io/serviceaccount
  2. 通过automountServiceAccountToken: false可以禁用自动挂载(安全场景推荐)
  3. SA的命名空间必须与使用它的Pod所在命名空间一致

2.2 SA的Token管理实战

获取token进行API访问测试:

# 获取token
kubectl get secret -n monitoring | grep prometheus-token
kubectl describe secret prometheus-token-xxxxx -n monitoring

# 使用curl测试API访问
curl -k -H "Authorization: Bearer <token>" https://<api-server>/api/v1/namespaces/monitoring/pods

常见踩坑点

  • Token默认有效期是1年,生产环境建议定期轮换
  • 旧版本K8s(<=1.23)的token是永久的,需要特别注意
  • 通过kubectl create token命令可以创建临时token(v1.22+)

3. Role/ClusterRole精细配置

3.1 命名空间权限设计

假设我们要给CI/CD系统设计一个部署专用Role:

# ci-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: ci-deployer
rules:
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get", "list"]

权限设计原则

  1. 遵循最小权限原则,就像只给装修工人需要的房间钥匙
  2. 生产环境应该禁止使用*通配符
  3. 对敏感资源(如secrets)要特别限制

3.2 集群级权限控制

日志收集系统通常需要跨命名空间读取Pod日志:

# log-collector-cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: log-collector
rules:
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get", "list"]
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "list"]

ClusterRole使用场景

  1. 集群级别资源(nodes, persistentvolumes等)
  2. 非资源端点(如/healthz)
  3. 跨所有命名空间的资源访问

4. 绑定策略实战

4.1 RoleBinding典型配置

将CI部署角色绑定到SA:

# ci-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-deployer-binding
  namespace: dev
subjects:
- kind: ServiceAccount
  name: ci-bot
  namespace: ci
roleRef:
  kind: Role
  name: ci-deployer
  apiGroup: rbac.authorization.k8s.io

绑定技巧

  1. SA可以跨命名空间绑定(如上例ci命名空间的SA绑定dev命名空间的Role)
  2. 但RoleBinding和Role必须在同一命名空间
  3. 一个SA可以绑定多个Role

4.2 ClusterRoleBinding注意事项

集群管理员配置示例:

# admin-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-binding
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

安全警告

  • ClusterRoleBinding会授予集群范围权限
  • 避免直接将cluster-admin绑定给普通SA
  • 推荐使用RoleBinding引用ClusterRole实现命名空间隔离

5. 权限验证与问题排查

5.1 权限检查工具

# 检查SA是否有删除Pod权限
kubectl auth can-i delete pods \
  --as=system:serviceaccount:dev:ci-bot \
  --namespace=dev

# 查看SA的完整权限
kubectl auth can-i --list \
  --as=system:serviceaccount:dev:ci-bot \
  --namespace=dev

5.2 常见问题排查流程

  1. 确认错误类型

    kubectl get pods -n dev --as=system:serviceaccount:dev:ci-bot
    

    典型错误:Error from server (Forbidden)

  2. 检查绑定关系

    kubectl get rolebindings,clusterrolebindings -A | grep ci-bot
    
  3. 验证Role/ClusterRole

    kubectl describe role ci-deployer -n dev
    
  4. 检查审计日志

    kubectl logs -n kube-system kube-apiserver-node1 | grep Forbidden
    

排查技巧

  • 使用-v=6参数查看API请求详情
  • 检查kube-apiserver日志中的RBAC决策记录
  • 临时绑定view角色帮助诊断

6. 高级配置模式

6.1 聚合ClusterRole

扩展默认角色权限:

# custom-view-cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: custom-view
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["batch"]
  resources: ["cronjobs"]
  verbs: ["get", "list", "watch"]

6.2 资源名称限制

精细化控制特定资源实例:

# configmap-updater.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["app-config"]
  verbs: ["update", "get"]

7. 安全最佳实践

  1. 最小权限原则

    • 从最小权限开始,逐步增加
    • 生产环境避免使用*通配符
  2. 定期审计

    kubectl get rolebindings,clusterrolebindings -A -o yaml > rbac-backup-$(date +%F).yaml
    
  3. 敏感操作保护

    • 对delete等危险操作实施二次确认
    • 通过准入控制器补充限制
  4. SA安全加固

    • 禁用default SA的自动挂载
    • 为重要SA设置自动轮换
# secure-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secure-app
automountServiceAccountToken: false

在真实生产环境中,我曾见过因为一个过度授权的ClusterRoleBinding导致的安全事件。那次经历让我深刻理解到:RBAC配置就像给系统上锁,每个锁孔都要精确匹配,任何多余的钥匙都可能成为安全隐患。

更多推荐