RBAC 与 kubeconfig 详解:从身份到授权

This article is extracted from the chat log with AI. Please identify it with caution.

本文边界:本文聚焦身份认证后的授权模型、RBAC 对象及权限排查;TLS 连接、证书链和 SAN 匹配请阅读连接与证书专题。

推荐深读Kubernetes 证书、kubeconfig 与 API Server 的关系

说明:本文由 Codex 根据作者提供的主题、素材与公开资料辅助生成,属于 AI 生成/整理内容,非作者原创。请读者自行甄别并交叉验证。

1. 文档定位#

这篇文档回答一个经常被混在一起的问题:

为什么 kubeconfig 里明明配置了用户,kubectl 也能连上集群,
但执行某些命令时还是会报 Forbidden?

原因是 kubeconfig 和 RBAC 处在不同层次:

  • kubeconfig 解决“连哪个集群、用哪个身份、默认在哪个 namespace 操作”。
  • RBAC 解决“这个身份在 Kubernetes API 里能做什么”。

简单说:

kubeconfig 决定你是谁,以及你要访问哪里;
RBAC 决定你能不能做这件事。

2. RBAC 是什么#

RBAC 是 Role-Based Access Control 的缩写,中文通常叫“基于角色的访问控制”。

在 Kubernetes 里,RBAC 是一种授权机制。它不负责认证用户是谁,而是在认证完成后,判断这个身份能否执行某个 API 操作。

一个 Kubernetes API 请求大致可以拆成:

主体:user / group / service account
动作:get / list / watch / create / update / patch / delete
资源:pods / deployments / secrets / nodes
范围:namespace 内,或者整个 cluster

RBAC 做的事情就是把这些要素组合起来判断:

某个 subject 是否被绑定到了某组 rules;
这组 rules 是否允许当前请求的 verb、resource、apiGroup、namespace。

3. 从 kubectl 到 API Server 的完整链路#

理解 RBAC 之前,先看一次 kubectl get pods -n dev 背后发生了什么。

flowchart TD
  A["kubectl get pods -n dev"] --> B["读取 kubeconfig"]
  B --> C["选择 current-context"]
  C --> D["拿到 cluster、user、namespace"]
  D --> E["连接 API Server"]
  E --> F["TLS 校验与认证"]
  F --> G["API Server 得到 username / groups"]
  G --> H["授权检查:RBAC / Node / Webhook 等"]
  H --> I["准入控制 Admission"]
  I --> J["读写 Kubernetes 对象"]

这条链路里,常见错误对应不同阶段:

现象常见位置大致含义
connection refused / i/o timeout连接 API Server地址、网络、端口、代理或负载均衡问题
x509: certificate ...TLS 校验kubeconfig 里的 server、CA 与 API Server 证书不匹配
Unauthorized / HTTP 401认证token、客户端证书、exec 插件等凭据无效
Forbidden / HTTP 403授权身份已经确认,但 RBAC 没允许这个动作

所以,Forbidden 不是 kubeconfig 没生效。恰恰相反,它通常说明 API Server 已经知道你是谁,只是这个身份没有足够权限。

4. kubeconfig 的结构#

kubeconfig 不是固定文件名,而是一类 Kubernetes 客户端配置文件。默认情况下,kubectl 会读取:

$HOME/.kube/config

也可以通过环境变量或参数指定:

KUBECONFIG=/path/to/config kubectl get pods
kubectl --kubeconfig=/path/to/config get pods

一个典型 kubeconfig 长这样,下面是脱敏示例:

apiVersion: v1
kind: Config
preferences: {}

clusters:
  - name: prod
    cluster:
      server: https://api.prod.example.com:6443
      certificate-authority-data: <base64-ca-cert>

users:
  - name: alice
    user:
      client-certificate-data: <base64-client-cert>
      client-key-data: <base64-client-key>

contexts:
  - name: prod-alice-dev
    context:
      cluster: prod
      user: alice
      namespace: dev

current-context: prod-alice-dev

它的核心可以概括成三张表:

区块作用解决的问题
clusters集群连接信息API Server 在哪里,如何校验证书
users客户端认证信息用什么凭据证明“我是谁”
contexts组合集群、用户、namespace当前用哪个身份访问哪个集群

current-context 是默认上下文。执行 kubectl get pods 时,如果不额外指定 context,kubectl 就会使用它。

