跳过正文
K8s Gateway API:告别 Ingress,拥抱下一代流量路由

K8s Gateway API:告别 Ingress,拥抱下一代流量路由

·593 字·3 分钟·
目录
K8s 完全指南 - 这篇文章属于一个选集。
§ : 本文

Ingress 的问题
#

Ingress 是 K8s 最早的流量入口抽象,用了这么多年,大家对它的局限性应该都有体会。

功能受限,靠注解打补丁。 Ingress 规范只定义了最基础的路径匹配和 TLS 终止。稍微复杂一点的需求,比如超时设置、限流、Header 改写、跨域,统统要靠 nginx.ingress.kubernetes.io/proxy-connect-timeout 这类私有注解实现。不同实现(nginx-ingress、Traefik、Kong)的注解完全不一样,写的配置跟实现深度绑定,换个 Ingress Controller 就要重写。

权限模型不合理。 Ingress 资源和 Service 在同一层,业务研发可以随意创建 Ingress,直接影响到集群入口的路由规则。在多租户场景下,这种设计让基础设施团队很难做权限管控——你总不能让所有人都只能操作同一个 Ingress 对象。

协议支持不够。 原生 Ingress 只支持 HTTP/HTTPS,TCP/UDP 路由、gRPC 都没有。各家实现用 CRD 扩展,但又是私有的。

Gateway API 就是在这个背景下设计出来的,目标是用一套标准 API 覆盖 Ingress 的所有场景,同时解决权限模型的问题。

Gateway API 的设计分层
#

Gateway API 把流量路由拆成三层,对应三种角色:

基础设施管理员
    ↓ 管理
GatewayClass(定义使用什么实现,类似 StorageClass)
    ↓
Gateway(具体的负载均衡器实例,绑定端口/TLS/证书)
    ↑ 业务团队
HTTPRoute / TCPRoute / GRPCRoute(定义路由规则,指向 Service)

GatewayClass 是集群级别资源,由基础设施团队创建,定义使用哪种实现(Envoy Gateway、Cilium、Traefik 等)。

Gateway 定义一个具体的入口,包括监听的协议/端口/证书。通常也由基础设施团队管理,或者授权给特定 namespace 的管理员。

HTTPRoute/TCPRoute/GRPCRoute 定义实际的路由规则,指向具体的 Service。业务团队自己管理,不需要依赖基础设施团队。

这个分层解决了权限问题:基础设施团队控制 Gateway(入口能力),业务团队自主管理路由规则,互不干扰。

实际配置示例
#

基础 HTTPRoute
#

# 基础设施团队创建
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-gateway
  namespace: infra
spec:
  gatewayClassName: envoy
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: prod-tls-cert
            namespace: infra
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: "true"

allowedRoutes.namespaces 控制哪些 namespace 的 Route 可以附着到这个 Gateway——这是权限隔离的关键配置。

# 业务团队创建,在自己的 namespace 下
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
  namespace: production
spec:
  parentRefs:
    - name: prod-gateway
      namespace: infra
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api/v1
          headers:
            - name: X-API-Version
              value: "v1"
      backendRefs:
        - name: api-service-v1
          port: 8080
          weight: 100

路径匹配和 Header 匹配
#

rules:
  - matches:
      - path:
          type: Exact
          value: /healthz
    backendRefs:
      - name: health-service
        port: 8080

  - matches:
      - path:
          type: RegularExpression
          value: /api/v[0-9]+/.*
    backendRefs:
      - name: api-service
        port: 8080

金丝雀发布(流量权重)
#

这是 Gateway API 最实用的功能之一,原生支持流量拆分:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: canary-route
  namespace: production
spec:
  parentRefs:
    - name: prod-gateway
      namespace: infra
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      backendRefs:
        - name: api-service-stable
          port: 8080
          weight: 90
        - name: api-service-canary
          port: 8080
          weight: 10

90% 流量到 stable,10% 到 canary,这在 Ingress 里需要靠各家私有注解实现,Gateway API 原生支持。

结合 Header 可以做更精细的金丝雀:

