用 Ingress2Gateway 一条命令完成 Gateway API 迁移
【免费下载链接】ingress2gatewayConvert Ingress resources to Gateway API resources项目地址: https://gitcode.com/gh_mirrors/in/ingress2gateway
集群里还压着两百条 ingress-nginx 规则,deadline 卡在周五,你不想再对着上百个 nginx 注解一条条手抄进 Gateway。Ingress2Gateway 就是为这一刻准备的:它读走你现有的 Ingress 和注解,直接吐出 Gateway API 的 Gateway 与 HTTPRoute,30 秒就能看到迁移长什么样。
它到底替谁解决了什么问题 🤔
说实话,迁移最大的坑不在命令,在你脑子里那套"注解→能力"的映射。ingress-nginx 一个 host + path 的 Ingress,往往塞了 rewrite、canary、CORS、timeout 七八个注解,它们散落在 YAML 里,跟标准字段混在一起。手工搬的时候,漏一个proxy-read-timeout或rewrite-target,线上就是 502 和错路由。
我一开始也以为照着文档把每个注解抄到对应字段就行。踩过的坑是:同一能力在不同控制器下写法完全不同,nginx 的cors-allow-origin和 Traefik 的写法没有对应关系,人肉对齐必然出错,这套 nginx 注解转 Gateway 的事不该靠手感。
Ingress2Gateway 这个 ingress-nginx 迁移工具用两层结构解决它。Providers 负责"读懂"——ingress-nginx、Traefik、Kong 各有一个 provider,把五花八门的注解归一化成中间表示(IR);Emitters 负责"写出"——standard只吐核心 Gateway API,envoy-gateway会额外补上实现相关的资源。你不用关心某个注解落在哪一层,provider 和 emitter 各管一段,这也正是它比手写脚本稳的原因。
Ingress2Gateway 迁移架构:Providers 与 Emitters 分层示意
先跑通,再深入
别研究参数,先让它跑。装好之后对着一个命名空间预览,转换结果直接打到终端:
brew install ingress2gateway ingress2gateway print --providers=ingress-nginx --emitter=envoy-gateway -n prod看终端滚出来的 Gateway 和 HTTPRoute 就懂七成了。想不碰集群、只验证本地文件,把-n prod换成--input-file ingress.yaml即可,适合在正式动集群前先离线跑一遍。
三种典型迁移场景
场景一:路径重写 rewrite-target → URLRewrite
你原来写nginx.ingress.kubernetes.io/rewrite-target: /,配上带捕获组的路径。它帮你变成 HTTPRoute 上的 URLRewrite 过滤器,前缀重写映射成ReplacePrefixMatch:
annotations: nginx.ingress.kubernetes.io/rewrite-target: / # 转换后 filters: - type: URLRewrite urlRewrite: { path: { type: ReplacePrefixMatch, replacePrefixMatch: / } }带$1、$2这种捕获组的复杂重写,标准 Gateway API 表达不了,得靠 envoy-gateway 的 HTTPRouteFilter 用正则替换兜底;而且 URLRewrite 属实验特性,要加--allow-experimental-gw-api,漏了它过滤就静默失效。
场景二:CORS + 金丝雀权重 ⚖️
一条规则里同时压了 CORS 和 canary。CORS 那五个注解会被 envoy-gateway 拆成一个 HTTPRouteFilter 的cors段;canary-weight则直接落到 backendRefs 的weight上,20/80 按比例分流。
# CORS 注解 → envoy-gateway HTTPRouteFilter spec: cors: { allowOrigins: [https://app.example.com], maxAge: 86400 } # canary-weight: 20 → backendRefs 的 weight这里最省心的是权重换算:你写 20,它就给你 canary 20、主干 80,不会让你自己补那个 80。
场景三:跨命名空间 parentRef
HTTPRoute 在业务命名空间,Gateway 却放在独立的 gateway-system。跨命名空间引用 backend 或 parentRef,Gateway API 默认是拒绝的。Ingress2Gateway 会顺手生成 ReferenceGrant 把这条引用放行,省得你一个个补:
# 自动生成的放行 kind: ReferenceGrant spec: from: { kind: HTTPRoute, namespace: prod } to: [ { kind: Service, name: api } ]动手前确认这 3 件事
注解支持边界。不是所有注解都有映射,Lua 脚本、复杂限流这类没有对应 Gateway 能力。会坑你的是:provider 转不了时会打 warning,你只 apply 不读报告,就等于把这部分配置静默丢了。
命名空间策略。Gateway API 的跨命名空间引用比 Ingress 严格。会坑你的是:你以为 backendRef 能直接跨 ns 指过去,结果缺 ReferenceGrant,路由建好了却连不上后端。
TLS 配置差异。Ingress 把证书写在spec.tls,Gateway API 挪到 Gateway 的 listener 上。会坑你的是:只迁移了路由没迁移 Gateway,证书就没人加载,443 直接 404。
| 注解能力 | 支持度 |
|---|---|
| CORS / 重定向 / 超时 | 完全支持 |
| 正则路径 / 后端 TLS | 部分支持 |
| Lua 脚本 / 高级限流 | 需手动迁移 |
验证与回退 ✅
kubectl apply -f out.yaml kubectl get gateways,httproutes -n prod curl -kI https://example.com/healthGateway API 迁移验证与回退流程示意
回退思路一句话:先备份 Ingress,两套控制器并行跑,再用 DNS 权重把流量一点点切到 Envoy Gateway,切不动随时回 DNS,不用动集群。
延伸阅读
想深挖转换逻辑,看 Emitters 源码 里 envoy-gateway 怎么补 CORS 和正则重写;provider 侧看 ingress-nginx provider 各注解怎么归一化。整体设计动机和 Envoy Gateway 配置转换的输出边界,docs 里的 emitters.md 写得很清楚。
【免费下载链接】ingress2gatewayConvert Ingress resources to Gateway API resources项目地址: https://gitcode.com/gh_mirrors/in/ingress2gateway
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考