5. clusters:连接哪个 API Server#

clusters 描述集群入口:

clusters:
  - name: prod
    cluster:
      server: https://api.prod.example.com:6443
      certificate-authority-data: <base64-ca-cert>

几个关键字段:

字段作用
namekubeconfig 内部引用名,不一定等于真实集群名
serverKubernetes API Server 地址
certificate-authorityCA 证书文件路径
certificate-authority-data内嵌的 CA 证书内容,通常是 base64 编码
insecure-skip-tls-verify是否跳过 TLS 校验,生产环境不建议使用

server 只决定 kubectl 要连哪里,不决定权限。

如果 server 指向了正确集群,但后面的 user 是只读身份,那么仍然只能读。 如果 server 指向了错误集群,即使名字也叫 prod,RBAC 检查的是那个集群里的权限。

6. users:认证成哪个身份#

users 描述认证方式。名字叫 users,但它也可以代表程序、组件、CI/CD、插件登录身份。

常见写法有几类。

6.1 客户端证书#

users:
  - name: alice
    user:
      client-certificate-data: <base64-client-cert>
      client-key-data: <base64-client-key>

客户端证书用于 mTLS 认证。API Server 会根据证书识别请求方身份。

常见约定是:

  • 证书 CN 对应 username。
  • 证书 O 对应 groups。

例如证书 subject 类似:

CN=alice,O=dev-team

那么 API Server 认证后得到的身份大致是:

username: alice
groups:
  - dev-team

RBAC 绑定时就可以把权限授给 User aliceGroup dev-team

6.2 Bearer token#

users:
  - name: ci-bot
    user:
      token: <redacted-token>

token 可以来自 ServiceAccount、OIDC、云厂商 IAM 或其他认证系统。

token 自己不等于权限。token 只能帮助 API Server 识别身份,识别之后仍然要经过授权检查。

6.3 exec 插件#

users:
  - name: cloud-user
    user:
      exec:
        apiVersion: client.authentication.k8s.io/v1
        command: example-login-plugin
        args:
          - get-token

exec 表示 kubectl 在访问集群前会执行一个本地命令,由这个命令返回认证凭据。

很多云厂商或企业登录方案都会使用这种方式,例如通过 CLI 获取短期 token。

这也是为什么不要使用不可信来源的 kubeconfig:一个恶意 kubeconfig 可以通过 exec.command 诱导本机执行命令。把 kubeconfig 当成脚本一样审查,是更稳妥的习惯。

7. contexts:把集群、身份和 namespace 绑在一起#

contexts 是 kubeconfig 最容易被低估的一层。

contexts:
  - name: prod-alice-dev
    context:
      cluster: prod
      user: alice
      namespace: dev

current-context: prod-alice-dev

这表示:

默认访问 prod 这个 cluster;
默认使用 alice 这个 user;
默认 namespace 是 dev。

注意,namespace 只是默认操作范围,不是权限授予。

例如当前 context 默认 namespace 是 dev,但 RBAC 没给 alice 访问 dev 的 Pod 权限,照样会 Forbidden。

反过来,当前 context 默认 namespace 是 dev,但你执行:

kubectl get pods -n prod

命令行上的 -n prod 会覆盖 context 里的默认 namespace,然后 RBAC 会按 prod namespace 检查权限。

8. kubeconfig 与 RBAC 的对应关系#

把 kubeconfig 和 RBAC 连起来看,关键是 users[].name 不一定等于 RBAC 里的真实 username。

例如:

users:
  - name: my-local-alias
    user:
      client-certificate-data: <cert>

这里 my-local-alias 只是 kubeconfig 内部名字。真正进入 API Server 的身份来自证书、token 或 exec 插件结果。

所以排查权限时,不要只看 kubeconfig 里的 users[].name。更可靠的方式是问 API Server 当前身份是谁:

kubectl auth whoami

如果集群或 kubectl 版本不支持这个命令,可以结合认证方式判断身份,或者让管理员通过审计日志、SubjectAccessReview 等方式确认。

9. ServiceAccount 身份#

ServiceAccount 是 Kubernetes 里的非人类账号,常用于 Pod、控制器、CI/CD 或集群内组件。

一个 ServiceAccount 是 namespaced 对象:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: report-reader
  namespace: dev

