ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Cilium Gateway API 外部鉴权实战:用 ExternalAuth 过滤器把 HTTP/gRPC 鉴权下沉到独立 Auth Service

Cilium Gateway API 外部鉴权实战:用 ExternalAuth 过滤器把 HTTP/gRPC 鉴权下沉到独立 Auth Service Cilium Gateway API 外部鉴权实战用 ExternalAuth 过滤器把 HTTP/gRPC 鉴权下沉到独立 Auth Service【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium导读本文基于 Cilium 仓库中examples/kubernetes/gateway/external-authz示例完整讲解如何在 Cilium Gateway API 体系中通过HTTPRoute的ExternalAuth过滤器把请求鉴权前置到独立的外部鉴权服务auth service。你将掌握最小可用的 HTTP/gRPC 双协议 ext_authz 测试服务的构建与部署方法、五种典型HTTPRoute配置HTTP 鉴权、共享配置复用、鉴权参数变体、gRPC 鉴权、无鉴权对照以及 Cilium Operator 侧 ExternalAuth 过滤器的解析与下发链路从而能够在自己的集群中快速复现、验证并扩展这套外部鉴权方案。目录结构与示例定位示例代码位于仓库的 examples/kubernetes/gateway/external-authz 目录共四个文件文件作用README.md示例说明构建、部署、验证步骤与预期行为manifests.yaml一次性清单命名空间、Deployment/Service、Gateway 与 5 条 HTTPRoutemain.go最小鉴权服务实现同时提供 HTTP 与 gRPC 两种 ext_authz 端点Dockerfile多阶段构建Go 编译 无发行版的 static 运行镜像这个示例属于 Cilium 对 Gateway APIExternalAuth过滤器的实验性支持。文档 nginx-annotations-migration.rst 在迁移对照表中也把ExternalAuth-style HTTPRoute filter 标注为实验特性因此本文所有配置均以当前仓库为准并在文末给出使用边界提示。测试鉴权服务一个最小可用的 ext_authz 实现示例中的 auth serviceext-authz-test是一个刻意保持极简的鉴权服务它的全部行为可以概括为三句话HTTP ext_authz 端点监听8080端口gRPC ext_authz 端点监听9000端口两种协议下总是放行always allow、每个请求打一行日志、并在放行响应中注入X-Test-Authz响应头。之所以总是放行是为了让使用者把注意力完全集中在 Gateway API 配置与请求转发路径上而不是纠缠于鉴权策略本身——你完全可以在main.go的Check中加上自己的 token 校验逻辑把它改造成真实的鉴权服务。入口与双协议启动流程从源码看main.go 的启动逻辑非常清晰main函数L49-L108端口可通过环境变量HTTP_PORT默认8080与GRPC_PORT默认9000覆盖通过signal.NotifyContext监听SIGINT/SIGTERM实现优雅退出使用errgroup并发启动两个服务器http.Server挂在/healthz就绪/存活探针与/鉴权处理两个路由上gRPC 服务器同时注册了envoy.service.auth.v3.Authorization服务authv3.RegisterAuthorizationServer和grpc.health.v1.Health健康检查服务收到退出信号后先GracefulStopgRPC再以 5 秒超时关闭 HTTP。HTTP 鉴权行为/路由newHTTPMuxL110-L128中的处理逻辑如下/healthz返回200 ok供 Deployment 的readinessProbe与livenessProbe使用其余所有路径/兜底视为鉴权请求打印一行结构化日志method、path、host、排序后的 header 列表随后设置X-Test-Authz: allowed-http响应头返回200 allowed。gRPC 鉴权行为Check方法gRPC 端实现了 Envoy ext_authz 标准接口CheckL130-L159从CheckRequest.Attributes.Request.Http中提取 method、path、host 与 headers 并打印日志返回CheckResponseStatus为OKHttpResponse为OkHttpResponse其中通过Headers注入x-test-authz: allowed-grpc并通过DynamicMetadata写入resultallowed。这套响应结构与 Envoy 的envoy.service.auth.v3协议完全对齐而 Cilium 代理正是通过内置 Envoy 来执行 Gateway API 过滤器在 pkg/envoy/resource/envoy.go 中注册了envoy.extensions.filters.http.ext_authz/v3过滤器因此示例服务可以无缝对接。构建镜像并导入 kind 集群README 针对本地kind集群给出了两条命令docker build -t external-authz-test:dev -f examples/kubernetes/gateway/external-authz/Dockerfile . kind load docker-image external-authz-test:dev第一条命令用 Dockerfile 构建镜像第一阶段基于golang:1.26关闭 CGO 并启用 vendor 模式编译external-authz二进制第二阶段基于cgr.dev/chainguard/static:latest无发行版基础镜像仅拷贝二进制作为入口镜像体积小、攻击面小。第二条命令把本地镜像导入 kind 节点避免触发镜像拉取Deployment 中imagePullPolicy: IfNotPresent与image: external-authz-test:dev正是为此设计。如果不是 kind而是其他集群需要把external-authz-test:dev推送到集群可访问的镜像仓库并相应修改 manifests.yaml 中的镜像地址。部署前置条件README 明确列出两条假设缺一不可Cilium Gateway API 支持已启用例如 Helm 安装时开启gatewayAPI.enabledtrue已安装带ExternalAuth支持的 Gateway API CRDs。这是因为ExternalAuth过滤器尚属实验特性需要安装了对应实验版 CRD schema 的 Gateway API 版本标准 GA 版 CRD 中可能并不包含该过滤器字段。因此请先确认集群中的gateway.networking.k8s.io/v1CRD 已支持HTTPRouteFilterExternalAuth再执行部署。一键部署完整演示环境满足前置条件后执行 README 中的单条命令即可创建整套资源kubectl apply -f examples/kubernetes/gateway/external-authz/manifests.yaml该清单manifests.yaml会依次创建命名空间gateway-external-authz-demoauth-serviceext-authz-testDeployment1 副本暴露http:8080与grpc:9000带/healthz就绪与存活探针 同名 Servicehttp:8080、grpc:9000两个端口echo 后端基于gcr.io/k8s-staging-gateway-api/echo-basic镜像的echoDeployment Service8080端口一个 Gatewayext-authz-gateway使用gatewayClassName: ciliumHTTP 监听器web端口 80允许同命名空间路由五条 HTTPRoute覆盖五类鉴权场景。下面逐个拆解这五条 HTTPRoute 的配置。场景一HTTP ExternalAuth/http-auth第一条路由ext-authz-http展示了最基础的 HTTP 外部鉴权apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ext-authz-http namespace: gateway-external-authz-demo spec: parentRefs: - name: ext-authz-gateway rules: - matches: - path: type: PathPrefix value: /http-auth filters: - type: ExternalAuth externalAuth: protocol: HTTP backendRef: name: auth-service port: 8080 http: path: /check allowedResponseHeaders: - X-Test-Authz backendRefs: - name: echo port: 8080关键点filters[].type: ExternalAuth声明启用外部鉴权externalAuth.protocol: HTTP指定鉴权走 HTTP 协议backendRef指向auth-service:8080HTTP 端点externalAuth.http.path: /check指定 Cilium 向鉴权服务发送请求时使用的路径——注意示例服务对所有非/healthz路径一视同仁地放行所以这里使用任意路径均可allowedResponseHeaders: [X-Test-Authz]声明允许把鉴权服务响应头中的X-Test-Authz透传回原始客户端。示例服务返回的X-Test-Authz: allowed-http正是通过这个白名单才能出现在最终响应里。场景二复用同一鉴权配置/http-auth-shared路由ext-authz-http-shared的ExternalAuth配置与场景一完全相同同一个 auth service、同一个/check路径、同一个响应头白名单只是匹配路径换成了/http-auth-shared。它用于验证一份鉴权配置被多个路由共享的复用模型——在真实场景中这通常意味着多组 API 路径共用同一套 OIDC/OAuth2 鉴权服务无需重复配置。场景三鉴权参数变体/http-auth-variant路由ext-authz-http-variant复用了同一个鉴权服务但换了不同的鉴权参数filters: - type: ExternalAuth externalAuth: protocol: HTTP backendRef: name: auth-service port: 8080 http: path: /variant-check allowedHeaders: - X-Debug-Token allowedResponseHeaders: - X-Test-Authz与场景一/二对比差异有两处http.path改为/variant-check验证不同路由可以向鉴权服务请求不同鉴权路径新增allowedHeaders: [X-Debug-Token]声明把客户端请求头X-Debug-Token转发给鉴权服务。这正是 README 验证步骤中使用curl -H X-Debug-Token: demo的原因——带上这个头后你可以在 auth-service 的日志里看到它被转发进来。场景四gRPC ExternalAuth/grpc-auth路由ext-authz-grpc演示 gRPC 协议的外部鉴权filters: - type: ExternalAuth externalAuth: protocol: GRPC backendRef: name: auth-service port: 9000 grpc: {} backendRefs: - name: echo port: 8080关键差异externalAuth.protocol: GRPCbackendRef指向 auth-service 的 gRPC 端点9000grpc: {}为 gRPC 鉴权配置占位当前示例未启用额外选项如allowedRequestHeaders等。此时 Cilium 代理会通过 Envoy 的 gRPC ext_authz 过滤器把鉴权请求以envoy.service.auth.v3.Authorization/CheckRPC 发送给服务端触发 main.go 中实现的Check方法。场景五无鉴权对照/no-auth路由no-auth没有配置任何过滤器直接backendRefs指向 echo 后端。它是验证链路差异的对照组请求应当直接到达后端auth-service 日志中不会出现对应记录。验证观察请求如何穿过鉴权过滤器第一步获取网关地址kubectl -n gateway-external-authz-demo get gateway ext-authz-gateway从输出中取得 Gateway 的对外地址LoadBalancer IP 或主机名记为GATEWAY_ADDRESS。第二步发送五类请求curl -i http://GATEWAY_ADDRESS/http-auth curl -i http://GATEWAY_ADDRESS/http-auth-shared curl -i -H X-Debug-Token: demo http://GATEWAY_ADDRESS/http-auth-variant curl -i http://GATEWAY_ADDRESS/grpc-auth curl -i http://GATEWAY_ADDRESS/no-auth注意第三条命令带了X-Debug-Token: demo请求头用于验证场景三中allowedHeaders的转发行为。第三步观察鉴权日志kubectl -n gateway-external-authz-demo logs deploy/ext-authz-test -f日志以slog文本格式输出。HTTP 请求会打出http ext_authz request行包含 method、path、host 以及排好序的 header 列表flattenHTTPHeaders实现gRPC 请求会打出grpc ext_authz request行同样包含 method/path/host/headers。预期行为对照表请求路径auth-service 是否出现日志说明/http-auth是HTTP 请求基础 HTTP 鉴权/http-auth-shared是HTTP 请求同一鉴权配置被复用/http-auth-variant是HTTP 请求auth path 为/variant-check同一服务、不同鉴权参数/grpc-auth是gRPC 请求gRPC 协议外部鉴权/no-auth否无鉴权过滤器直达后端若/http-auth的响应中能看到X-Test-Authz: allowed-http、/grpc-auth的响应中能看到X-Test-Authz: allowed-grpc说明allowedResponseHeaders白名单透传生效同时/http-auth-variant的日志里应能看到X-Debug-Tokendemo证明allowedHeaders转发生效。原理纵深ExternalAuth 过滤器在 Cilium 中的处理链路从 HTTPRoute 到内部模型ExternalAuth过滤器并不是由数据面直接魔法处理的它在 Cilium Operator 中先被转换成语义化的内部模型。核心实现在 operator/pkg/model/ingestion/gateway.go 的toHTTPExternalAuthFilter函数若ExternalAuth过滤器存在但未指定端口Operator 会打印告警并直接忽略该过滤器ExternalAuth filter has no port specified; filter will be ignored解析backendRef指向的服务与端口解析跨命名空间引用及BackendTLSPolicy细节addBackendTLSDetails构造model.HTTPExternalAuthFilter其字段与 CRD 一一对应ProtocolHTTP/GRPC、PathPrefix对应http.path、AllowedRequestHeaders对应allowedHeaders、AllowedResponseHeaders对应allowedResponseHeaders以及ForwardBody当forwardBody.maxSize 0时启用请求体转发。此外operator/pkg/gateway-api/indexers/httproute.go 中实现了对ExternalAuth过滤器后端服务的索引并有对应单测保证当鉴权服务本身发生变化时引用它的路由能被正确关联与更新。从模型到 Envoy 过滤器内部模型最终会在代理侧翻译为 Envoy 的 ext_authz HTTP 过滤器配置。Cilium 的 Envoy 资源注册文件 pkg/envoy/resource/envoy.go 与 cec_resource_parser.go 分别注册并导入了envoy.extensions.filters.http.ext_authz/v3HTTP 过滤器与envoy.extensions.filters.network.ext_authz/v3而示例服务实现的正是这一套过滤器所需的envoy.service.auth.v3协议。整条链路可以概括为HTTPRoute(filters[].typeExternalAuth) → Operator: toHTTPExternalAuthFilter() 解析为 model.HTTPExternalAuthFilter → 代理侧生成 Envoy ext_authz filter 配置 → Envoy 按 protocol 调用 auth-service 的 HTTP(8080) 或 gRPC(9000) 端点 → 鉴权服务返回 OK(放行) 或 NonOK(拒绝)响应头按白名单透传 → 放行后请求继续转发到 echo 后端使用边界与后续扩展建议该特性在本文档语境下为实验性字段语义可能随 Gateway API 上游演进调整生产使用前请核对所用 Cilium 版本的 CRD 与升级说明示例服务总是放行实际接入时可在CheckgRPC或/处理器HTTP中增加 token/JWT 校验并将Status置为PermissionDenied等非 OK 状态码即可实现拒绝语义通过allowedHeaders可以把客户端身份头如Authorization、X-User转发给鉴权服务通过allowedResponseHeaders可以把鉴权服务产出的头如X-Test-Authz、用户信息透传给下游若鉴权服务需要校验请求体如签名类鉴权可通过forwardBody开启请求体转发maxSize限制大小。小结examples/kubernetes/gateway/external-authz为 Cilium Gateway API 的ExternalAuth过滤器提供了一套完整、可复现的最小演示一个同时暴露 HTTP/gRPC ext_authz 端点的测试服务、一份覆盖五类鉴权场景的清单以及清晰的验证步骤。配合 Operator 侧的解析实现toHTTPExternalAuthFilter与代理侧的 Envoy ext_authz 过滤器你可以快速理解HTTPRoute 声明鉴权 → 控制器下发配置 → 代理调用外部鉴权服务 → 放行/拒绝的完整链路并以此为骨架搭建生产级的外部鉴权方案。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表