CKA [Networking] – Ingress和Gateway的区别

在 Kubernetes 中,IngressGateway 都是用于管理集群外部流量进入集群服务的机制,但它们各自适用的场景、控制能力和架构设计不同

✅ 一、有了 Ingress,为什么还需要 Gateway?

Ingress 的局限性:

  1. 耦合太紧:
    • Ingress 通常依赖于特定的控制器(如 NGINX、Traefik),它的行为和功能依赖于这些控制器实现。
    • 不同控制器支持的 annotation、配置方式不一致,缺乏标准化。
  2. 功能有限:
    • Ingress 只支持 L7 HTTP/HTTPS 路由,不支持 L4(如 TCP、gRPC、TLS passthrough)流量。
    • 复杂场景(如多协议支持、多租户、多路径转发)难以配置。
  3. 扩展性差:
    • 想要对路由进行更复杂的控制(如权重转发、重写 header、限流)时,必须依赖控制器扩展。

✅ 二、Ingress 和 Gateway 的区别

项目IngressGateway (Gateway API)
定义Ingress 是 Kubernetes 最早期引入的资源类型,用于管理 HTTP/HTTPS 入口流量Gateway 是 Kubernetes 新一代标准,来源于 Gateway API 项目,设计上更灵活、可扩展
支持协议主要支持 HTTP/HTTPS支持 HTTP、HTTPS、TCP、TLS、gRPC 等多协议
控制器耦合强依赖特定 Ingress ControllerGateway 与 Controller 解耦,Controller 实现了 GatewayClass,可被替换
可扩展性差,扩展依赖 annotation好,原生 CRD 支持更复杂的路由策略(HTTPRoute、TCPRoute 等)
安全性难以做细粒度权限管理更好支持 RBAC、多租户控制(Gateway 与 Route 可分开授权)
多租户支持弱,Ingress 通常在单一 namespace 管理强,Gateway 和 Route 可以分别在不同 namespace 中定义和控制
状态反馈状态反馈不标准,用户体验差状态清晰标准化,调试和排错更容易

✅ 三、Gateway 的优点

  1. 协议丰富:支持 HTTP、TCP、TLS、gRPC、UDP(部分实现)等多种协议,支持更多真实世界的流量场景。
  2. 清晰分层架构
    • GatewayClass:定义控制器类型(例如 Istio、NGINX)。
    • Gateway:声明资源入口点(监听端口、证书等)。
    • Route(如 HTTPRoute, TCPRoute):定义路由规则。
    👉 类似于 Istio 的 Gateway + VirtualService 架构,分离关注点,权限更好管理。
  3. 跨 namespace 管理
    • 一个 Gateway 可以由 platform team 管理,而 Route 可以由 app team 在不同 namespace 独立管理,真正实现平台与业务解耦。
  4. 更好的标准化与可观测性
    • Gateway API 规范提供标准状态反馈和错误信息,便于调试和监控。
    • 与服务网格(如 Istio)深度集成,有天然优势。

新版本发布控制的多样性

httproute需要配合gateway, 在httproute当中可以设置weight, 这个weight可以根据不同的比重来分发流量到不同的service。

1. 灰度/金丝雀发布(Canary Releases)
当你发布一个新版本(foo-v2)时,不想一下子把所有流量都切给它,而是先把绝大多数请求留给旧版本(foo-v1),比如 90%→10% 的比例流转。这样即便新版本有问题,也只影响小部分用户,便于快速回

rules:
  - backendRefs:
      - name: foo-v1
        port: 8080
        weight: 90
      - name: foo-v2
        port: 8080
        weight: 10

weight 值 90 和 10 的和(100)就是“分母”,每个后端实例获得的流量占比即为 weight/100

2. A/B 测试
你可以把不同的后端(A 版本、B 版本)设置不同权重,比如 50/50,或者按照 70/30 分流给不同实验组,以收集用户行为数据、对比效果。一次性在同一条路由下搞定,不必再额外引入 Service Mesh 的流量分发规则

3. 蓝绿部署(Blue-Green Deployment)
当新旧环境同时在线时,可以先把 100% 流量给“蓝”(旧环境),确认没问题后,把“绿”(新环境)的权重调到 1(此时占比 50%:50%),再切到 0(100% 都给新环境)。

# 切换完成时的新配置
rules:
  - backendRefs:
      - name: blue-svc
        port: 8080
        weight: 0
      - name: green-svc
        port: 8080
        weight: 1

只需更新 weight,就能实现平滑切换和快速回滚

Canary Deployment里,如何确保同一个用户都固定在同一个service当中?

在 Gateway API 里,weight 只是按比例(随机)把每个请求分给不同后端,它并不会“记住”同一个用户之前去了哪里。要让 同一个用户 在整个会话/浏览器里「一以贯之」地命中同一个版本,你需要在路由层面做会话粘滞 (session affinity),常用的模式就是:

  1. 首次请求 随机分流(按 weight),并在响应里写入一个 Cookie,比如 canary=true
  2. 后续请求 根据这个 Cookie 匹配路由,把它始终导向同一个后端

下面给出一个基于 HTTPRoute 的简化示例(假设你的 Controller 支持 HTTPRouteFilter 中的 RequestHeaderModifier 和 HeaderMatch):

apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: canary-release
spec:
  parentRefs:
    - name: my-gateway

  # 1. 如果请求带了 canary=true,就走 canary-svc
  rules:
    - matches:
        - headers:
            - name: Cookie
              value: "canary=true"
      backendRefs:
        - name: canary-svc
          port: 80
          weight: 100

  # 2. 默认流量,按比例先给 canary,再给 stable
    - matches:
        - path:
            type: Prefix
            value: /
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              # 在响应里给客户端写 Cookie,后续它会带上
              - name: Set-Cookie
                value: "canary=true; Path=/; Max-Age=3600"
      backendRefs:
        - name: canary-svc
          port: 80
          weight: 10
        - name: stable-svc
          port: 80
          weight: 90

1. 默认情况走这一条规则

  • 当请求里没有 Cookie: canary=true 时,就会匹配到第 2 条规则(因为第 1 条需要带这个 Cookie)。

2. 按权重(weight)分流

  • 在这一条规则里,我们给了两个后端:
    • canary-svcweight: 10
    • stable-svcweight: 90
  • 这表示“把 100% 的默认流量里,有 10% 随机发给 canary,剩下 90% 发给 stable”。
  • 实际上 Controller 会把请求分成 10:90 的概率,你的客户端每次来,随机地有 10% 的机会被路由到 canary-svc,90% 的机会被路由到 stable-svc

3.设置 Cookie 以便粘滞

对于被分到 canary-svc 的那 10% 请求,规则里又附带了一个 RequestHeaderModifier 过滤器:

filters:
  - type: RequestHeaderModifier
    requestHeaderModifier:
      add:
        - name: Set-Cookie
          value: "canary=true; Path=/; Max-Age=3600"
  • 它会在 响应 头里加上 Set-Cookie: canary=true,告诉浏览器这个用户“以后你就是 canary 组的”。

4.后续请求保持一致

  • 浏览器拿到这个 Cookie 后,每次再来就带上 Cookie: canary=true,这样就会命中第 1 条规则,100% 发给 canary-svc,保证用户体验一致,不会“新旧页面混用”。

Loading

Facebook评论