它的 RBAC 身份通常是:

User: system:serviceaccount:dev:report-reader
Groups:
  - system:serviceaccounts
  - system:serviceaccounts:dev
  - system:authenticated

Pod 使用 ServiceAccount:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: report-api
  namespace: dev
spec:
  template:
    spec:
      serviceAccountName: report-reader
      containers:
        - name: app
          image: nginx

然后通过 RBAC 给这个 ServiceAccount 授权。

现代 Kubernetes 中,Pod 内使用的 ServiceAccount token 通常是短期、自动轮换的 projected token。不要为了方便长期保存静态 ServiceAccount token,尤其不要把它提交到 Git 仓库或博客文档里。

10. RBAC 的四类对象#

Kubernetes RBAC 有四类核心对象:

对象作用范围
Role定义一组 namespace 内权限namespaced
ClusterRole定义一组集群级权限,或可复用权限模板cluster-scoped
RoleBindingRoleClusterRole 授给 subjectnamespaced
ClusterRoleBindingClusterRole 授给 subjectcluster-scoped

RoleClusterRole 只是权限定义。 RoleBindingClusterRoleBinding 才是真正把权限给某个主体。

可以记成:

Role / ClusterRole = 权限清单
RoleBinding / ClusterRoleBinding = 把权限清单给谁

11. Role:namespace 内的权限定义#

Role 只能定义某个 namespace 内的权限。

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

含义是:

在 dev namespace 中,
允许读取 pods 资源。

注意,这个 Role 本身不会让任何人获得权限。必须再创建 RoleBinding。

12. ClusterRole:集群级权限或可复用模板#

ClusterRole 不属于任何 namespace。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

它有三类常见用途:

  1. 定义集群级资源权限,例如 nodesnamespacespersistentvolumes
  2. 定义所有 namespace 都可用的权限,再通过 ClusterRoleBinding 全局授权。
  3. 作为权限模板,通过不同 namespace 里的 RoleBinding 局部授权。

例如 Kubernetes 内置的 vieweditadmincluster-admin 都是 ClusterRole。

13. RoleBinding:在 namespace 内授权#

RoleBinding 把一个 Role 或 ClusterRole 绑定给一组 subjects。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: alice-read-pods
  namespace: dev
subjects:
  - kind: User
    name: alice
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

含义是:

把 dev namespace 中的 pod-reader Role,
授给 User alice,
只在 dev namespace 生效。

subjects 可以有多个:

subjects:
  - kind: User
    name: alice
    apiGroup: rbac.authorization.k8s.io
  - kind: Group
    name: dev-team
    apiGroup: rbac.authorization.k8s.io
  - kind: ServiceAccount
    name: report-reader
    namespace: dev

14. ClusterRoleBinding:集群范围授权#

ClusterRoleBinding 把 ClusterRole 授给 subject,并在整个集群生效。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ops-node-reader
subjects:
  - kind: Group
    name: ops-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: node-reader
  apiGroup: rbac.authorization.k8s.io

只要用了 ClusterRoleBinding,就要特别谨慎。它通常意味着权限跨 namespace 或覆盖集群级资源。

最危险的例子是:

ClusterRoleBinding -> cluster-admin

这相当于给 subject 集群管理员权限。

15. 四种绑定组合#

权限定义绑定方式是否允许实际效果
RoleRoleBinding允许在 RoleBinding 所在 namespace 授权
ClusterRoleRoleBinding允许复用 ClusterRole 规则,但只在 RoleBinding 所在 namespace 生效
ClusterRoleClusterRoleBinding允许在整个集群范围授权
RoleClusterRoleBinding不允许ClusterRoleBinding 只能引用 ClusterRole

最容易误解的是第二种:

RoleBinding 绑定 ClusterRole,不代表全局授权。

例如:

kubectl create rolebinding dev-view \
  --clusterrole=view \
  --user=alice \
  --namespace=dev

这只是让 alicedev namespace 中拥有 view 权限,并不会让她查看所有 namespace。

16. rules 字段详解#

Role 和 ClusterRole 的核心是 rules

rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]

16.1 apiGroups#

apiGroups 指 Kubernetes API 分组。

写法示例资源
[""]podsservicesconfigmapssecrets
["apps"]deploymentsreplicasetsstatefulsetsdaemonsets
["batch"]jobscronjobs
["rbac.authorization.k8s.io"]rolesrolebindingsclusterroles

