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