更新时间:2026-06-05 GMT+08:00
分享

NGINX Ingress迁移至Envoy Gateway

当前许多企业使用NGINX Ingress作为Kubernetes集群的入口网关来管理外部流量,而NGINX Ingress开源项目已于2026年3月后停止维护更新,并推荐使用Gateway的方式作为替代方案。建议您从NGINX Ingress迁移到Envoy Gateway,该过程涉及将现有Ingress资源转换为与Envoy Gateway兼容的资源。本文将介绍如何通过迁移工具将NGINX ingress迁移到Envoy Gateway,降低迁移难度。

Envoy Gateway社区提供了两个官方工具来辅助迁移(参见Migrating from Ingress Resources):

  • ingress2gateway(基础转换):官方的转换工具,但仅支持转换成Gateway和HTTPRoute资源。
  • ingress2eg(增强版):一个非官方的概念验证工具,从ingress2gateway分支衍生而来。ingress2eg不仅生成Gateway API资源(Gateway、HTTPRoute),还可以生成Envoy Gateway专属的CRD(BackendTrafficPolicy、SecurityPolicy 等)。

迁移工具当前只支持部分主要功能迁移,请关注工具产生的告警。且生成Gateway API的YAML后,建议务必经过人工审核并在测试环境验证后再进行流量迁移。

前提条件

  • 集群中已部署NGINX Ingress控制器插件,并且插件状态为运行中。
  • 集群中已部署Envoy Gateway插件,并且插件状态为运行中。
  • 执行迁移的节点上部署了kubectl工具并已连接集群。

注意事项

  • 本文的迁移是指创建出相似配置的Gateway和HTTPRoute资源,Gateway和NGINX Ingress功能差异详见Envoy Gateway与NGINX Ingress功能对比
  • 迁移过程中请不要修改NGINX Ingress配置。
  • 迁移完成后,请不要随意修改、删除线上正在使用的NGINX Ingress配置,在充分验证完新建的Envoy Gateway功能正常的情况后再进行修改。
  • 迁移的Envoy Gateway会使用插件安装时的配置自动创建ELB。
  • NGINX Ingress配置的secret为nginx默认密钥时,转换的gateway密钥名称等于空,需要手动修改。

支持迁移的功能

  • ingress2gateway支持迁移的功能

    功能类别

    NGINX Ingress 注解

    Gateway API 资源

    说明

    灰度发布

    canary

    canary-weight

    canary-weight-total

    canary-by-header

    canary-by-header-value

    HTTPRoute(权重/匹配规则)

    基于权重和Header的流量拆分

    重定向 - 临时

    temporal-redirect

    temporal-redirect-code

    HTTPRoute(RequestRedirect过滤器,302)

    临时URL重定向,可自定义状态码(301/302)

    重定向 - 永久

    permanent-redirect

    permanent-redirect-code

    HTTPRoute(RequestRedirect过滤器,301)

    永久URL重定向,可自定义状态码(301/302)

    重定向 - WWW

    from-to-www-redirect

    HTTPRoute(RequestRedirect过滤器,301)

    www到非www域名重定向

    请求头修改

    upstream-vhost

    connection-proxy-header

    HTTPRoute(RequestHeaderModifier过滤器)

    请求头操作(设置Host、Connection)

    超时

    proxy-connect-timeout

    proxy-send-timeout

    proxy-read-timeout

    HTTPRoute(Timeouts.Request)

    TCP级超时转换为HTTP请求超时

    CORS 跨域

    enable-cors

    cors-allow-origin

    cors-allow-methods

    cors-allow-headers

    cors-allow-credentials

    cors-expose-headers

    cors-max-age

    HTTPRoute(CORS配置)

    跨域资源共享策略

  • ingress2eg支持迁移的功能

    请参见官方说明