core API group 用空字符串 "" 表示。

16.2 resources#

resources 指资源类型,通常是复数形式:

resources: ["pods", "services", "deployments"]

子资源要写成 resource/subresource

resources: ["pods/log", "pods/exec"]

几个常见子资源:

子资源常见命令
pods/logkubectl logs
pods/execkubectl exec
pods/portforwardkubectl port-forward
deployments/scale调整副本数

所以,一个用户能 get pods,不一定能 kubectl logs;能 get pods/log,也不一定能 kubectl exec

16.3 verbs#

常见 verbs:

verb含义
get读取单个对象
list列出对象集合
watch持续监听对象变化
create创建对象
update整体更新对象
patch局部更新对象
delete删除单个对象
deletecollection批量删除对象

还有一些特殊 verb:

verb常见用途
bind绑定 Role 或 ClusterRole
escalate创建或修改包含更高权限的 Role / ClusterRole
impersonate模拟其他用户、组或 ServiceAccount
use使用某些资源,例如 PodSecurityPolicy 时代曾常见
approve批准证书签名请求

bindescalateimpersonate 都非常敏感,通常只应该给集群管理员或受控自动化系统。

16.4 resourceNames#

resourceNames 可以把权限限制到具体对象名。

rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["app-config"]
    verbs: ["get", "update"]

这表示只能读取或更新名为 app-config 的 ConfigMap。

注意,listwatch 通常不适合搭配 resourceNames 做精确限制,因为列表请求本身没有指定单个对象名。

16.5 nonResourceURLs#

nonResourceURLs 用于非资源 API 路径,例如:

rules:
  - nonResourceURLs: ["/healthz", "/readyz", "/version"]
    verbs: ["get"]

这类规则只能放在 ClusterRole 中,因为非资源 URL 不属于某个 namespace。

17. 一个完整的人类用户授权例子#

假设 kubeconfig 中当前上下文是:

contexts:
  - name: prod-alice-dev
    context:
      cluster: prod
      user: alice
      namespace: dev
current-context: prod-alice-dev

认证后 API Server 识别出的 username 是 alice

现在希望 alice 只能在 dev namespace 读取 Pod 日志,不能创建、删除 Pod。

可以定义:

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

验证:

kubectl auth can-i list pods -n dev --as=alice
kubectl auth can-i get pods/log -n dev --as=alice
kubectl auth can-i delete pods -n dev --as=alice

预期是:

yes
yes
no

如果 kubeconfig 当前 namespace 也是 dev,那么下面两条命令等价:

kubectl get pods
kubectl get pods -n dev

但 RBAC 看的不是 kubeconfig 文件里写了什么,而是 API Server 认证出的 alice 身份,以及请求落在哪个 namespace。

18. 一个 ServiceAccount 授权例子#

应用运行在 dev namespace,只需要读取本 namespace 的 ConfigMap。

先创建 ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-reader
  namespace: dev

创建 Role:

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

绑定给 ServiceAccount:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-reader-configmap-reader
  namespace: dev
subjects:
  - kind: ServiceAccount
    name: app-reader
    namespace: dev
roleRef:
  kind: Role
  name: configmap-reader
  apiGroup: rbac.authorization.k8s.io

Deployment 使用这个 ServiceAccount:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: dev
spec:
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      serviceAccountName: app-reader
      containers:
        - name: app
          image: nginx

验证:

kubectl auth can-i list configmaps \
  --as=system:serviceaccount:dev:app-reader \
  -n dev

19. 跨 namespace 的 ServiceAccount 授权#

ServiceAccount 属于某个 namespace,但可以被绑定到另一个 namespace 的 RoleBinding 中。

例如:

ServiceAccount 在 dev namespace;
它需要读取 maintenance namespace 中的 Jobs。

做法是在目标 namespace maintenance 创建 Role 和 RoleBinding:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: job-reader
  namespace: maintenance
rules:
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-app-read-maintenance-jobs
  namespace: maintenance
subjects:
  - kind: ServiceAccount
    name: app-reader
    namespace: dev
roleRef:
  kind: Role
  name: job-reader
  apiGroup: rbac.authorization.k8s.io

关键点是:

