讲解

API Server 的每个请求都要过三关:认证(你是谁)、鉴权(你能不能做)、准入控制(请求合不合规)。RBAC(基于角色的访问控制)是鉴权的主流模型,概念只有四个,两两分一组:Role/ClusterRole 定义「权限」(能对什么资源做什么操作——verbs 如 get、list、watch、create、delete);RoleBinding/ClusterRoleBinding 把权限「绑定」给主体(用户、组、ServiceAccount)。Role 和 RoleBinding 只在单个命名空间内生效;ClusterRole 是集群级权限(Node、PV 这类集群资源,或跨所有命名空间的权限),ClusterRoleBinding 把它绑定到主体。一个常见组合:ClusterRoleBinding 引用 ClusterRole 给全集群权限;RoleBinding 也可以引用 ClusterRole,表示「这套通用权限只在此命名空间生效」。

Pod 里的程序访问 API Server(比如控制器、CI 流水线里的脚本)走的是 ServiceAccount:每个命名空间有 default SA,Pod 默认挂它。实践原则是「最小权限」:给应用建专用 ServiceAccount,只绑它真正需要的权限——只读监控给 get/list/watch,绝不让业务 Pod 拿 delete 权限。默认的 default SA 没绑定额外权限,这本身就是一道安全默认值,不要图省事给它放权。

验证权限不必真的造个 Pod 进去试,kubectl auth can-i 是标准工具:kubectl auth can-i delete pods --as=system:serviceaccount:命名空间:SA名 直接问 API Server「这个主体能不能做这件事」,返回 yes/no。管理员还能加 --as 之外的 --as-group 模拟组成员。排障思路也顺这个来:权限报错(Forbidden)时先确认主体身份(谁在用),再看它绑了什么 Role/ClusterRoleBinding,最后看 Role 里的 rules 到底允不允许这个 verb + resource 组合。

示例

一个只读 ServiceAccount:SA + Role(只能 get/list/watch Pod)+ RoleBinding 三件套:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ohmydocs-verify-reader
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ohmydocs-verify-pod-reader
rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ohmydocs-verify-read-pods
subjects:
    - kind: ServiceAccount
      name: ohmydocs-verify-reader
      namespace: ohmydocs-verify
roleRef:
  kind: Role
  name: ohmydocs-verify-pod-reader
  apiGroup: rbac.authorization.k8s.io

用 auth can-i 当场验证:list pods 被允许,delete pods 被拒绝——最小权限生效:

kubectl auth can-i list pods --as=system:serviceaccount:ohmydocs-verify:ohmydocs-verify-reader
if kubectl auth can-i delete pods --as=system:serviceaccount:ohmydocs-verify:ohmydocs-verify-reader | grep -q yes; then
  echo "意外:只读账号居然能删 Pod"
  exit 1
else
  echo "符合预期:delete pods 被拒绝"
fi
kubectl auth can-i create deployments --as=system:serviceaccount:ohmydocs-verify:ohmydocs-verify-reader || echo "create deployments 同样被拒绝"

对照看:集群管理员(当前 kubeconfig 的身份)当然什么都能做:

kubectl auth can-i delete pods --as=system:serviceaccount:ohmydocs-verify:ohmydocs-verify-reader > /dev/null 2>&1 && echo unexpected || true
kubectl auth can-i list pods

把某账号提权成集群管理员的写法(生产慎用,仅演示 ClusterRoleBinding 结构):

# 仅示意:绑定内置 cluster-admin 等于交出整个集群,生产环境绝不这样授权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ohmydocs-verify-admin-demo
subjects:
    - kind: ServiceAccount
      name: ohmydocs-verify-reader
      namespace: ohmydocs-verify
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

常见坑

  • 图省事绑 cluster-admin:一个业务账号被攻破 = 整个集群沦陷;权限按「需要才给、给最小集」逐条加。
  • RoleBinding 的 subject 忘了 namespace:ServiceAccount 主体必须写对它所在的命名空间,写错了绑定静默无效。
  • Role 和 ClusterRole 用混:Node、PV、namespaces 这些集群级资源只能用 ClusterRole 授权,写在 Role 里无效。
  • 改了权限没生效的错觉:RBAC 变更实时生效,不需要重启;如果「还不行」,多半是绑错了主体或还有别的绑定在起作用(auth can-i 一查便知)。

小结

RBAC 四件套:Role/ClusterRole 定权限,RoleBinding/ClusterRoleBinding 绑主体;Pod 的身份是 ServiceAccount,权限给最小集;auth can-i 是权限验证与排障的标准工具。权限收紧了,下一章进入实战综合:故障排查。