使用ingress2gateway进行迁移示例

  1. 登录节点,确保当前节点可以使用kubectl获取集群内的Ingress资源。

    kubectl get ingress

  2. 查看集群内安装的NGINX Ingress控制器插件的ingressclass名称。

    kubectl get ingressclass

    回显如下:

    NAME     CONTROLLER                    PARAMETERS   AGE
    nginx    k8s.io/ingress-nginx          <none>       29h
    nginx2   k8s.io/ingress-nginx-nginx2   <none>       27s

  3. 在节点上安装ingress2gateway工具(下载地址),操作步骤详情请参见Installation
  4. 使用ingress2gateway将NGINX Ingress转换成Gateway的YAML并保存。

    执行以下命令,其中{ingressclass名称}为步骤2中查询到的ingressclass名称,选择其中一个控制器下的Ingress进行转换。
    ./ingress2gateway print --providers=ingress-nginx  --ingress-nginx-ingress-class={ingressclass名称} > nginx.yaml

    nginx.yaml文件内容如下:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2gateway-1.1.0
      name: nginx
      namespace: default
    spec:
      gatewayClassName: nginx               #修改成集群内已存在的GatewayClass名称,比如envoy-gateway
      listeners:
      - hostname: www.example.com
        name: www-example-com-http
        port: 80
        protocol: HTTP
      - hostname: www.example.com
        name: www-example-com-https
        port: 443
        protocol: HTTPS
        tls:
          certificateRefs:
          - group: ""
            kind: Secret
            name: ""                                      #修改成secret名称
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2gateway-1.1.0
      name: test2-www-example-com
      namespace: default
    spec:
      hostnames:
      - www.example.com
      parentRefs:
      - name: nginx
        port: 443
        sectionName: www-example-com-https
      rules:
      - backendRefs:
        - name: nginx
          port: 8080
        matches:
        - path:
            type: PathPrefix
            value: /a
      - backendRefs:
        - name: nginx-2
          port: 9001
        matches:
        - path:
            type: PathPrefix
            value: /
    status:
      parents: []
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2gateway-1.1.0
      name: test2-www-example-com-http
      namespace: default
    spec:
      hostnames:
      - www.example.com
      parentRefs:
      - name: nginx
        port: 80
      rules:
      - filters:
        - requestRedirect:
            scheme: https
            statusCode: 308      #当前Gateway仅支持301和302,需要手动修改
          type: RequestRedirect
        matches:
        - path:
            type: PathPrefix
            value: /a
      - filters:
        - requestRedirect:
            scheme: https
            statusCode: 308            #当前Gateway仅支持301和302,需要手动修改
          type: RequestRedirect
        matches:
        - path:
            type: PathPrefix
            value: /
    status:
      parents: null
    • 当前httproute.spec.rules.filters.requestRedirect.statusCode参数仅支持301和302,需要手动修改配置后再创建。
    • NGINX Ingress配置的secret为nginx默认密钥时,转换的gateway密钥名称等于空,需要手动修改。

  5. 创建Gateway、HTTPRoute资源。

    kubectl apply -f nginx.yaml

    回显如下:

    gateway.gateway.networking.k8s.io/nginx created
    httproute.gateway.networking.k8s.io/test2-all-hosts created

  6. 访问Envoy Gateway。

    1. 查询Envoy Gateway的ELB地址。
      kubectl get gateway nginx -o jsonpath='{.status.addresses}'
    2. 在同VPC内的节点上,访问ELB私有地址。
      curl -ik --resolve www.example.com:443:xx.xx.xx.xx https://www.example.com

      回显如下:

      HTTP/2 200 OK
      server: nginx/1.19.3
      date: Sat, 16 May 2026 09:04:17 GMT
      content-type: text/html
      content-length: 612
      last-modified: Tue, 29 Sep 2020 14:12:31 GMT
      etag: "5f7340cf-264"
      accept-ranges: bytes

  7. 流量迁移

    请不要随意修改、删除线上正在使用的NGINX Ingress配置,在充分验证完新建的Envoy Gateway功能正常的情况后再处理。

    1. 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标:
      • 业务成功率
      • 接口延迟(P99 / P95)
      • 错误日志(4xx / 5xx)
      • ELB后端健康状态
    2. 逐步放大流量
      • 将流量比例提升至:10% → 30% → 50%
      • 提升后继续观察相关指标,确认无异常后再逐步放大流量,直至全量切换。