rules:
  # 带有特定 Header 的请求全量走 canary
  - matches:
      - headers:
          - name: X-Canary
            value: "true"
    backendRefs:
      - name: api-service-canary
        port: 8080
        weight: 100
  # 其余流量走 stable
  - matches:
      - path:
          type: PathPrefix
          value: /api
    backendRefs:
      - name: api-service-stable
        port: 8080
        weight: 100

gRPC 路由
#

Gateway API 有专门的 GRPCRoute,无需用 Ingress 的各种 grpc 注解:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: grpc-route
  namespace: production
spec:
  parentRefs:
    - name: prod-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: order.OrderService
            method: CreateOrder
      backendRefs:
        - name: order-grpc-service
          port: 9090

支持 Gateway API 的主流实现
#

实现特点适用场景
Envoy Gateway官方参考实现,功能完整通用,推荐新项目
Cilium与 Cilium CNI 深度集成已用 Cilium CNI 的集群
Traefik v3轻量,易操作中小规模
Kong企业级功能(限流/认证)需要 API 网关功能
Istio与服务网格集成已用 Istio 的场景

我们目前在生产用 Envoy Gateway,API 兼容性最好,社区活跃。

从 Ingress 迁移
#

迁移步骤
#

  1. 安装 Gateway API CRD(注意选版本)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
  1. 安装 Gateway API 实现(以 Envoy Gateway 为例)
helm install eg oci://docker.io/envoyproxy/gateway-helm \
  --version v1.3.0 \
  -n envoy-gateway-system \
  --create-namespace
  1. 逐条迁移 Ingress 规则,先不删老的

原来的 Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

对应的 HTTPRoute(注意注解对应的功能要通过 Gateway 的 filter 或者实现特定的扩展来配置):

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-route
  namespace: production
spec:
  parentRefs:
    - name: prod-gateway
      namespace: infra
  hostnames:
    - "api.example.com"
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /api
      filters:
        - type: URLRewrite
          urlRewrite:
            path:
              type: ReplacePrefixMatch
              replacePrefixMatch: /
      backendRefs:
        - name: api-service
          port: 8080
  1. 用 DNS 做切流:把域名先解析到新的 Gateway LB,观察一段时间,确认没问题后删老的 Ingress。

踩坑
#

CRD 版本问题。 Gateway API 有 standardexperimental 两个 channel,stable 功能在 standard 里,TCPRoute、GRPCRoute 等部分功能还在 experimental。安装 CRD 时要确认版本。

实现差异。 Gateway API 定义了核心规范,但各家实现对扩展功能的支持不一样。比如超时设置,不同实现用不同方式配置(有的通过 filter,有的通过实现特定的 Policy CRD)。迁移前先查目标实现的文档。

与老 Ingress 共存。 两套系统可以同时运行,只是会有两个 LB。如果集群规模大,要注意 LB 的成本。通常的做法是迁移一个服务就删一个 Ingress,分批次推进。

allowedRoutes 配置容易遗漏。 如果 HTTPRoute 创建后没有生效,大概率是 Gateway 的 allowedRoutes 没有包含 Route 所在的 namespace。检查 Gateway 状态和 Route 状态,有明确的 status condition 可以看。

Gateway API 在 2025 年已经 GA,核心资源(Gateway、HTTPRoute)都升到了 v1。Ingress 不会废弃,但新项目没必要再从 Ingress 起步,直接 Gateway API 省得以后再折腾迁移。

Wenzhuo Huang
作者
Wenzhuo Huang
搞运维的工程师,写代码的运维人。专注 Kubernetes、AWS、GitOps 与基础设施可靠性。这个博客既是我的技术笔记本,也是我踩过的坑的受害者档案。
K8s 完全指南 - 这篇文章属于一个选集。
§ : 本文

相关文章

Kubernetes 网络深度解析——CNI、kube-proxy、NetworkPolicy 完全指南

·962 字·5 分钟
K8s 网络是很多工程师的知识盲区,平时不出问题就忽略,一出问题就完全不知道从哪下手。我在多次生产网络故障的排查中,深刻理解了 K8s 网络的每一层。这篇文章从 Pod 网络模型讲到 NetworkPolicy 实战,帮你建立完整的 K8s 网络知识体系。