Cilium Gateway API 实战:使用 RequestHeaderModifier 增删改 HTTP 请求头 📅 发布时间:2026/9/14 20:57:11 👁 浏览次数: Cilium Gateway API 实战使用 RequestHeaderModifier 增删改 HTTP 请求头【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium本文基于 Cilium 官方文档Documentation/network/servicemesh/gateway-api/header.rst编写讲解如何基于 Gateway API 在 Cilium Gateway 上实现入站 HTTP 请求的头部修改Header Modification通过RequestHeaderModifier过滤器的add/set/remove三种动作向请求添加自定义头、覆盖已有头或删除敏感头。读完后你将掌握完整的部署与验证步骤并能从源码层面理解这些过滤器在 Cilium Operator 中如何被转换为 Envoy 数据面配置。背景Gateway 能修改 HTTP 请求头HTTP 头部修改HTTP header modification是指对入站请求执行添加add、删除remove或修改set头部字段的操作。典型用途包括为下游服务注入自定义标识头、统一改写内部追踪头如x-request-id、或在暴露给客户端前剥离内部敏感头。在 Cilium 中头部修改通过 Gateway API 标准的HTTPRoute过滤器配置无需修改 Envoy 配置或部署额外的 Sidecar。Cilium 以 Gateway API 的实现者身份gatewayClassName: cilium解析这些规则由 Operator 将HTTPRouteFilter翻译为数据面规则。准备回显Echo应用验证头部修改最直观的方式是使用一组回显服务客户端请求到达后Echo Pod 会把请求路径、主机、方法、协议以及全部请求头以 JSON 形式原样返回。通过比对响应体中的头部列表即可直观确认 Gateway 的修改是否生效。部署回显应用对应文档中的echo-app.rst段落示例定义见 echo-basic.yaml$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/main/examples/kubernetes/gateway/echo-basic.yaml验证 Pod 正常运行$ kubectl get pods NAME READY STATUS RESTARTS AGE echo-1-7d88f779b-m6r46 1/1 Running 0 21s echo-2-5bfb6668b4-n7llh 1/1 Running 0 21s该文件定义了echo-1、echo-2两个 Deployment 及其 ServiceService 端口8080映射到容器端口3000targetPort: 3000。后续 HTTPRoute 的backendRefs将指向这些 Service。部署 Cilium Gateway 与 HTTPRoute要为入站请求添加头部使用类型为RequestHeaderModifier的过滤器指定add动作及头部的名称和值。完整示例见 request-header.yaml--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: cilium-gw spec: gatewayClassName: cilium listeners: - protocol: HTTP port: 80 name: web-gw-echo allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-http-echo spec: parentRefs: - name: cilium-gw rules: - matches: - path: type: PathPrefix value: /add-a-request-header filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: my-header-name value: my-header-value backendRefs: - name: echo-1 port: 8080这个示例会在请求中添加名为my-header-name、值为my-header-value的头部。逐条说明关键配置字段含义spec.gatewayClassName: cilium指定由 Cilium 实现该 Gateway要求集群中已存在名为cilium的 GatewayClasslisteners[].protocol: HTTP/port: 80Gateway 在 80 端口以明文 HTTP 监听allowedRoutes.namespaces.from: Same只接受与 Gateway 同命名空间内的路由绑定spec.parentRefs将 HTTPRoute 绑定到名为cilium-gw的 Gatewaymatches[].path.type: PathPrefix前缀匹配/add-a-request-headerfilters[].type: RequestHeaderModifierGateway API v1 标准过滤器类型作用于请求方向requestHeaderModifier.add添加头部的键值对列表backendRefs流量转发目标echo-1:8080部署并查看 Gateway 状态$ kubectl apply -f examples/kubernetes/gateway/request-header.yaml $ kubectl get gateway cilium-gw NAME CLASS ADDRESS PROGRAMMED AGE cilium-gw cilium 172.18.255.200 8s上述命令创建了监听 80 端口的 Gatewaycilium-gw。ADDRESS列即为可访问的 Gateway 地址部分云厂商如 EKS 可能给出完全限定域名而非 IP属正常现象。可将其记为环境变量GATEWAY供后续 curl 使用。验证 add向请求添加头部$ curl -s http://$GATEWAY/add-a-request-header { path: /add-a-request-header, host: 172.18.255.200, method: GET, proto: HTTP/1.1, headers: { Accept: [ */* ], My-Header-Name: [ my-header-value ], User-Agent: [ curl/7.81.0 ], X-Envoy-Internal: [ true ], X-Forwarded-For: [ 172.18.0.1 ], X-Forwarded-Proto: [ http ], X-Request-Id: [ 61a72702-3dfa-4bc3-a21c-7544ef36af7b ] }, httpPort: 3000, namespace: default, ingress: , service: , pod: echo-1-7d88f779b-m6r46 }响应体中可以看到My-Header-Name: my-header-value这一条目——该头并不存在客户端原始请求中curl 只发送了Accept与User-Agent它正是 Gateway 依据add规则注入的。其余头部如X-Forwarded-For、X-Forwarded-Proto、X-Request-Id是 Cilium 数据面Envoy 层自动补充的标准代理头。验证 remove删除请求头使用remove关键字加头部名称列表即可删除请求头例如filters: - type: RequestHeaderModifier requestHeaderModifier: remove: [x-request-id]为匹配规则增加remove-a-request-header前缀匹配后x-request-id即被剥离$ curl --fail -s http://$GATEWAY/remove-a-request-header { path: /remove-a-request-header, host: 172.18.255.200, method: GET, proto: HTTP/1.1, headers: { Accept: [ */* ], User-Agent: [ curl/7.81.0 ], X-Envoy-Internal: [ true ], X-Forwarded-For: [ 172.18.0.1 ], X-Forwarded-Proto: [ http ] }, httpPort: 3000, namespace: default, ingress: , service: , pod: echo-1-7d88f779b-m6r46 }对比 add 场景的响应此处头部列表中已没有X-Request-Id字段说明remove生效。验证 set修改已有头部使用set动作可同时指定头部名称与新值用于覆盖已有头部在 Gateway API 语义中set无论头部原先是否存在都会写入该值filters: - type: RequestHeaderModifier requestHeaderModifier: set: - name: x-request-id value: set-cilium-header-value配合edit-a-request-header前缀匹配后x-request-id被改写$ curl -s http://$GATEWAY/edit-a-request-header { path: /edit-a-request-header, host: 172.18.255.200, method: GET, proto: HTTP/1.1, headers: { Accept: [ */* ], User-Agent: [ curl/7.81.0 ], X-Envoy-Internal: [ true ], X-Forwarded-For: [ 172.18.0.1 ], X-Forwarded-Proto: [ http ], X-Request-Id: [ set-cilium-header-value ] }, httpPort: 3000, namespace: default, ingress: , service: , pod: echo-1-7d88f779b-m6r46 }可以看到X-Request-Id的取值已从数据面生成的 UUID 变为配置中指定的set-cilium-header-value。三种动作的语义小结add追加头部。若头部已存在行为遵循 Gateway API 规范——在值不冲突时可产生多头set设置/覆盖头部。无论原先是否存在都写入给定值原值为空时清除原值remove按名称删除头部列表形式一次可删除多个。源码视角Cilium 如何翻译头部过滤器上述 YAML 从控制面走到数据面的转换逻辑可以从源码结构中找到清晰的证据。Cilium Operator 中的 Gateway API 模型摄取代码 operator/pkg/model/ingestion/gateway.go 对HTTPRoute与GRPCRoute的过滤器逐一做了分支处理case gatewayv1.HTTPRouteFilterRequestHeaderModifier: // ... HeadersToAdd: toHTTPHeaders(f.RequestHeaderModifier.Add), HeadersToSet: toHTTPHeaders(f.RequestHeaderModifier.Set), HeadersToRemove: f.RequestHeaderModifier.Remove, // ... case gatewayv1.HTTPRouteFilterResponseHeaderModifier: ResponseHeaderModifier: model.HTTPHeaderFilter{ HeadersToAdd: toHTTPHeaders(f.ResponseHeaderModifier.Add), HeadersToSet: toHTTPHeaders(f.ResponseHeaderModifier.Set), HeadersToRemove: f.ResponseHeaderModifier.Remove, },从源码结构看可以得到几个实现层面的结论add/set/remove三个字段一一映射为内部模型model.HTTPHeaderFilter的HeadersToAdd、HeadersToSet、HeadersToRemove随后由数据面Envoy下发为对应的头部操作配置响应方向同样受支持ResponseHeaderModifier过滤器以完全相同的方式翻译即可以对后端返回的响应头执行同样的增删改操作gRPC 场景同样覆盖同文件gateway.go中GRPCRouteFilterRequestHeaderModifier/GRPCRouteFilterResponseHeaderModifier分支表明 gRPC 路由也能使用头部修改过滤器——这与grpc语义一致因为 gRPC 底层同样是 HTTP/2 头部过滤器合法性由路由检查模块把关operator/pkg/gateway-api/routechecks/httproute.go 及其测试httproute_test.go负责在控制面对RequestHeaderModifier等过滤器做有效性校验不合法的过滤器会导致 HTTPRoute 状态被标记为未 accepted/programmed而不是被静默忽略。此外Gateway API 项目自带的符合性测试vendored 于 vendor/sigs.k8s.io/gateway-api/conformance/tests/httproute-request-header-modifier.go验证了add/set/remove的标准行为语义Cilium 通过 Gateway API 符合性测试意味着本文演示的行为在不同厂商实现间是可移植的。常见问题排查kubectl get gateway中ADDRESS为空Gateway 尚未被 Cilium 编程Programmed。检查是否存在名为cilium的 GatewayClass 且其状态为 Accepted可参考 Gateway API 安装与排错文档 installation.rst、troubleshooting.rst。响应中看不到新头部先确认请求路径命中了对应 rule 的matches前缀本文示例分别为/add-a-request-header、/remove-a-request-header、/edit-a-request-header再看kubectl describe httproute中该规则是否被 Accepted 与 Programmed。EKS 等环境下 ADDRESS 是 FQDN属正常现象直接以域名访问即可。小结本文完整走通了 Cilium 环境下 Gateway API 请求头修改的实操闭环部署 回显应用 → 部署 Gateway 与 HTTPRoute 示例 → 用 curl 验证add/remove/set三种动作的实际效果。实现上Cilium Operator 在 operator/pkg/model/ingestion/gateway.go 中将 Gateway API 的RequestHeaderModifier以及ResponseHeaderModifier、gRPC 变体翻译成统一的内部头部过滤器模型从而把声明式的 YAML 规则落到 Envoy 数据面。由于全部基于 Gateway API v1 标准字段这套头部修改能力可以在支持相同 GatewayClass 语义的集群之间平滑迁移。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考