RoleBinding 放在哪个 namespace,权限就在哪个 namespace 生效;
subjects 里的 ServiceAccount 可以来自另一个 namespace。

20. kubeconfig 里 namespace 和 RBAC namespace 的关系#

假设 kubeconfig 当前 context:

context:
  cluster: prod
  user: alice
  namespace: dev

这只表示默认命令会落到 dev

kubectl get pods

等价于:

kubectl get pods -n dev

RBAC 判断时会看:

user = alice
verb = list
resource = pods
namespace = dev

如果执行:

kubectl get pods -n test

判断条件就变成:

user = alice
verb = list
resource = pods
namespace = test

所以,context 中的 namespace 只是默认值,不是权限边界本身。真正的权限边界来自 RoleBinding 所在 namespace,或者 ClusterRoleBinding 的集群级授权。

21. 常见内置 ClusterRole#

Kubernetes 默认提供一些面向用户的 ClusterRole:

ClusterRole大致含义
cluster-admin超级管理员权限
adminnamespace 管理员,通常不包含资源配额和 namespace 本身管理
edit可修改 namespace 内多数应用资源
view只读查看 namespace 内多数资源

这些通常不是直接改,而是通过 Binding 使用。

给用户 namespace 只读权限:

kubectl create rolebinding alice-view \
  --clusterrole=view \
  --user=alice \
  --namespace=dev

给用户整个集群管理员权限:

kubectl create clusterrolebinding alice-cluster-admin \
  --clusterrole=cluster-admin \
  --user=alice

第二条命令非常敏感,生产环境不要随手使用。

22. roleRef 的特殊性#

RoleBindingClusterRoleBinding 都有 roleRef

roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

roleRef 指向被授予的 Role 或 ClusterRole。

创建后,roleRef 不能直接修改。这样设计是为了避免有人通过修改 binding 的引用,在保留 subject 不变的情况下悄悄把低权限绑定换成高权限绑定。

如果要改绑定的角色,通常删除并重建 binding,或者使用:

kubectl auth reconcile -f rbac.yaml

23. RBAC 是加法模型#

RBAC 没有显式 deny 规则。

如果一个用户同时被多个 RoleBinding 或 ClusterRoleBinding 命中,权限会合并。

例如:

alice 通过 Group dev-team 获得 view;
alice 又通过 User alice 获得 pod delete;
最终 alice 同时拥有 view 和 delete pods 的权限。

授权结果是加法,不会因为另一个 Role 没有写 delete 就抵消掉 delete。

从 Kubernetes API Server 整体授权看,如果没有任何授权器允许请求,请求默认拒绝。RBAC 自己负责表达“允许什么”,不负责表达“禁止什么”。

24. 权限排查命令#

先看当前 context:

kubectl config current-context
kubectl config get-contexts
kubectl config view --minify

如果需要看原始凭据:

kubectl config view --minify --raw

注意,--raw 可能输出证书、key、token 等敏感内容,不要粘贴到公开地方。

再看当前身份:

kubectl auth whoami

检查当前身份是否有权限:

kubectl auth can-i list pods -n dev
kubectl auth can-i get pods/log -n dev
kubectl auth can-i create deployments.apps -n dev
kubectl auth can-i --list -n dev

模拟某个用户或 ServiceAccount:

kubectl auth can-i list pods \
  --as=alice \
  -n dev

kubectl auth can-i list configmaps \
  --as=system:serviceaccount:dev:app-reader \
  -n dev

查看绑定关系:

kubectl get role,rolebinding -n dev
kubectl get clusterrole,clusterrolebinding
kubectl describe rolebinding alice-read-pods -n dev
kubectl describe clusterrolebinding alice-cluster-admin

如果只知道用户或组名,可以搜索所有 binding:

kubectl get rolebinding -A -o yaml
kubectl get clusterrolebinding -o yaml

然后查找 subjects.name 是否命中目标用户、组或 ServiceAccount。

25. Forbidden 排查流程#

当看到类似错误:

Error from server (Forbidden): pods is forbidden:
User "alice" cannot list resource "pods" in API group "" in the namespace "dev"

可以直接拆解:

User: alice
verb: list
resource: pods
apiGroup: ""
namespace: dev