使用ingress2eg进行迁移示例

  1. 登录节点,确保当前节点可以使用kubectl获取集群内的Ingress资源。

    kubectl get ingress

  2. 查看集群内安装的NGINX Ingress控制器插件的ingressclass名称。

    kubectl get ingressclass

    回显如下:

    NAME     CONTROLLER                    PARAMETERS   AGE
    nginx    k8s.io/ingress-nginx          <none>       29h
    nginx2   k8s.io/ingress-nginx-nginx2   <none>       27s

  3. 安装ingress2eg工具(下载地址),操作步骤详情请参见Installation
  4. 查看集群中需要迁移的Ingress。

    示例如下:
    apiVersion: v1
    items:
    - apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        creationTimestamp: "2026-05-14T06:45:11Z"
        generation: 3
        name: test2
        namespace: default
        resourceVersion: "2749120"
        uid: 36f54e81-e9ca-4f8b-a303-723ad36022bc
      spec:
        ingressClassName: nginx
        rules:
        - host: www.example.com
          http:
            paths:
            - backend:
                service:
                  name: nginx
                  port:
                    number: 8080
              path: /a
              pathType: Prefix
              property:
                ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
        tls:
        - {}
      status:
        loadBalancer:
          ingress:
          - ip: 172.16.1.26
    - apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        annotations:
          nginx.ingress.kubernetes.io/limit-rps: "10"
        creationTimestamp: "2026-05-13T07:58:56Z"
        generation: 6
        name: www
        namespace: default
        resourceVersion: "2770503"
        uid: 9db1744f-ff72-4b43-9c6d-efefeb6d4310
      spec:
        ingressClassName: nginx
        rules:
        - host: www.example.com
          http:
            paths:
            - backend:
                service:
                  name: nginx-2
                  port:
                    number: 9001
              path: /
              pathType: ImplementationSpecific
              property:
                ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH
      status:
        loadBalancer:
          ingress:
          - ip: 172.16.1.26
    kind: List
    metadata:
      resourceVersion: ""

  5. 执行ingress2eg命令。

    # Convert from cluster resources in a specific namespace
    ./ingress2eg print --namespace default  --ingress-nginx-ingress-class={ingressclass名称}

    对于上述资源,预期输出内容如下:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2eg-dev
      name: nginx
      namespace: default
    spec:
      gatewayClassName: eg                #修改成集群内已存在的GatewayClass名称,比如envoy-gateway
      listeners:
      - hostname: www.example.com
        name: www-example-com-http
        port: 80
        protocol: HTTP
      - hostname: www.example.com
        name: www-example-com-https
        port: 443
        protocol: HTTPS
        tls:
          certificateRefs:
          - group: ""
            kind: Secret
            name: ""
    status: {}
    ---
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2eg-dev
      name: test2-www-example-com       #名称
      namespace: default
    spec:
      hostnames:
      - www.example.com
      parentRefs:
      - name: nginx
      rules:
      - backendRefs:
        - name: nginx
          port: 8080
        matches:
        - path:
            type: PathPrefix
            value: /a
        name: rule-0-prefix-a
      - backendRefs:
        - name: nginx-2
          port: 9001
        matches:
        - path:
            type: PathPrefix
            value: /
        name: rule-1-impl-specific
    status:
      parents: []
    ---
    apiVersion: gateway.envoyproxy.io/v1alpha1
    kind: BackendTrafficPolicy
    metadata:
      annotations:
        gateway.networking.k8s.io/generator: ingress2eg-dev
      name: test2-www-example-com-1
      namespace: default
    spec:
      rateLimit:
        local:
          rules:
          - clientSelectors:
            - sourceCIDR:
                type: Distinct
                value: 0.0.0.0/0
            limit:
              requests: 10
              unit: Second
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: test2-www-example-com
        sectionName: rule-1-impl-specific
    status:
      ancestors: null

  6. 保存输出,并将所有资源应用到集群中。

    ingress2eg print --namespace default > gateway-resources.yaml
    kubectl apply -f gateway-resources.yaml

  7. 访问Envoy Gateway。

    1. 查询Envoy Gateway的ELB地址。
      kubectl get gateway nginx -o jsonpath='{.status.addresses}'
    2. 在同VPC内的节点上,访问ELB私有地址。
      curl -ik --resolve www.example.com:443:xx.xx.xx.xx https://www.example.com

      回显如下:

      HTTP/2 200 OK
      server: nginx/1.19.3
      date: Sat, 16 May 2026 09:04:17 GMT
      content-type: text/html
      content-length: 612
      last-modified: Tue, 29 Sep 2020 14:12:31 GMT
      etag: "5f7340cf-264"
      accept-ranges: bytes

  8. 流量迁移

    请不要随意修改、删除线上正在使用的NGINX Ingress配置,在充分验证完新建的Envoy Gateway功能正常的情况后再处理。

    1. 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标:
      • 业务成功率
      • 接口延迟(P99 / P95)
      • 错误日志(4xx / 5xx)
      • ELB后端健康状态
    2. 逐步放大流量
      • 将流量比例提升至:10% → 30% → 50%
      • 提升后继续观察相关指标,确认无异常后再逐步放大流量,直至全量切换。

相关文档