bigywater.tech
Kubernetes · 92

kubectl auth can-i:鉴权结果的查询接口

怎么在不真正执行的前提下判断某个用户有没有某个权限?kubectl auth can-i 到底调了什么 API?reason 能告诉我什么?--list 可靠吗?这篇用 alice 的几条权限把 can-i 的各种用法都跑一遍,并直接提交三种 Review 对象。

0 / 1
can-i 的退出码:yes 为 0,no 为 1,可直接用在脚本里
selfsubjectaccessreviews
can-i 背后调用的 API 资源;请求头带 --as 对应的 Impersonate-User
incomplete=false
SelfSubjectRulesReview 结果完整的标志;Webhook 授权器会让它变成 true

常见查询

实测 · 本机执行输出
  can-i list pods                   --as=alice -n k86 → yes(退出码 0)
  can-i delete pods                 --as=alice -n k86 → no(退出码 1)
  can-i get pods/log                --as=alice -n k86 → yes(退出码 0)
  can-i get configmaps/app-cfg      --as=alice -n k86 → yes(退出码 0)
  can-i get configmaps/other        --as=alice -n k86 → no(退出码 1)
  can-i update configmaps/app-cfg   --as=alice -n k86 → yes(退出码 0)
  换成命名空间 default:['no'](退出码 1)
  --all-namespaces:['no'](RoleBinding 只在 k86 里生效)
  集群级资源 nodes:['no']
  非资源 URL /healthz(system:public-info-viewer 默认允许认证用户):['yes']
  非资源 URL /metrics:['no']

alice 在命名空间 k86 有 Role pod-reader(pods get/list、pods/log get、configmap app-cfg get/update)。can-i list pods → yes(退出码 0),delete pods → no(退出码 1),get pods/log → yes,get configmaps/app-cfg → yes,get configmaps/other → no(resourceNames 限制),update configmaps/app-cfg → yes。换到 default 命名空间、--all-namespaces、集群级资源 nodes 都是 no;非资源 URL /healthz → yes(system:public-info-viewer 默认允许),/metrics → no。

背后的 API

实测 · 本机执行输出
  Impersonate-User: alice
  I1011 01:36:19.884403 49837 round_trippers.go:527] "Request" verb="POST" url="https://127.0.0.1:50727/apis/authorization.k8s.io/v1/selfsubjectaccessreviews" headers=<
  Impersonate-User: alice
  I1011 01:36:19.885454 49837 round_trippers.go:632] "Response" status="201 Created" headers=<
  自己提交 SelfSubjectAccessReview(--as=alice,list pods):allowed=True;reason='RBAC: allowed by RoleBinding "alice-reader/k86" of Role "pod-reader" to User "alice"'
  直接提交 SubjectAccessReview(user: alice, list pods):allowed=True;reason='RBAC: allowed by RoleBinding "alice-reader/k86" of Role "pod-reader" to User "alice"'
  delete pods:allowed=False;reason=None
  给 SubjectAccessReview 加上 groups: [system:masters],delete pods:allowed=True;reason=None

-v=8 能看到 kubectl auth can-i 只是发了一次 POST https://…/apis/authorization.k8s.io/v1/selfsubjectaccessreviews,请求头里有 Impersonate-User: alice,返回 201 Created。自己提交 SelfSubjectAccessReview 得到 allowed=true 和 reason: RBAC: allowed by RoleBinding "alice-reader/k86" of Role "pod-reader" to User "alice"——能告诉你是哪条绑定放行的。直接提交 SubjectAccessReview(spec.user=alice)结果相同;delete pods 是 allowed=false 且 reason 为空;给它加上 groups: [system:masters] 后 delete 变成 allowed=true、reason 为空——超级用户组由专门的授权器放行,没有 RBAC 的理由。

--list

实测 · 本机执行输出
  can-i --list -n k86 --as=alice:共 22 行;和 pod-reader 相关的:
    pods [] [] [get list]
    configmaps [] [app-cfg] [get update]
    pods/log [] [] [get]
  直接提交 SelfSubjectRulesReview:incomplete=False;resourceRules 5 条,nonResourceRules 2 条;evaluationError=None

kubectl auth can-i --list -n k86 --as=alice 共 22 行,其中和 pod-reader 相关的是 pods [get list]、configmaps [app-cfg] [get update]、pods/log [get]。它背后是 SelfSubjectRulesReview:直接提交得到 incomplete=False、resourceRules 5 条、nonResourceRules 2 条。这个列表是规则展开,适合人看;要精确判断某个具体操作,还是用具体的 can-i 或 SubjectAccessReview(incomplete=true 时尤其不能依赖列表,比如集群配了 Webhook 授权器)。

小陷阱

实测 · 本机执行输出
  资源名写错(podz):['no', "Warning: the server doesn't have a resource type 'podz'"](只给警告,结果仍是 no)
  --subresource=log:['yes']
  -q 只返回退出码:1(输出:空)
  --as=alice --as-group=system:masters delete pods:['yes'](管理员可以模拟任意组;组也参与鉴权)

资源名写错(podz)只给 Warning: the server doesn't have a resource type 'podz',结果仍是 no,所以 “no” 不一定是没权限;--subresource=log 查 get pods/log;-q 不输出,只用退出码;--as=alice --as-group=system:masters 的 delete pods → yes——模拟时 --as-group 会改变结果。

分步演示

auth can-i
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0,kubectl v1.36);alice 是一个不存在的用户,权限来自命名空间 k86 里的 Role 和 RoleBinding;“管理员”用于 --as 模拟;kubectl -v=8 的请求体是 protobuf 不可读,所以另外用 kubectl create -f 直接提交三种 Review 对象看 JSON;每种情形各一次
    • 没有验证:Webhook 授权器 / Node 授权器 / ABAC 下 SubjectAccessReview 的 reason 与 incomplete;LocalSubjectAccessReview(命名空间级);SelfSubjectReview 与 auth whoami;审计日志里 SubjectAccessReview 的记录;大规模 RoleBinding 下 can-i --list 的耗时
    京ICP备2026067502号-1京公网安备11010502063487号