元鉴
返回中文阅读流

Kubernetes Blog

发布 Ingress2Gateway 1.0:通往 Gateway API 的迁移路径

随着 Ingress-NGINX 计划于 2026 年 3 月退役,Kubernetes 网络正迎来转折点。

中文内容

已翻译official company source英文原文2026-03-20

发布 Ingress2Gateway 1.0:通往 Gateway API 的迁移路径

By Beka Modebadze (Google), Steven Jin (Microsoft) | Friday, March 20, 2026

随着 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
  • ← 上一篇
  • 下一篇 →

原文标题

Announcing Ingress2Gateway 1.0: Your Path to Gateway API