下一步检查:

  1. kubeconfig 当前 context 是否连到正确集群。
  2. 当前认证身份是否真的是 alice
  3. dev namespace 下是否有 RoleBinding 命中 alice 或她所在的 group。
  4. 命中的 Role 或 ClusterRole 是否包含 apiGroups: [""]resources: ["pods"]verbs: ["list"]
  5. 是否误把 RoleBinding 创建到了别的 namespace。
  6. 是否需要的是子资源权限,比如 pods/logpods/exec

如果错误是:

User "system:serviceaccount:dev:app-reader" cannot get resource "secrets"

说明 Pod 使用的是 dev/app-reader 这个 ServiceAccount。要么给它增加权限,要么让 Pod 改用已经拥有对应权限的 ServiceAccount。更好的选择通常是前者,并且只增加必要权限。

26. 常见误区#

26.1 kubeconfig user 名字等于 RBAC username#

不一定。

kubeconfig 的 users[].name 是本地引用名。真实 username 来自认证结果。

客户端证书、token、exec 插件都可能让 API Server 得到不同的 username 和 groups。

26.2 current-context 的 namespace 能授予权限#

不能。

namespace 只是默认请求范围。能不能操作这个 namespace 的资源,由 RBAC binding 决定。

26.3 能 get pods 就能 logs 或 exec#

不一定。

kubectl logs 需要 pods/log 子资源权限。 kubectl exec 需要 pods/exec 子资源权限。

26.4 RoleBinding 绑定 ClusterRole 就是集群权限#

不是。

RoleBinding 的 namespace 会限制授权范围。想要全局授权才使用 ClusterRoleBinding。

26.5 给 default ServiceAccount 授权很安全#

不一定。

如果某个 namespace 下很多 Pod 都没有显式指定 serviceAccountName,它们都会使用 default ServiceAccount。给 default 绑定高权限,等于把这个 namespace 中大量工作负载都提升了权限。

26.6 只读 secrets 没风险#

有风险。

getlistwatch Secrets 都可能暴露 Secret 内容。尤其是 list secrets -o yaml 会返回一批 Secret 的内容。很多时候,能读 Secret 就接近能拿到应用凭据。

26.7 允许创建 Pod 只是部署权限#

不只是。

能创建 Pod 或能创建控制 Pod 的工作负载,往往意味着可以挂载 ConfigMap、Secret、PVC,甚至使用 namespace 内其他 ServiceAccount。生产中给 create podscreate deployments 权限时,要把它视为较高权限。

27. 最小权限实践#

推荐实践:

  1. 人类用户优先绑定到 Group,而不是逐个绑定 User。
  2. 应用不要使用 default ServiceAccount,给每个应用创建专用 ServiceAccount。
  3. Role 优先于 ClusterRoleBinding,namespace 内能解决就不要给集群级权限。
  4. 能用 get 就不要给 list,能用 list 就不要给 watch,能只读就不要给写权限。
  5. 谨慎授予 secretspods/execimpersonatebindescalate
  6. 不要把 kubeconfig、token、客户端私钥提交到 Git 仓库。
  7. 不使用来源不可信的 kubeconfig,尤其要审查 users[].user.exec
  8. 使用 kubectl auth can-i 在变更前后验证权限。

一个比较稳妥的应用权限模型:

一个应用 = 一个 ServiceAccount
一个 ServiceAccount = 一组最小 Role
一个 namespace = 一组清晰的 RoleBinding
跨 namespace 访问 = 明确在目标 namespace 创建 RoleBinding
集群级访问 = 单独审查 ClusterRoleBinding

28. 总结#

把 RBAC 和 kubeconfig 放在同一张图里,可以这样理解:

kubeconfig:
  current-context -> context -> cluster + user + namespace

cluster:
  server + CA -> 连接哪个 API Server,并确认服务端可信

user:
  client cert / token / exec -> 认证成哪个 Kubernetes 身份

namespace:
  默认请求范围,不是权限本身

RBAC:
  Role / ClusterRole -> 定义允许哪些 API 操作
  RoleBinding / ClusterRoleBinding -> 把这些允许规则授给 User / Group / ServiceAccount

最后记住三句话:

kubeconfig 负责“去哪儿”和“我是谁”。
RBAC 负责“我能做什么”。
Forbidden 通常说明认证成功了,但授权没通过。

参考资料#

本文共 7530 字,创建于 Jul 7, 2026

相关标签: Kubernetes, DevOps, ByAI