CFN Cloud
Cloud Future New Life
en zh
2025-12-29 · 0 次浏览

Kubernetes Tips:RBAC 最小权限(可落地版本)

用 ServiceAccount / Role / Binding 把权限收敛到“刚好够用”,既安全又不把团队卡死在 cluster-admin。

RBAC 是 Kubernetes 里最有杠杆的安全控制之一:它能把“一个小失误”限制在命名空间内,而不是扩散成集群级事故。但 RBAC 也最容易走向另一个极端——大家被权限折腾到崩溃,最后一句“直接给 cluster-admin 吧”。

这篇 tips 的目标是:实用最小权限。不是追求理论完美,而是让权限体系可运营、可审计、可迭代。

三个概念先搞清楚

  • Subject(主体):谁在发起请求(用户/用户组/ServiceAccount)。
  • Role / ClusterRole:允许做什么(对哪些资源做哪些动词)。
  • RoleBinding / ClusterRoleBinding:把角色绑定给主体(真正生效的地方)。

记住一句话:

Role 只是规则,Binding 才让规则生效。

命名空间权限 vs 集群权限

  • Role/RoleBinding:命名空间级别,推荐给业务应用使用。
  • ClusterRole/ClusterRoleBinding:可能是集群范围,谨慎使用,主要给平台组件/控制器/运维工具。

生产最佳实践:

  • 业务应用优先用 Role + RoleBinding
  • 只有确实需要跨命名空间/集群范围时才上 ClusterRole

ServiceAccount:别再用 default 了

Pod 不指定 serviceAccountName 时会用 namespace 的 default ServiceAccount。很多团队的默认 SA 被不小心绑定了高权限,风险非常大。

推荐:

  1. 每个应用使用独立 ServiceAccount
  2. 默认关闭 token 挂载(除非真的需要访问 K8s API)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api
  namespace: app
automountServiceAccountToken: false

Deployment 里也显式写:

spec:
  template:
    spec:
      serviceAccountName: api
      automountServiceAccountToken: false

如果应用确实需要访问 API(比如 leader election、watch 资源),再把 token 挂载打开,并严格审核 RBAC。

Role 规则怎么写:先从“可用的只读”开始

RBAC 规则由三部分组成:

  • apiGroups
  • resources
  • verbs

一个常见的“排障只读” Role(给人用):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ns-observer
  namespace: app
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "services", "endpoints", "configmaps", "events"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]

注意 pods/log:很多人只给了 pods,却发现看不了日志,就是因为漏了子资源。

子资源是 RBAC 的高频坑

常见子资源:

  • 看日志:pods/log
  • 远程执行:pods/exec
  • 端口转发:pods/portforward
  • 写 status:deployments/statuspods/status

当你看到 “forbidden” 时,不要只盯着 pods,也要检查子资源权限。

绑定策略:把“人”和“应用”分开

不要把人和应用随便绑在同一个 Role 上。推荐做法:

  • 应用 SA:只给程序真正需要的最小权限
  • 人(运维/开发):默认只读;需要写权限时走升级 Role(更严格、可审计)

这样你才能在审计里说清楚:

  • “应用代码能做什么”
  • “某个用户在什么情况下能做什么”

kubectl auth can-i 做权限验算

这是最实用的 RBAC 调试工具:

kubectl auth can-i get pods -n app
kubectl auth can-i get pods/log -n app
kubectl auth can-i create pods/exec -n app

支持模拟某个 ServiceAccount:

kubectl auth can-i get secrets -n app --as system:serviceaccount:app:api

这能让你在上线前就验证权限是否“刚好够用”,而不是靠线上报错摸索。

常见最小权限配方

1)只读 ConfigMap(watch 热更新)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cm-reader
  namespace: app
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]

2)leader election(leases)

很多控制器通过 coordination.k8s.io 的 leases 做 leader election:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: leader-election
  namespace: app
rules:
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

3)允许创建 Pods(高风险权限)

“能创建 Pod”通常意味着很强的能力:可能拉任意镜像、尝试访问服务、消耗资源等。它应被视为高危权限,需要:

  • 严格限定命名空间
  • 结合 Pod Security / Admission Policy 限制 Pod 能做什么
  • 尽量用固定模板的控制器,而不是让业务任意创建 Pod

红旗(能避免很多事故)

  • 给应用 ServiceAccount 绑定 cluster-admin
  • resources: ["*"] + verbs: ["*"] 的通配角色
  • 广泛授予读取 secrets(secrets 常常就是“钥匙”)
  • 把 break-glass 权限变成长期常态

让升级权限“可控”(break-glass)

真实世界里你总会遇到需要更高权限的场景。关键是把升级变成:

  • 有时效(临时)
  • 可审计(关联工单/事故)
  • 有范围(限定 namespace/动作)

即使只是流程+日志记录,也比“永久 cluster-admin”强很多。

进阶:更成熟团队会用的技巧

resourceNames 做“点状权限”

比如只允许读一个 ConfigMap:

rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["api-config"]
    verbs: ["get"]

pods/execpods/portforward 当成高权限

exec/port-forward 基本等价于“进入容器”,风险很高。建议单独做一个 debug Role,由值班/运维组按需申请,而不是默认给所有人。

Checklist

  • 每个应用都有独立 ServiceAccount
  • 默认关闭 automountServiceAccountToken,除非需要访问 API
  • 业务优先 Role/RoleBinding,不乱用 ClusterRoleBinding
  • 子资源(pods/log、pods/exec)按需显式授权
  • kubectl auth can-i + impersonation 做上线前验算
  • break-glass 权限临时、可审计、可回收

参考链接

FAQ

Q: Role 和 ClusterRole 有什么区别? A: Role 只在命名空间内生效;ClusterRole 可用于集群范围或非命名空间资源。

Q: 为什么 Pod 权限超出预期? A: 可能绑定了默认 ServiceAccount 或过宽的 ClusterRoleBinding,检查 SA 与绑定关系。

Q: 如何验证权限? A:kubectl auth can-i 并指定对应 ServiceAccount。