从 Ingress-Nginx 迁移到 Envoy Gateway 指南

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

查看本文大纲

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

为什么要迁移?

Kubernetes 中的 Ingress 控制器是网络流量管理的基础组件,许多团队在初期会选择使用 ingress-nginx,因为它易于部署且社区广泛支持。然而,随着生产环境需求的提升,传统 Ingress API 与 nginx 控制器的局限性也日益显现,比如依赖注解的配置方式难以理解,更新配置时容易导致流量中断等问题。

更值得注意的是,近期的安全漏洞(如 CVE-2025-1974)暴露了继续依赖 ingress-nginx 所带来的安全风险。此外,维护团队已宣布,ingress-nginx 将在 18 个月后进入维护模式参考视频),这意味着现在是时候评估更现代、更具可扩展性的替代方案了。

Envoy Gateway 是一个值得关注的选择,它原生支持 Kubernetes Gateway API,具备更强的可观测性和可扩展性,能够更好地满足企业级流量管理的需求。

认识 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 社区治理。

迁移流程:从 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/23