kube-rbac-proxy 授权原理深度解读:SubjectAccessReview 是如何工作的?
kube-rbac-proxy 授权原理深度解读:SubjectAccessReview 是如何工作的?
【免费下载链接】kube-rbac-proxyKubernetes RBAC authorizing HTTP proxy for a single upstream.项目地址: https://gitcode.com/gh_mirrors/ku/kube-rbac-proxy
kube-rbac-proxy 是一个面向单一上游服务的 Kubernetes RBAC 授权 HTTP 代理,其授权核心正是 Kubernetes 的SubjectAccessReview(SAR)机制。本文带你从源码角度深度解读 kube-rbac-proxy 工作原理:一次 HTTP 请求如何被翻译成一次 RBAC 授权检查,TokenReview 与 SubjectAccessReview 两次 API 调用如何协同,以及结果缓存、静态授权器、请求重写等进阶机制的真实实现,帮你彻底搞懂这套侧车代理的授权链路。
为什么普通服务需要 SubjectAccessReview 代理?🚪
在默认配置下,Kubernetes 集群内任何 Pod 都能访问其他 Pod 的网络端口。如果你的应用(比如 Prometheus 的 metrics 端点)希望只允许持有合法 RBAC 权限的调用方访问,就需要一个"门卫":
- 校验调用方身份(你是谁?)
- 校验调用方权限(你能做这件事吗?)
- 通过后才把请求转发给真正的上游应用
kube-rbac-proxy 正是扮演这个门卫角色。它不自己实现权限判断,而是把判断委托给 Kubernetes API Server 的 SubjectAccessReview 接口,因此你的 RBAC 策略只维护一份,规则完全统一。
kube-rbac-proxy 完整工作流程:认证 → 授权 → 转发
一次请求从进入到转发,需要依次穿过三个过滤器(见pkg/filters/auth.go),顺序至关重要:
| 顺序 | 过滤器 | 作用 | 失败返回 |
|---|---|---|---|
| 1 | WithAuthentication | 身份认证 | 401 Unauthorized |
| 2 | WithAuthorization | RBAC 授权 | 403 Forbidden |
| 3 | WithAuthHeaders | 注入用户信息到请求头 | — |
在入口处(cmd/kube-rbac-proxy/app/kube-rbac-proxy.go的Run函数),处理器会按照WithAuthHeaders → WithAuthorization → WithAuthentication的顺序层层包裹,也就是先认证、再授权、最后才放行。此外--ignore-paths配置的路径可以完全跳过认证授权直接转发。
第一次 API 调用:TokenReview 完成身份认证 🎫
当客户端携带 Bearer Token 访问时,kube-rbac-proxy 调用authentication.k8s.io的TokenReview接口,把 token 交给 API Server 校验签名、有效期和 audiences,换取一个标准的 Kubernetes 用户对象(用户名 + 组)。
这一逻辑位于pkg/authn/delegating.go,通过authenticatorfactory.DelegatingAuthenticatorConfig构建,其中:
- 匿名访问被强制关闭(
Anonymous.Enabled = false) - TokenReview 结果缓存 2 分钟(
CacheTTL) - 如果配置了
--client-ca-file,客户端 TLS 证书也是合法的认证方式
认证成功后,用户对象被写入请求上下文,供下一步授权使用。
第二次 API 调用:SubjectAccessReview 完成授权 ✅
认证通过后,kube-rbac-proxy 调用authorization.k8s.io的SubjectAccessReview接口,把"用户 + 请求属性"打包发送给 API Server,由 API Server 基于 RBAC 规则做出 Allow / Deny / NoOpinion 的判断。
创建 SAR 授权器的核心代码在pkg/authz/auth.go的NewSarAuthorizer:
- 设置
SubjectAccessReviewClient指向 Authorization V1 接口 - 允许结果缓存 5 分钟(
AllowCacheTTL) - 拒绝结果缓存 30 秒(
DenyCacheTTL)
正是这两个缓存 TTL,让高频请求不必每次都打到 API Server,性能大幅提升。
SubjectAccessReview 的关键:请求如何被翻译成授权属性 🔑
API Server 只认 RBAC 属性,不认识 HTTP 请求。kube-rbac-proxy 的核心魔法就在pkg/proxy/proxy.go的GetRequestAttributes:把 HTTP 请求翻译成authorizer.Attributes。
HTTP 方法到 RBAC 动词的映射表
| HTTP 方法 | RBAC 动词 |
|---|---|
| POST | create |
| GET | get |
| PUT | update |
| PATCH | patch |
| DELETE | delete |
| 其他 | *(任意) |
资源请求与非资源请求
RBAC 授权区分两类请求:
- 非资源请求:不配置
resourceAttributes时,代理直接使用 URL 路径(如/metrics)构造属性,对应 RBAC 中的nonResourceURLs规则。 - 资源请求:配置
resourceAttributes后,通过 namespace、apiGroup、resource、subresource、name 构造属性,对应 RBAC 中的resources规则。
例如examples/resource-attributes示例中,要求调用方对 Servicekube-rbac-proxy拥有services/proxy子资源的get权限,SAR 请求就会携带这组资源属性去校验。
双保险:静态授权器与 SAR 授权器如何叠加 🛡️
细心的读者会发现:Run函数中创建了两个授权器,并通过union.New组合:
- 静态授权器(
NewStaticAuthorizer):在本地配置里做精确匹配,支持用户名、动词、命名空间、资源、路径等字段,全部匹配才放行。命中即返回 Allow,不命中返回 NoOpinion,不会拒绝。 - SAR 授权器(
NewSarAuthorizer):走 SubjectAccessReview 委托 API Server 判断。
两个授权器按"先静态、后 SAR"的顺序求并集,只要其中一个允许,请求就放行。这种设计既支持纯本地白名单(性能最好),也支持完全交给 Kubernetes RBAC 管理(策略最统一)。
高级配置:按请求重写 SubjectAccessReview ✍️
kube-rbac-proxy 还支持根据请求参数动态改写 SAR 内容(见examples/rewrites示例),适用于多租户场景:
rewrites.byQueryParameter:从 URL 查询参数取值rewrites.byHTTPHeader:从请求头取值resourceAttributes中支持 Go 模板{{ .Value }},把参数值注入属性字段
比如把 URL 中的?namespace=foo映射到 SAR 的 namespace 字段,这样同一个代理就可以服务不同命名空间的授权校验,灵活度极高。
部署前必看的 RBAC 权限配置 📋
kube-rbac-proxy 自身需要两个 API 的创建权限才能工作:
rules: - apiGroups: ["authentication.k8s.io"] resources: ["tokenreviews"] verbs: ["create"] - apiGroups: ["authorization.k8s.io"] resources: ["subjectaccessreviews"] verbs: ["create"]完整可运行的 Deployment、Service、ConfigMap 与 RBAC 清单可以直接参考examples/resource-attributes/deployment.yaml和examples/rewrites/deployment.yaml。
另外提醒一句:使用 Token 认证时,接收方可以冒充调用方身份。请只在调用方 token 权限足够低、或接收方权限本身更高的情况下使用 Token 认证;生产环境更推荐 mTLS 客户端证书方案。
总结:理解 SubjectAccessReview 是掌握 kube-rbac-proxy 的关键 🎯
回顾全文,kube-rbac-proxy 的授权原理可以浓缩为一句话:它把"HTTP 请求"翻译成"RBAC 属性",再通过 SubjectAccessReview 委托 API Server 裁决,并辅以静态白名单和结果缓存来提升性能与灵活性。
- 认证靠TokenReview(你是谁),授权靠SubjectAccessReview(你能做什么)
- 属性翻译逻辑在
pkg/proxy/proxy.go,授权器在pkg/authz/auth.go,过滤器链在pkg/filters/auth.go - 允许缓存 5 分钟、拒绝缓存 30 秒,是性能优化的关键参数
掌握了这条链路,你就能自信地在生产集群里部署 kube-rbac-proxy,并针对业务场景定制资源属性与重写规则了。如果你正准备保护自己的 metrics 端点或内部服务,不妨按照上面的流程亲手搭建一遍,感受"一次认证、二次授权"的完整闭环。
【免费下载链接】kube-rbac-proxyKubernetes RBAC authorizing HTTP proxy for a single upstream.项目地址: https://gitcode.com/gh_mirrors/ku/kube-rbac-proxy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
