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进行迁移示例
- 登录节点,确保当前节点可以使用kubectl获取集群内的Ingress资源。
kubectl get ingress
- 查看集群内安装的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
- 在节点上安装ingress2gateway工具(下载地址),操作步骤详情请参见Installation。
- 使用ingress2gateway将NGINX Ingress转换成Gateway的YAML并保存。 执行以下命令,其中{ingressclass名称}为步骤2中查询到的ingressclass名称,选择其中一个控制器下的Ingress进行转换。
./ingress2gateway print --providers=ingress-nginx --ingress-nginx-ingress-class={ingressclass名称} > nginx.yamlnginx.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密钥名称等于空,需要手动修改。
- 创建Gateway、HTTPRoute资源。
kubectl apply -f nginx.yaml
回显如下:
gateway.gateway.networking.k8s.io/nginx created httproute.gateway.networking.k8s.io/test2-all-hosts created
- 访问Envoy Gateway。
- 查询Envoy Gateway的ELB地址。
kubectl get gateway nginx -o jsonpath='{.status.addresses}' - 在同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
- 查询Envoy Gateway的ELB地址。
- 流量迁移
请不要随意修改、删除线上正在使用的NGINX Ingress配置,在充分验证完新建的Envoy Gateway功能正常的情况后再处理。
- 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标:
- 业务成功率
- 接口延迟(P99 / P95)
- 错误日志(4xx / 5xx)
- ELB后端健康状态
- 逐步放大流量
- 将流量比例提升至:10% → 30% → 50%
- 提升后继续观察相关指标,确认无异常后再逐步放大流量,直至全量切换。
- 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标:
使用ingress2eg进行迁移示例
- 登录节点,确保当前节点可以使用kubectl获取集群内的Ingress资源。
kubectl get ingress
- 查看集群内安装的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
- 安装ingress2eg工具(下载地址),操作步骤详情请参见Installation。
- 查看集群中需要迁移的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: "" - 执行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 - 保存输出,并将所有资源应用到集群中。
ingress2eg print --namespace default > gateway-resources.yaml kubectl apply -f gateway-resources.yaml
- 访问Envoy Gateway。
- 查询Envoy Gateway的ELB地址。
kubectl get gateway nginx -o jsonpath='{.status.addresses}' - 在同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
- 查询Envoy Gateway的ELB地址。
- 流量迁移
请不要随意修改、删除线上正在使用的NGINX Ingress配置,在充分验证完新建的Envoy Gateway功能正常的情况后再处理。
- 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标:
- 业务成功率
- 接口延迟(P99 / P95)
- 错误日志(4xx / 5xx)
- ELB后端健康状态
- 逐步放大流量
- 将流量比例提升至:10% → 30% → 50%
- 提升后继续观察相关指标,确认无异常后再逐步放大流量,直至全量切换。
- 修改域名指向,将部分流量(1% ~ 5%)切换到Gateway的新IP地址,观察服务线上情况。包括但不限于以下指标: