从 Ingress-Nginx 迁移到 Envoy Gateway 指南

本博客介绍如何从 ingress-nginx 平滑迁移到基于 Gateway API 的 Envoy Gateway,包含迁移动因、Minikube 实操步骤及 ingress2gateway 工具的使用,帮助用户实现更现代、可扩展的 Ingress 管理。

版权声明
本文为 Jimmy Song 原创。转载请注明来源: https://jimmysong.io/blog/migrating-from-ingress-nginx-to-envoy-gateway/
查看本文大纲

本文旨在帮助当前依赖 ingress-nginx 的用户迁移至 Envoy Gateway 并采用 Gateway API。我们将介绍迁移的动因,提供一个基于 Minikube 的实操示例,并展示如 ingress2gateway 工具如何简化整个迁移流程。

为什么要迁移?

Ingress Controller 是每个 Kubernetes 集群中不可或缺的组件。许多用户在最初搭建集群时选择了 ingress-nginx,并在之后很少关注它的配置运行。而传统的 Ingress API 与 nginx controller 存在诸多限制:如果你曾因复杂的注解配置而感到困扰,或者遇到配置更改导致连接中断的情况,那么你可能已经意识到,是时候寻找更现代的替代方案了。

认识 Envoy Gateway 和 Gateway API

Envoy Proxy 是一个现代的、为云原生设计的代理,具备可观测性、热更新和良好的可运维性。Envoy Gateway(EG) 基于 Envoy 构建,提供了基于 Kubernetes Gateway API 的强大 Ingress 解决方案。

与传统的 Ingress API 不同,Gateway API 提供了 GatewayHTTPRouteGatewayClass 等结构化资源,支持更清晰、无注解的配置方式。EG 支持如下高级特性:

这些特性往往可以替代额外的 API Gateway 产品。Envoy Gateway 是完全开源的,并由 CNCF 社区治理。

如需企业级支持,Tetrate Enterprise Gateway for Envoy (TEG) 提供了一个可用于生产的企业级发行版。

迁移流程:从 nginx 迁移到 Envoy Gateway

在动手迁移之前,先来了解 ingress2gateway 工具的工作原理。这个 CLI 工具会扫描现有的 Kubernetes Ingress 资源(特别是为 ingress-nginx 配置的资源),并将其转换为 Gateway API 的资源,即 GatewayHTTPRoute。该工具不会生成 GatewayClass,因此用户需要提前创建好并进行引用。借助此工具,用户无需重写所有配置,就能平滑过渡至 Gateway API 和现代的 Ingress Controller(如 Envoy Gateway)。

image
ingress2gateway 工作流程

下面我们将以 macOS 上的 Minikube 为例,演示从 ingress-nginx 迁移至 Envoy Gateway 的完整过程。

步骤 1:启动 Minikube 并启用 NGINX Ingress 插件

minikube start
minikube addons enable ingress

步骤 2:部署 httpbin 服务及 Ingress 资源

kubectl apply -f - << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
spec:
  selector:
    app: httpbin
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpbin
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: httpbin.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: httpbin
            port:
              number: 80
EOF

步骤 3:通过 tunnel 启用 LoadBalancer 访问

minikube tunnel

步骤 4:测试 NGINX Ingress 是否生效

curl -H "Host: httpbin.local" http://127.0.0.1/get

步骤 5:安装 Envoy Gateway

helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.3.2 \
  -n envoy-gateway-system --create-namespace

步骤 6:创建名为 nginx 的 GatewayClass

kubectl apply -f - << EOF
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
EOF

步骤 7:使用 ingress2gateway 转换配置

安装工具:

go install github.com/kubernetes-sigs/ingress2gateway@latest

转换配置:

ingress2gateway print --providers ingress-nginx | kubectl apply -f -

如果 Ingress 不在 default 命名空间,需添加 --namespace 参数。

步骤 8:验证迁移是否成功

测试路由:

curl --header 'Host: httpbin.local' http://127.0.0.1/get

步骤 9:清理 NGINX Ingress(可选)

终止 tunnel 并关闭 ingress 插件:

minikube addons disable ingress

总结

通过迁移到 Envoy Gateway,你可以获得更加结构化、功能丰富的 Ingress 配置方式。这种方式由 CNCF 社区驱动,支持速率限制、身份认证和 Web 防护等开箱即用的功能,且标准一致、可移植性强。

延伸阅读

最后更新于 2025/04/18