Kubernetes Ingress 到 Gateway API:服务暴露的演进之路

引言 在 Kubernetes 集群中,如何将内部服务安全、高效地暴露给外部用户,是每个平台工程师必须面对的核心问题。自 K8s 诞生以来,Ingress 长期扮演着「官方网关「的角色;然而随着微服务架构的复杂化,Ingress 的诸多限制逐渐暴露。

引言

在 Kubernetes 集群中,如何将内部服务安全、高效地暴露给外部用户,是每个平台工程师必须面对的核心问题。自 K8s 诞生以来,Ingress 长期扮演着"官方网关"的角色;然而随着微服务架构的复杂化,Ingress 的诸多限制逐渐暴露。2023 年 GA 的 Gateway API,正是 Kubernetes 社区给出的下一代标准答案。本文将系统梳理从 Ingress 到 Gateway API 的演进脉络,并给出可落地的迁移实践。


一、Ingress:单层入口与注解地狱

Ingress 的核心设计非常简洁:它定义了一组规则,将集群外部的 HTTP/HTTPS 流量路由到集群内的 Service。所有流量先经过云厂商或自建的一层负载均衡(LoadBalancer),再由 Ingress Controller 根据域名和路径分发到后端 Pod。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: frontend-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-svc
                port:
                  number: 80
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls

