中文内容
发布 Ingress2Gateway 1.0:通往 Gateway API 的迁移路径
随着 Ingress-NGINX 计划于 2026 年 3 月退役,Kubernetes 网络格局正处于转折点。对大多数组织而言,问题不是是否要迁移到 Gateway API,而是如何安全地完成迁移。
从 Ingress 迁移到 Gateway API 是 API 设计上的根本性转变。Gateway API 提供模块化、可扩展的 API,并对 Kubernetes 原生 RBAC 提供强有力支持。相反,Ingress API 较为简单,Ingress-NGINX 等实现则通过较为专门的注解、ConfigMap 和 CRD 来扩展该 API。脱离 Ingress-NGINX 等 Ingress 控制器进行迁移,意味着需要完成一项艰巨任务:捕捉 Ingress 控制器的所有细微行为,并将这些行为映射到 Gateway API。
Ingress2Gateway 是一款助手,可帮助团队有信心地从 Ingress 迁移到 Gateway API。它会将 Ingress 资源/清单以及特定实现的注解转换为 Gateway API,同时对无法转换的配置发出警告并提供建议。
今天,SIG Network 很高兴宣布发布 Ingress2Gateway 1.0。这个里程碑代表着一款稳定、经过测试的迁移助手,面向准备将其网络栈现代化的团队。
正文:Ingress2Gateway 1.0
Ingress-NGINX 注解支持
1.0 版本的主要改进是更全面的 Ingress-NGINX 支持。在 1.0 版本之前,Ingress2Gateway 仅支持三种 Ingress-NGINX 注解。对于 1.0 版本,Ingress2Gateway 支持 30 多种常见注解(CORS、后端 TLS、正则匹配、路径重写等)。
全面的集成测试
每个受支持的 Ingress-NGINX 注解,以及常见注解的代表性组合,都有控制器级集成测试作为支撑,用于验证 Ingress-NGINX 配置与生成的 Gateway API 在行为上的等价性。这些测试会在实时集群中运行真实控制器,并比较运行时行为(路由、重定向、重写等),而不仅仅是 YAML 结构。
这些测试:
- 启动一个 Ingress-NGINX 控制器
- 启动多个 Gateway API 控制器
- 应用包含特定实现配置的 Ingress 资源
- 使用 ingress2gateway 将 Ingress 资源转换为 Gateway API,并应用生成的清单
- 验证 Gateway API 控制器和 Ingress 控制器表现出等价行为。
全面的测试套件不仅能在开发过程中发现错误,还能确保转换的正确性,尤其是在存在令人意外的边缘情况和非预期默认值时,从而避免在生产环境中才发现问题。
通知与错误处理
迁移并不是“一键式”事务。揭示细微差异和不可转换行为,与转换受支持配置同样重要。1.0 版本整理了通知的格式和内容,使缺失内容以及修复方式更加清晰。
使用 Ingress2Gateway
Ingress2Gateway 是迁移助手,而不是一次性替代工具。其目标是
- 迁移受支持的 Ingress 配置和行为
- 识别不受支持的配置并建议替代方案
- 重新评估并可能丢弃不理想的配置
本节其余部分将说明如何安全迁移以下 Ingress-NGINX 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "1G"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Request-Id: $req_id";
name: my-ingress
namespace: my-ns
spec:
ingressClassName: nginx
rules:
- host: my-host.example.com
http:
paths:
- backend:
service:
name: website-service
port:
number: 80
path: /users/(\d+)
pathType: ImplementationSpecific
tls:
- hosts:
- my-host.example.com
secretName: my-secret
1. 安装 Ingress2Gateway
如果你已设置 Go 环境,可以使用以下方式安装 Ingress2Gateway
go install github.com/kubernetes-sigs/ingress2gateway@v1.0.0
否则,
brew install ingress2gateway
你也可以从 GitHub 下载二进制文件或从源代码构建。
2. 运行 Ingress2Gateway
你可以向 Ingress2Gateway 传入 Ingress 清单,也可以让该工具直接从集群读取。
# Pass it files
ingress2gateway print --input-file my-manifest.yaml,my-other-manifest.yaml --providers=ingress-nginx > gwapi.yaml
# Use a namespace in your cluster
ingress2gateway print --namespace my-api --providers=ingress-nginx > gwapi.yaml
# Or your whole cluster
ingress2gateway print --providers=ingress-nginx --all-namespaces > gwapi.yaml
注意:
You can also pass--emitter <agentgateway|envoy-gateway|kgateway> to output implementation-specific extensions.3. 审查输出
这是最关键的一步。上一节中的命令会将 Gateway API 清单输出到 gwapi.yaml,同时也会发出警告,说明哪些内容没有被精确转换以及哪些内容需要手动审查。
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: nginx
namespace: my-ns
spec:
gatewayClassName: nginx
listeners:
- hostname: my-host.example.com
name: my-host-example-com-http
port: 80
protocol: HTTP
- hostname: my-host.example.com
name: my-host-example-com-https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: my-secret
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: my-ingress-my-host-example-com
namespace: my-ns
spec:
hostnames:
- my-host.example.com
parentRefs:
- name: nginx
port: 443
rules:
- backendRefs:
- name: website-service
port: 80
filters:
- cors:
allowCredentials: true
allowHeaders:
- DNT
- Keep-Alive
- User-Agent
- X-Requested-With
- If-Modified-Since
- Cache-Control
- Content-Type
- Range
- Authorization
allowMethods:
- GET
- PUT
- POST
- DELETE
- PATCH
- OPTIONS
allowOrigins:
- '*'
maxAge: 1728000
type: CORS
matches:
- path:
type: RegularExpression
value: (?i)/users/(\d+).*
name: rule-0
timeouts:
request: 10s
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: my-ingress-my-host-example-com-ssl-redirect
namespace: my-ns
spec:
hostnames:
- my-host.example.com
parentRefs:
- name: nginx
port: 80
rules:
- filters:
- requestRedirect:
scheme: https
statusCode: 308
type: RequestRedirect
Ingress2Gateway 成功地将一些注解转换为其 Gateway API 等价形式。例如,nginx.ingress.kubernetes.io/enable-cors 注解被转换为 CORS 过滤器。但仔细查看后会发现,nginx.ingress.kubernetes.io/proxy-{read,send}-timeout 和 nginx.ingress.kubernetes.io/proxy-body-size 注解并不能完全映射。日志显示了这些省略的原因以及转换背后的理由。
┌─ WARN ────────────────────────────────────────
│ Unsupported annotation nginx.ingress.kubernetes.io/configuration-snippet
│ source: INGRESS-NGINX
│ object: Ingress: my-ns/my-ingress
└─
┌─ INFO ────────────────────────────────────────
│ Using case-insensitive regex path matches. You may want to change this.
│ source: INGRESS-NGINX
│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN ────────────────────────────────────────
│ ingress-nginx only supports TCP-level timeouts; i2gw has made a best-effort translation to Gateway API timeouts.request. Please verify that this meets your needs. See documentation: https://gateway-api.sigs.k8s.io/guides/http-timeouts/
│ source: INGRESS-NGINX
│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN ────────────────────────────────────────
│ Failed to apply my-ns.my-ingress.metadata.annotations."nginx.ingress.kubernetes.io/proxy-body-size" from my-ns/my-ingress: Most Gateway API implementations have reasonable body size and buffering defaults
│ source: STANDARD_EMITTER
│ object: HTTPRoute: my-ns/my-ingress-my-host-example-com
└─
┌─ WARN ────────────────────────────────────────
│ Gateway API does not support configuring URL normalization (RFC 3986, Section 6). Please check if this matters for your use case and consult implementation-specific details.
│ source: STANDARD_EMITTER
└─
有一条警告指出,Ingress2Gateway 不支持 nginx.ingress.kubernetes.io/configuration-snippet 注解。你需要查看你的 Gateway API 实现文档,确认是否有办法实现等价行为。
该工具还通知我们,Ingress-NGINX 正则匹配是不区分大小写的前缀匹配,这就是为什么会出现 (?i)/users/(\d+).* 这样的匹配模式。大多数组织会希望通过从路径模式中移除开头的 (?i) 和结尾的 .*,将此行为改为区分大小写的精确匹配。
Ingress2Gateway 尽力将 nginx.ingress.kubernetes.io/proxy-{send,read}-timeout 注解转换为 HTTP 路由中的 10 秒请求超时。如果对该服务的请求应当短得多,例如 3 秒,你可以在 Gateway API 清单中进行相应更改。
此外,nginx.ingress.kubernetes.io/proxy-body-size 没有 Gateway API 等价项,因此未被转换。不过,大多数 Gateway API 实现对最大请求体大小和缓冲都有合理默认值,因此在实践中这可能不是问题。此外,某些发射器可能通过特定实现的扩展为该注解提供支持。例如,在先前的 ingress2gateway print 命令中添加 --emitter agentgateway、--emitter envoy-gateway 或 --emitter kgateway 标志,会使生成的 Gateway API 清单包含额外的特定实现配置,尝试捕捉请求体大小配置。
我们还看到一条关于 URL 规范化的警告。Agentgateway、Envoy Gateway、Kgateway 和 Istio 等 Gateway API 实现都在一定程度上进行 URL 规范化,但不同实现之间行为各异,并且无法通过标准 Gateway API 配置。你应检查并测试你的 Gateway API 实现的 URL 规范化行为,以确保其与你的用例兼容。
为匹配 Ingress-NGINX 的默认行为,Ingress2Gateway 还在 80 端口添加了一个监听器,并添加了一个 HTTP Request 重定向过滤器,用于将 HTTP 流量重定向到 HTTPS。你可能根本不想提供 HTTP 流量,并可移除 80 端口上的监听器以及相应的 HTTPRoute。
注意:
Always thoroughly review the generated output and logs.手动应用这些更改后,Gateway API 清单可能如下所示。
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: nginx
namespace: my-ns
spec:
gatewayClassName: nginx
listeners:
- hostname: my-host.example.com
name: my-host-example-com-https
port: 443
protocol: HTTPS
tls:
certificateRefs:
- group: ""
kind: Secret
name: my-secret
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
gateway.networking.k8s.io/generator: ingress2gateway-dev
name: my-ingress-my-host-example-com
namespace: my-ns
spec:
hostnames:
- my-host.example.com
parentRefs:
- name: nginx
port: 443
rules:
- backendRefs:
- name: website-service
port: 80
filters:
- cors:
allowCredentials: true
allowHeaders:
- DNT
...
allowMethods:
- GET
...
allowOrigins:
- '*'
maxAge: 1728000
type: CORS
matches:
- path:
type: RegularExpression
value: /users/(\d+)
name: rule-0
timeouts:
request: 3s
4. 验证
现在你已经有了 Gateway API 清单,应在开发集群中对其进行充分测试。在这种情况下,你至少应再次确认你的 Gateway API 实现的最大请求体大小默认值是否适合你,并验证三秒超时是否足够。
在开发集群中验证行为后,将你的 Gateway API 配置与现有 Ingress 并行部署。我们强烈建议随后使用加权 DNS、云负载均衡器或平台的流量拆分功能逐步迁移流量。这样,如果有任何配置错误通过了测试,你可以快速恢复。
最后,当你已将所有流量迁移到 Gateway API 控制器后,删除你的 Ingress 资源并卸载你的 Ingress 控制器。
结论
Ingress2Gateway 1.0 版本只是一个开始,我们希望你使用 Ingress2Gateway 安全迁移到 Gateway API。随着 2026 年 3 月 Ingress-NGINX 退役日期临近,我们邀请社区帮助我们提高配置覆盖率、扩展测试并改进用户体验。
关于 Gateway API 的资源
Gateway API 的范围可能令人望而生畏。以下资源可帮助你使用 Gateway API:
- 监听器集合允许应用开发者管理网关监听器。
- gwctl 可让你全面查看 Gateway 资源,例如挂载关系和 linter 错误。
- Gateway API Slack:Kubernetes Slack 上的 #sig-network-gateway-api
- Ingress2Gateway Slack:Kubernetes Slack 上的 #sig-network-ingress2gateway
- 正文:GitHub:kubernetes-sigs/ingress2gateway
- ← 上一篇
- 下一篇 →