从Ingress Nginx迁移到Kubernetes Gateway API:下一代云原生网关实战指南
1. 项目概述:从 Ingress Nginx 到 Gateway API 的必然演进
最近在云原生社区里,一个消息引发了不小的讨论:Ingress Nginx 项目即将进入维护模式,不再增加新功能。这对于大量依赖它作为 Kubernetes 集群入口网关的团队来说,无疑是一个需要认真对待的信号。我自己的生产环境里也跑着不少 Ingress Nginx 的实例,听到这个消息后,第一反应不是焦虑,而是觉得这是一个契机,一个推动技术栈向更标准、更强大方向演进的契机。这个契机,就是 Kubernetes Gateway API。
简单来说,这个项目就是教你如何从熟悉的 Ingress Nginx 平稳过渡到代表未来的 Gateway API,并利用其构建下一代云原生路由体系。它解决了什么问题?最直接的,是解决了 Ingress 资源模型表达能力不足、厂商实现碎片化以及多租户支持薄弱的核心痛点。举个例子,在 Ingress 时代,如果你想做一个基于请求头X-User-Type: vip的灰度发布,或者实现精细化的流量切分和镜像,原生的 Ingress 规范要么不支持,要么需要借助各种 Annotation(注解)来实现,而这些注解在不同 Ingress Controller(如 Nginx, Contour, Traefik)之间完全不通用,换一个就得重写配置,维护成本极高。
Gateway API 就是为了终结这种混乱而生的。它是一套由 Kubernetes SIG-Network 社区主导设计的、表达力更强的官方标准 API。它不再是一个“万能”的 Ingress 资源,而是拆解成了GatewayClass,Gateway,HTTPRoute等一组资源,各司其职,清晰定义了基础设施提供商、集群管理员、应用开发者的职责边界。这不仅仅是 API 的升级,更是运维模型和权限模型的升级。
那么,这个项目适合谁?如果你是正在使用 Ingress Nginx 的运维工程师或平台开发者,担心未来的技术债务,那么你需要了解如何迁移。如果你是刚开始设计 Kubernetes 入口方案的新团队,那么直接拥抱 Gateway API 无疑是更前瞻的选择。即便你只是对云原生网络感兴趣,理解 Gateway API 的设计哲学,也能让你对 Kubernetes 的服务网络有更深刻的认识。接下来,我将手把手带你从概念到实操,完成这次关键的架构升级。
2. 核心架构解析:为什么 Gateway API 是“下一代”
要理解为什么迁移是值得的,我们必须先抛开具体的配置语法,深入看看 Gateway API 在架构设计上到底做了哪些革新。这不仅仅是换了个 YAML 文件格式那么简单,而是一次对 Kubernetes 入口流量管理范式的重新定义。
2.1 角色分离与多租户支持
这是 Gateway API 最核心的进步。在传统的 Ingress 模型里,通常只有一个Ingress资源。开发者在里面定义主机名、路径规则和后端服务。但问题来了:谁来决定监听哪些端口和协议?谁来配置负载均衡器?SSL 证书由谁管理?这些职责往往模糊地混杂在一起,要么需要集群管理员介入,要么开发者通过注解拥有过大的权限,安全边界不清。
Gateway API 通过引入明确的角色,优雅地解决了这个问题:
- 基础设施提供商:他们定义
GatewayClass。这相当于一个“网关类型”的模板,声明了底层实现的种类,比如“使用 Contour 实现的网关”、“使用 Istio 实现的网关”。他们负责让这个GatewayClass在集群中可用。 - 集群管理员:他们创建
Gateway资源。这个资源代表一个具体的、部署好的网关实例。管理员在这里配置网络层的关键属性:监听哪些端口(如 80, 443)、使用什么协议(HTTP, HTTPS, TLS)、为哪些主机名提供服务(*.example.com),以及绑定 TLS 证书。Gateway引用一个GatewayClass,从而确定了具体的实现技术。通过 Kubernetes 的 RBAC,可以严格限制只有管理员能操作Gateway资源。 - 应用开发者:他们创建
HTTPRoute(或TCPRoute,GRPCRoute等)资源。这个资源才是真正定义路由规则的地方:将特定主机名下的特定路径(如/api/v1/*),转发到自己的后端 Service。开发者完全不需要关心网关监听什么端口、证书从哪里来,他们只需要将自己的HTTPRoute通过parentRefs字段关联到管理员创建好的Gateway上即可。
这种分离带来了巨大的好处:平台团队可以集中管理网络入口和安全策略(TLS),应用团队可以自助式地发布和配置自己的路由规则,互不干扰,完美契合了云原生环境下的多租户和自助服务需求。
2.2 跨实现的可移植性
Ingress 的一个主要痛点是“注解地狱”。为了实现高级功能(如超时、重试、认证),你必须使用特定 Ingress Controller 的注解,例如nginx.ingress.kubernetes.io/proxy-connect-timeout: "30s"。一旦你想从 Nginx Ingress Controller 切换到 Traefik,所有这些配置都需要重写,迁移成本巨大。
Gateway API 将许多常见的高级功能直接设计成了 API 字段,成为了标准的一部分。例如,在HTTPRoute的规则中,你可以直接配置:
rules: - matches: - path: value: "/api" filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: "X-Env" value: "canary" backendRefs: - name: my-canary-service port: 80上面的配置表示:匹配路径/api,在转发前添加一个请求头X-Env: canary,然后转发到my-canary-service。这个RequestHeaderModifier过滤器是 Gateway API 的标准字段,任何兼容的实现(如 Envoy Gateway, Contour, Istio)都必须以相同的方式支持它。这意味着你的路由配置在不同网关实现间有了可移植性。
当然,Gateway API 也通过ExtensionRef机制允许厂商提供自定义功能,但它鼓励并将通用功能标准化,这极大地减少了供应商锁定的风险。
2.3 更丰富的路由匹配与流量管理能力
原生的 Ingress 只支持基于主机(host)和路径(path)的匹配,功能非常基础。Gateway API 的HTTPRoute则强大得多:
- 多维匹配:可以同时基于路径、请求头(Header)、查询参数(Query Params)甚至 HTTP 方法(GET, POST)进行组合匹配。这使得实现基于用户身份、设备类型或 API 版本的精细化路由成为可能。
- 流量切分:原生支持将流量按百分比分配给不同的后端服务。这是实现金丝雀发布、蓝绿部署的核心功能,无需再依赖服务网格或复杂的注解。
rules: - matches: - path: value: "/" backendRefs: - name: production-service port: 80 weight: 90 - name: canary-service port: 80 weight: 10 - 过滤器链:除了前面提到的修改头部的过滤器,还支持重定向、URL 重写、请求镜像等。特别是请求镜像,可以将一部分生产流量复制到测试环境,用于监控或压测,而对原请求不产生影响。
这些能力原本需要借助服务网格(Service Mesh)或高级的 Ingress Controller 扩展才能实现,现在在入口网关层通过标准 API 即可完成,技术栈得以简化。
注意:Gateway API 目前仍处于发展阶段,其 API 分为
Experimental(实验)、Standard(标准)和Extended(扩展)三个通道。生产环境采用时,建议重点关注已进入Standard通道的资源,如GatewayClass,Gateway,HTTPRoute。对于TCPRoute或更高级的GRPCRoute,需评估其成熟度及所用网关实现的兼容情况。
3. 实战迁移:从 Ingress Nginx 配置到 Gateway API 资源
理论讲得再多,不如动手实践。我们假设一个非常典型的 Ingress Nginx 配置场景,然后一步步将其转换为 Gateway API 的配置。这个例子涵盖了 HTTPS、多路径路由和简单的重写规则。
3.1 原始 Ingress Nginx 配置示例
假设我们有一个名为my-app的应用,它有两个服务:前端web-ui和后端api-service。我们希望通过app.example.com域名访问,其中/路径走前端,/api/路径走后端,并且需要自动将/api/前缀重写掉(即后端服务接收到的请求路径不包含/api)。同时,我们已有一个 TLS 证书。
对应的 Ingress Nginx 的 YAML 可能如下所示:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 cert-manager.io/cluster-issuer: "letsencrypt-prod" spec: tls: - hosts: - app.example.com secretName: my-app-tls rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-ui port: number: 80 - path: /api(/|$)(.*) pathType: Prefix backend: service: name: api-service port: number: 8080这个配置做了几件事:
- 通过注解
cert-manager.io/cluster-issuer自动管理 TLS 证书(假设已安装 cert-manager)。 - 定义 TLS 部分,指定域名和存储证书的 Secret。
- 定义两条路由规则:
- 路径
/转发到web-ui服务的 80 端口。 - 路径
/api(/|$)(.*)使用正则表达式匹配,并通过rewrite-target注解将捕获组$2(即/api之后的部分)重写为新的路径,然后转发到api-service的 8080 端口。
- 路径
3.2 Gateway API 资源配置详解
现在,我们将上述功能用 Gateway API 的资源来实现。我们需要创建三个资源:Gateway,HTTPRoute,并且证书管理方式也可能发生变化。
第一步:创建 Gateway 资源(由集群管理员操作)
Gateway资源定义了网关实例的“监听器”。它不关心具体的路由规则,只关心网络层面的配置。
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: prod-gateway namespace: infra-team # 通常由平台团队管理,放在独立命名空间 spec: gatewayClassName: contour # 指定使用的 GatewayClass,这里以 Contour 为例 listeners: - name: https-app protocol: HTTPS port: 443 hostname: "app.example.com" tls: mode: Terminate certificateRefs: - kind: Secret name: my-app-tls namespace: default # 证书所在的命名空间 allowedRoutes: namespaces: from: Same关键点解析:
gatewayClassName: contour:这指向一个已由基础设施团队定义好的GatewayClass,它代表了底层使用 Contour 作为数据平面。listeners:定义了一个监听器,在 443 端口上监听 HTTPS 协议,且只针对主机名app.example.com。tls.mode: Terminate:表示在此网关上终止 TLS 连接。certificateRefs:引用了一个名为my-app-tls的 Kubernetes Secret,该 Secret 应包含有效的 TLS 证书和私钥。注意:Gateway API 本身不管理证书生命周期,你仍需使用 cert-manager 等工具生成证书并创建此 Secret。cert-manager 也已支持为 Gateway API 签发证书。allowedRoutes:这是一个重要的安全边界。namespaces.from: Same表示只允许与当前Gateway资源在同一命名空间(infra-team)中的HTTPRoute绑定到此监听器。你也可以设置为All或通过selector选择特定命名空间,以实现灵活的跨命名空间路由绑定。
第二步:创建 HTTPRoute 资源(由应用开发者操作)
HTTPRoute资源定义了具体的路由规则,并绑定到上一步创建的Gateway。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: my-app-route namespace: default # 应用所在的命名空间 spec: parentRefs: - name: prod-gateway namespace: infra-team # 指定 Gateway 所在的命名空间 sectionName: https-app # 指定绑定到 Gateway 的哪个监听器 hostnames: - "app.example.com" rules: # 规则1:匹配根路径,转发到前端服务 - matches: - path: type: PathPrefix value: / backendRefs: - name: web-ui port: 80 # 规则2:匹配 /api 路径,重写后转发到后端服务 - matches: - path: type: PathPrefix value: /api filters: - type: URLRewrite urlRewrite: path: type: ReplacePrefix replacePrefixMatch: /api replacement: / backendRefs: - name: api-service port: 8080关键点解析:
parentRefs:这是将本路由规则“挂载”到网关的关键。它指明了使用哪个Gateway(prod-gateway,位于infra-team命名空间)的哪个监听器(https-app)。hostnames:进一步限定此路由规则仅对app.example.com生效。虽然Gateway监听器已经限定了主机名,但在HTTPRoute中再次声明是一个好习惯,也便于管理。rules:包含两个规则。- 第一个规则匹配路径前缀
/,直接转发到web-ui服务。 - 第二个规则匹配路径前缀
/api。这里使用了 Gateway API 标准过滤器URLRewrite。其配置是:当匹配到前缀/api时,将其替换为/。这样,到达api-service的请求路径就不再包含/api前缀了。这比 Ingress Nginx 的正则表达式重写更直观、更声明式。
- 第一个规则匹配路径前缀
3.3 迁移过程中的核心差异与注意事项
通过上面的对比,我们可以清晰地看到迁移带来的变化和需要注意的细节:
- 配置拆分与职责分离:一个
Ingress变成了一个Gateway+ 一个或多个HTTPRoute。网络配置(端口、证书)和路由配置(路径、后端)被物理分离,分别由不同角色管理。 - 注解的消亡与标准字段的崛起:
nginx.ingress.kubernetes.io/rewrite-target这种厂商特定的注解,被替换成了标准的filters字段下的URLRewrite过滤器。这大大提升了配置的可移植性。 - 命名空间隔离与安全:Gateway API 显式地支持跨命名空间的路由绑定,并通过
allowedRoutes进行控制。这为大型集群的多团队协作提供了安全的模型。在 Ingress 中,虽然也可以通过 RBAC 控制,但模型上不如 Gateway API 清晰。 - 证书管理:两者都需要 Secret 存储证书。区别在于,Gateway API 的
Gateway资源显式地引用这个 Secret。cert-manager 等工具对两者的支持都在不断成熟中。 - 路径匹配语法:Gateway API 的路径匹配类型(
Exact,PathPrefix,RegularExpression)更规范。它不再直接使用 Nginx 风格的正则,而是通过type: RegularExpression来声明,语义更清晰。
实操心得:在迁移初期,建议在测试环境并行运行 Ingress Nginx 和新的 Gateway API 网关(如 Envoy Gateway)。可以先将一部分非核心域名的流量切换到新网关,通过对比访问日志和监控指标,验证路由规则和流量行为是否完全一致。特别注意重写(Rewrite)、重定向(Redirect)和超时(Timeout)等行为的差异,这些往往是配置不一致导致问题的高发区。
4. 环境搭建与网关实现选型
了解了如何编写配置后,我们需要一个实际的 Kubernetes 环境和一个实现了 Gateway API 的网关控制器来运行它。目前社区有多种实现,我们需要根据自身情况做出选择。
4.1 主流 Gateway API 实现对比
选择哪个实现,取决于你现有的技术栈、对功能的需求以及对复杂度的容忍度。
| 实现方案 | 核心数据平面 | 特点与优势 | 适用场景 |
|---|---|---|---|
| Envoy Gateway | Envoy | Kubernetes SIG-Network 官方孵化项目,旨在提供最符合 Gateway API 标准的、开箱即用的参考实现。设计简洁,专注于 Gateway API 功能。 | 希望紧跟标准、寻求轻量级和官方参考实现的新项目或团队。 |
| Contour | Envoy | 由 VMware 开源,是 Gateway API 的早期和积极推动者。功能成熟,社区活跃,除了 Gateway API 也支持其自身的HTTPProxyCRD(功能更丰富)。 | 已经使用或考虑使用 Contour 的团队,或者需要更平滑地从其自定义 CRD 过渡。 |
| Istio | Envoy | 作为全功能服务网格,其入口网关 Istio Ingress Gateway 已全面支持 Gateway API。提供了最强大的流量管理、安全性和可观测性能力。 | 已经部署或计划部署 Istio 服务网格的团队,希望统一入口网关和网格内部流量的管理平面。 |
| Apache APISIX Ingress Controller | Apache APISIX | 基于高性能 API 网关 APISIX,对 Gateway API 支持良好。提供了强大的插件生态和动态配置能力。 | 看重高性能、丰富插件生态(如认证、限流、日志)的团队。 |
| Kong Ingress Controller | Kong | 基于 Kong 网关,同样提供了对 Gateway API 的支持以及强大的插件平台。 | 已经使用 Kong 生态系统,或需要其特定商业插件和支持的团队。 |
对于从 Ingress Nginx 迁移且希望尽可能简单直接的团队,Envoy Gateway是一个极佳的起点。它没有历史包袱,完全围绕 Gateway API 构建,让我们能更纯粹地体验新标准。下面我们就以 Envoy Gateway 为例进行部署。
4.2 使用 Envoy Gateway 快速搭建环境
Envoy Gateway 的安装非常简单,它本身也是一个 Pod 运行在你的集群中。
安装 Gateway API CRDs: Gateway API 的资源类型(如
Gateway,HTTPRoute)需要通过 Custom Resource Definitions (CRDs) 来定义。首先安装它们。kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml执行后,使用
kubectl get crd | grep gateway.networking.k8s.io检查是否成功创建了gateways,httproutes等 CRD。安装 Envoy Gateway: 同样通过一句命令部署 Envoy Gateway 及其所需的 RBAC 等资源。
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.0.0/install.yaml这会在
envoy-gateway-system命名空间下部署一个Deployment。使用kubectl get pod -n envoy-gateway-system确认 Pod 状态为Running。验证安装与创建 GatewayClass: 安装完成后,Envoy Gateway 会自动创建一个名为
envoy的GatewayClass。这是基础设施提供商提供的“网关类型”。kubectl get gatewayclass你应该能看到一个名为
envoy的GatewayClass,其CONTROLLER字段为gateway.envoyproxy.io/gatewayclass-controller。
至此,一个支持 Gateway API 的网关环境就准备就绪了。接下来,你就可以应用我们在第 3 节中编写的Gateway和HTTPRoute配置了。不过请注意,在之前的Gateway示例中,我们使用了gatewayClassName: contour,如果你用的是 Envoy Gateway,需要将其改为gatewayClassName: envoy。
4.3 部署示例应用并测试路由
让我们完成一个端到端的测试,部署一个简单的 Echo 应用。
部署后端服务:
apiVersion: v1 kind: Service metadata: name: echo-service spec: ports: - port: 80 targetPort: 8080 selector: app: echo --- apiVersion: apps/v1 kind: Deployment metadata: name: echo-deployment spec: replicas: 2 selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: - name: echo image: hashicorp/http-echo args: - "-text=Hello from Echo Pod!" ports: - containerPort: 8080应用这个 YAML 文件,它会创建一个返回固定文本的 Echo 服务。
创建 Gateway 资源(使用 Envoy Gateway):
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: demo-gateway spec: gatewayClassName: envoy # 关键:使用 envoy 这个 GatewayClass listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All # 允许所有命名空间的 HTTPRoute 绑定这个
Gateway定义了一个监听 80 端口的 HTTP 监听器。由于是测试,我们暂不配置 TLS。创建 HTTPRoute 资源:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: echo-route spec: parentRefs: - name: demo-gateway rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: echo-service port: 80这个路由规则将所有流量转发到
echo-service。获取访问地址并测试: 应用上述所有配置后,Envoy Gateway 会创建对应的 Envoy Proxy Pod 和 Service。查看这个 Service:
kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=demo-gateway你会看到一个类型为
LoadBalancer或NodePort的 Service。获取其外部 IP(EXTERNAL-IP)或使用节点 IP+端口。 使用curl访问该地址,你应该能看到Hello from Echo Pod!的响应。
注意事项:在生产环境中,
Gateway监听器通常会配置为 HTTPS,并关联 TLS 证书。你需要提前准备好证书 Secret,并在Gateway的tls字段中正确引用。对于自动证书管理,可以集成 cert-manager,它已经提供了CertificateCRD 来自动为 Gateway API 资源签发和续期证书,其配置逻辑与为 Ingress 签发证书类似,但引用的资源类型变成了Gateway。
5. 高级特性实践与迁移策略
掌握了基础迁移后,我们可以探索一些 Gateway API 的高级特性,并制定一个稳妥的生产环境迁移策略。
5.1 实现高级流量管理:金丝雀发布
Gateway API 原生支持流量权重分配,这使得实现金丝雀发布变得非常简单。假设我们有一个v1版本的服务,现在要上线v2版本,希望先导流 10% 的流量进行验证。
对应的HTTPRoute配置如下:
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: canary-release-route spec: parentRefs: - name: prod-gateway hostnames: - "app.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: app-service-v1 port: 80 weight: 90 - name: app-service-v2 port: 80 weight: 10关键点:在backendRefs中,可以为一个规则指定多个后端服务,并通过weight字段(权重值,总和通常为 100)来分配流量比例。网关会根据这个比例将请求分发到不同的服务。你可以通过逐步调整weight值(例如 90/10 -> 50/50 -> 0/100)来完成平滑的版本升级或回滚。这完全通过声明式 API 完成,无需修改网关的部署或复杂的注解。
5.2 基于请求头的动态路由
除了路径和权重,基于请求头的路由是灰度发布、A/B 测试的常用手段。例如,只有包含特定 HTTP 头X-Canary: true的请求才被路由到新版本。
apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: header-based-route spec: parentRefs: - name: prod-gateway hostnames: - "app.example.com" rules: # 规则1:匹配特定请求头的流量去 v2 - matches: - headers: - name: X-Canary value: "true" backendRefs: - name: app-service-v2 port: 80 # 规则2:其他所有流量去 v1(兜底规则) - matches: - path: type: PathPrefix value: / backendRefs: - name: app-service-v1 port: 80匹配顺序:HTTPRoute中的规则是按顺序评估的。第一个匹配的规则会被执行。因此,我们将检查X-Canary头的规则放在前面,兜底的通用路径规则放在后面。
5.3 生产环境渐进式迁移策略
对于已存在大量 Ingress Nginx 配置的生产系统,一刀切切换是危险的。建议采用渐进式迁移策略:
- 并行运行,双网关共存:在集群中同时部署 Ingress Nginx Controller 和新的 Gateway API 控制器(如 Envoy Gateway)。它们可以监听不同的 Service(NodePort/LoadBalancer),或者通过不同的 IngressClass/GatewayClass 区分。这是风险最低的阶段。
- 逐业务迁移,小范围验证:
- 选择试点:挑选一个非核心、流量较小的服务作为第一个迁移对象。
- 配置转换:将该服务的 Ingress 配置手动转换为
Gateway+HTTPRoute配置。 - DNS 测试:在测试环境中,将试点服务的测试域名(如
test-app.example.com)解析到新网关的地址。进行全面测试,包括功能、性能、监控和日志。
- 流量切换与监控:
- 蓝绿 DNS 切换:在确认试点服务稳定后,可以在 DNS 层面将少量生产流量(通过权重或分地区解析)指向新网关。例如,先切 1% 的流量。
- 严密监控:观察新网关的延迟、错误率、资源消耗等关键指标,并与旧网关进行对比。同时确保日志格式和字段符合现有日志分析系统的要求。
- 逐步放大:如果一切正常,逐步增加切流比例,如 5% -> 20% -> 50% -> 100%。
- 批量迁移与自动化:
- 在积累一定经验后,可以编写脚本或使用工具(如
ingress2gateway这类转换工具,但需仔细核对)来辅助批量转换配置。 - 建立标准的迁移流程和检查清单。
- 在积累一定经验后,可以编写脚本或使用工具(如
- 最终切换与清理:
- 当所有流量都成功迁移至新网关,且稳定运行足够长时间(如一个业务周期)后,可以下线旧的 Ingress Nginx Controller。
- 清理旧的
Ingress资源。
实操心得:在整个迁移过程中,监控和可观测性是生命线。确保新网关的 metrics(如请求数、延迟、4xx/5xx 错误)能够无缝集成到现有的 Prometheus + Grafana 监控体系中。同时,访问日志的格式和输出位置也需要调整适配,以确保业务排查和审计不受影响。Envoy 等网关通常有丰富的指标和灵活的日志配置,需要提前做好对接工作。
6. 常见问题与深度排查指南
在实际迁移和运维 Gateway API 的过程中,你肯定会遇到各种问题。下面我整理了一些典型问题的排查思路和解决方法,这些很多都是我在实践中踩过的坑。
6.1 路由不生效:HTTPRoute 状态排查
创建了Gateway和HTTPRoute后,访问网关地址却得到404或503,这是最常见的问题。首先,要学会查看资源的状态字段。
检查
Gateway状态:kubectl describe gateway <gateway-name>关注
Status部分。Listeners列表下每个监听器应有Accepted: True和Ready: True。如果Accepted为False,查看Conditions信息,常见原因有:GatewayClass不存在或控制器不支持。- 端口冲突(如该端口已被其他
Gateway或 Pod 占用)。 - TLS 证书引用的
Secret不存在或格式错误。
检查
HTTPRoute状态:kubectl describe httproute <httproute-name>同样查看
Status。Parents列表应显示它已成功绑定到预期的Gateway监听器,状态为Accepted: True。如果未绑定成功,检查:parentRefs字段中的name和namespace是否正确。Gateway监听器的allowedRoutes配置是否允许当前HTTPRoute所在的命名空间进行绑定。hostnames是否与Gateway监听器允许的主机名匹配。
6.2 后端服务无法连接:深入 Pod 与 Endpoint
如果路由状态正常,但返回502 Bad Gateway或503 Service Unavailable,问题可能出在网关到后端服务的连接上。
检查 Service 与 Endpoint:
kubectl get svc <service-name> -o wide kubectl get endpoints <service-name>确认
Service存在,且Endpoints列表不为空。空的Endpoints意味着没有 Pod 匹配Service的selector,可能是 Deployment 未成功创建或标签不匹配。检查网关数据平面日志: 直接查看 Envoy Proxy 容器的日志,这能提供最直接的错误信息。首先找到由你的
Gateway资源创建的 Envoy Proxy Pod(通常在envoy-gateway-system或其他指定命名空间)。kubectl logs -f <envoy-proxy-pod-name> -c envoy -n <gateway-namespace>在日志中搜索你的后端服务域名或集群名,常见的错误有:
no healthy upstream:后端 Pod 不健康或就绪探针失败。upstream connect error or disconnect/reset before headers:网络策略(NetworkPolicy)阻止了网关 Pod 访问应用 Pod,或者应用端口未正确监听。
6.3 TLS/HTTPS 相关问题
配置 HTTPS 时问题频发,需要层层排查。
- 证书 Secret 格式:Gateway API 要求 TLS 证书 Secret 必须是
kubernetes.io/tls类型,且包含tls.crt和tls.key两个键名。kubectl get secret <tls-secret-name> -o jsonpath='{.type}' # 应返回 `kubernetes.io/tls` kubectl get secret <tls-secret-name> -o jsonpath='{.data}' | jq keys # 应包含 `tls.crt` 和 `tls.key` - SNI 匹配:如果
Gateway的监听器配置了多个主机名,或者HTTPRoute的hostnames与Gateway监听器的hostname不匹配,可能会导致 SSL 握手失败。确保它们之间的一致性。 - 证书链完整性:确保
tls.crt中包含了完整的证书链(服务器证书 + 中间 CA 证书),而不仅仅是叶子证书。不完整的链可能导致某些客户端无法验证。
6.4 从 Ingress 注解到 Gateway API 过滤器的映射
迁移时,最大的工作量之一就是翻译那些五花八门的 Nginx 注解。下面是一个常见注解的映射参考:
| Ingress Nginx 注解 | Gateway API 等效实现 | 说明与注意事项 |
|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | HTTPRoute中的URLRewrite过滤器 | Gateway API 的替换逻辑更清晰,需指定type: ReplacePrefix或ReplaceFullPath。 |
nginx.ingress.kubernetes.io/configuration-snippet | 可能对应EnvoyPatchPolicy(扩展) 或自定义过滤器 | 这是 Nginx 特有的配置片段,迁移最复杂。Gateway API 标准方式是用其内置过滤器(如头修改、重定向)。对于必须的 Envoy 特定配置,可查阅所用实现的扩展机制(如 Envoy Gateway 的EnvoyProxyCRD)。建议优先重构业务逻辑,避免使用配置片段。 |
nginx.ingress.kubernetes.io/proxy-buffering | 网关实现特定的配置或策略 | 这类性能调优参数通常在 Gateway 或 GatewayClass 级别通过实现相关的自定义资源进行配置,而非在路由规则中。 |
nginx.ingress.kubernetes.io/ssl-redirect | 在Gateway中配置 HTTP 80 -> HTTPS 443 的重定向监听器,或使用HTTPRoute的RequestRedirect过滤器。 | 最佳实践是在Gateway中设置一个 HTTP 监听器,其唯一作用就是返回 301/302 重定向到 HTTPS。 |
一个重要的心态调整:迁移不仅是语法的转换,更是架构思维的升级。与其追求 100% 原样的功能映射,不如借此机会审视那些复杂的 Nginx 注解是否真的必要。很多时候,那些注解是为了弥补 Ingress 标准能力的不足。利用 Gateway API 更强大的标准功能(如流量切分、多维度匹配),或许能以更简洁、标准的方式实现业务需求,从而降低长期的维护成本。