上述 YAML 展示了一个典型的 Ingress 资源。它依赖 nginx.ingress.kubernetes.io/* 这类 annotations 来实现重写、SSL 重定向和速率限制——这正是社区戏称的 “annotations hell”(注解地狱)。不同 Controller(Nginx、Traefik、HAProxy)的注解互不兼容,导致配置锁定严重。

Ingress 的工作流程可概括为:

  1. 用户创建 Ingress 资源;
  2. Ingress Controller(如 NGINX Ingress Controller)监听资源变更;
  3. Controller 生成底层代理配置(如 nginx.conf)并重载;
  4. 外部流量经 LoadBalancer 到达 Controller,再按规则转发。

二、Ingress 的三大瓶颈

随着集群规模和多租户需求的增加,Ingress 的设计短板日益明显。

2.1 无法跨命名空间路由

Ingress 只能引用同命名空间的 Service。若平台团队希望在 infra 命名空间部署统一网关,而将业务服务分散在 team-ateam-b 等命名空间,Ingress 无法直接支持,只能借助繁琐的外部 Service 拼接。

2.2 协议支持受限

Ingress 仅原生支持 HTTP/HTTPS。对于 TCP、UDP、gRPC(TLS 模式)、数据库等四层流量,必须绕过 Ingress,使用 LoadBalancer 类型的 Service,导致网络入口分散、策略难以统一。

2.3 缺乏高级流量能力

Ingress 标准未定义流量分割(traffic splitting)、镜像(mirroring)、超时重试、蓝绿发布等高级能力。这些功能全部由各 Controller 通过私有注解实现,既不可移植,也难以维护。


三、Service Mesh 的补位:Istio Gateway

在 Gateway API 出现之前,许多团队选择用 Istio 的 Gateway 资源来弥补 Ingress 的不足。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: public-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: SIMPLE
        credentialName: app-tls
      hosts:
        - "app.example.com"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: frontend-vs
spec:
  hosts:
    - app.example.com
  gateways:
    - public-gateway
  http:
    - route:
        - destination:
            host: frontend-svc
            port:
              number: 80

Istio Gateway 解耦了"监听器配置"与"路由规则",且支持丰富的流量策略。但它本质上是 Service Mesh 的附属品,引入了 Sidecar 的复杂度和资源开销,对于不需要服务间 mTLS 或精细可观测性的场景显得过重。


四、Gateway API:面向角色的下一代标准

Gateway API 由 SIG-Network 主导设计,核心目标有三:

  • 角色分离:基础设施管理员、集群操作员、应用开发者各司其职;
  • 可扩展性:原生支持 HTTP、TCP、TLS、gRPC 等多协议;
  • 跨命名空间:允许 Gateway 引用其他命名空间的 Service。

4.1 核心资源模型

资源对应角色职责
GatewayClass基础设施管理员定义一类网关的模板(如 nginx、istio、traefik)
Gateway集群操作员配置监听器、TLS、地址等网络端点
HTTPRoute / TCPRoute / TLSRoute / GRPCRoute应用开发者定义具体的路由规则和后端服务

这种分层模型让不同团队可以独立操作各自资源,避免权限混乱。

4.2 Gateway + HTTPRoute 示例

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx
spec:
  controllerName: gateway.nginx.org/nginx-gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: infra
spec:
  gatewayClassName: nginx
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - kind: Secret
            name: app-tls
      allowedRoutes:
        namespaces:
          from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: frontend-route
  namespace: team-a
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  hostnames:
    - "app.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: frontend-svc
          port: 80

注意:这里的 HTTPRoute 位于 team-a 命名空间,却能挂载到 infra 命名空间的 Gateway 上。allowedRoutes.namespaces.from: All 显式授权了这种跨命名空间引用。


五、Ingress 到 Gateway API 的迁移实践

迁移不是一次性替换,而是渐进式推进。推荐按以下步骤实施:

5.1 前置条件:部署 Gateway API CRDs

多数集群默认未安装 Gateway API 的自定义资源。需要先部署 CRDs:

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml

5.2 选择并部署 Gateway Controller

根据团队现有技术栈,选择对应的 Gateway 实现:

方案特点适用场景
NGINX Gateway Fabric官方实现,轻量,与 NGINX Ingress 配置语法接近已有 Nginx 生态,追求标准合规
Traefik原生支持 Gateway API,Dashboard 直观云原生友好的中小集群
Istio功能最全,与 Mesh 无缝集成已部署 Service Mesh 的环境
Envoy Gateway基于 Envoy,扩展性强需要高级流量治理的大型平台

5.3 并行部署与灰度切换

  1. 在新命名空间(如 gateway-api)部署 Gateway 和 Gateway Controller;
  2. 将部分域名的 DNS 指向新 Gateway 的 LoadBalancer IP;
  3. 逐步将 Ingress 规则翻译为 HTTPRoute,验证功能一致性;
  4. 全域切换后,保留旧 Ingress Controller 一段时间作为回滚预案。

六、NGINX Ingress Controller vs NGINX Gateway Fabric

拥有 Nginx 技术栈的团队常纠结这两个项目。二者定位截然不同:

维度NGINX Ingress ControllerNGINX Gateway Fabric
标准遵循私有 annotations 为主原生 Gateway API
配置来源Ingress 资源Gateway + HTTPRoute
跨命名空间不支持原生支持
商业特性Plus 版本提供 WAF、JWT同样支持 Plus 扩展
社区归属Kubernetes Ingress-Nginx(社区)NGINX 官方 + SIG-Network

简言之,新项目首选 Gateway Fabric;存量 Ingress 可渐进迁移。二者甚至可以共存于同一集群,通过不同 LoadBalancer 入口分担流量。


七、Traefik 作为 Gateway Controller

Traefik 从 v3 起对 Gateway API 提供了开箱即用的支持。启用方式极其简单:

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: traefik
spec:
  controllerName: traefik.io/gateway-controller

Traefik 的优势在于其自动服务发现和简洁的 Dashboard。对于不想深度定制 Envoy 配置的团队,Traefik 是平衡易用性与功能性的优选。


八、实战:金丝雀发布与流量镜像

以下示例展示 Gateway API 在实际场景中的威力。

8.1 金丝雀发布(Canary)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: frontend-canary
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  hostnames:
    - app.example.com
  rules:
    - matches:
        - headers:
            - name: canary
              value: "true"
      backendRefs:
        - name: frontend-v2
          port: 80
    - backendRefs:
        - name: frontend-v1
          port: 80
          weight: 90
        - name: frontend-v2
          port: 80
          weight: 10

上述规则实现了双重策略:

  • canary: true Header 的请求 100% 进入 v2;
  • 普通请求按 90:10 比例分流到 v1 与 v2。

8.2 流量镜像(Traffic Mirroring)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: frontend-mirror
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  hostnames:
    - app.example.com
  rules:
    - backendRefs:
        - name: frontend-v1
          port: 80
      filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              name: frontend-v2
              port: 80

流量镜像将请求的副本发送给 v2,同时不影响主请求的响应。这对上线前的影子验证极为有用。


九、Ingress 与 Gateway API 综合对比

特性IngressGateway API
协议支持HTTP/HTTPSHTTP/HTTPS/TCP/TLS/gRPC
跨命名空间不支持原生支持
角色分离Gateway / Route 分层
流量分割依赖注解内置 weight
流量镜像不支持RequestMirror filter
可移植性注解锁定厂商标准资源,厂商无关
成熟度极高,生态丰富GA,逐渐主流

结语

Gateway API 不是对 Ingress 的简单修补,而是一次面向未来云原生网络的架构升级。它通过角色分离降低协作成本,通过标准资源打破厂商锁定,通过丰富的路由能力支撑现代化的发布策略。对于正在建设 Kubernetes 平台的团队,建议在新集群直接采用 Gateway API;存量集群则可按业务域逐步迁移。服务暴露的演进之路,从 Ingress 到 Gateway API,正是 Kubernetes 网络从"能用"走向"好用"的缩影。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「kubernetes」更多文章

  1. Kubernetes 可观测性实战:集群、Pod、网络、存储全链路监控