为什么说 Gateway API 是 Kubernetes 和服务网格入口中网关的未来?

标签: gateway api kubernetes | 发表时间:2022-11-02 11:18 | 作者:
出处:https://jimmysong.io/blog/

本文将以 Kubernetes Ingress、Istio 和 Envoy Gateway 为例,向你介绍 Kubernetes 中的入口网关和 Gateway API,同时介绍 Gateway API 使得 Kubernetes 和服务网格入口网关融合的新趋势。

本文观点

  • Ingress 作为 Kubernetes 的初代入口网关,它的资源模型过于简单以致于无法适应当今的可编程网络;
  • Gateway API 作为 Kubernetes 入口网关的最新成果,它通过角色划分将关注点分离,并提供跨 namespace 支持使其更适应多云环境,已获得大多数 API 网关的支持;
  • 入口网关(南北向)与服务网格(东西向,集群内路由)存在部分功能重叠,Gateway API 为两者的融合提供了新的参考模型;

Kubernetes 入口网关的历史

2014 年 6 月 Kubernetes 开源,起初只能使用 NodePort 和 LoadBalancer 类型的 Service 对象来暴露集群内服务,后来才诞生了 Ingress ,两年后(Kubernetes 1.2) Ingress API 进入 Beta 版本,随后为了保持其轻量和可移植的特性,Ingress API 相较于 Kubernetes 其他 API 发展得比较缓慢,直到 Kubernetes 1.19 它才升级到 GA。

Ingress 的主要目标是用简单的、声明性的语法来暴露 HTTP 应用。你可以在 Kubernetes 中部署多种 Ingress Controller,并在创建 Ingress 的时候通过 IngressClass 指定该网关使用的控制器,或者在 Kubernetes 中设置默认的默认的 IngressClass。Kubernetes 默认只支持 AWS、GCE 和 Nginx Ingress Controller,同时还支持大量的 第三方 Ingress Controller

下图展示了 Kubernetes Ingress 的工作流程。

image Kubernetes Ingress 工作流程

详细流程如下:

  1. Kubernetes 集群管理员在 Kubernetes 中部署 Ingress Controller;
  2. Ingress Controller 会持续监视 Kubernetes API Server 中的 IngressClass 和 Ingress 对象的变动;
  3. 管理员应用 IngressClass 和 Ingress 来部署网关;
  4. Ingress Controller 会根据管理员的配置来创建对应的入口网关并配置路由规则;
  5. 如果在云中,客户端会访问该入口网关的负载均衡器;
  6. 网关将根据 HTTP 请求中的 host 和 path 将流量路由到对应的后端服务;

Istio 同时支持 Ingress 和 Gateway API,下面是一个使用 Istio 入口网关的配置示例,在后文中会使用 Gateway API 创建该配置。

   apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: istio
spec:
  controller: istio.io/ingress-controller
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
spec:
  ingressClassName: istio
  rules:
  - host: httpbin.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: httpbin
            port: 8000

注意:Ingress 的 spec 中必须在 ingressClassName 字段中指定使用的 IngressClass,否则将无法创建对应的入口网关。

Kubernetes Ingress 的局限性

虽然 IngressClass 实现了入口网关与后台实现的解耦,但是它仍然有着巨大的局限性:

  • Ingress 的配置过于简单,仅支持 HTTP 协议路由;
  • HTTP 路由仅支持 host 和 path 匹配,对于高级路由功能没有通用配置,只能通过 annotation 来实现,比如 使用 Nginx Ingress Controller 实现 URL 重定向 ,需要配置 nginx.ingress.kubernetes.io/rewrite-target annotation,已经无法适应可编程路由的需求;
  • 不同命名空间中的服务要绑定到同一个网关中的情况在实际情况下经常出现,而入口网关无法在多个命名空间中共享;
  • 入口网关的创建和管理的职责没有划分界限,导致开发者不仅要

Kubernetes Gateway API

Gateway API 是一个 API 资源的集合 —— GatewayClassGatewayHTTPRouteTCPRouteReferenceGrant 等。Gateway API 暴露了一个更通用的代理 API,可以用于更多的协议,而不仅仅是 HTTP,并为更多的基础设施组件建模,为集群运营提供更好的部署和管理选项。

另外 Gateway API 通过将资源对象分离,实现配置上的解耦,可以由不同的角色的人员来管理,其中的 API 对象如下图所示。

image Gateway API 及角色

下面是在 Istio 中使用 Gateway API 的示例。

   apiVersion: gateway.networking.k8s.io/v1alpha2
kind: Gateway
metadata:
  name: gateway
  namespace: istio-ingress
spec:
  gatewayClassName: istio
  listeners:
  - name: default
    hostname: "*.example.com"
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: http
  namespace: default
spec:
  parentRefs:
  - name: gateway
    namespace: istio-ingress
  hostnames: ["httpbin.example.com"]
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: httpbin
      port: 8000

与 Ingress 类似,Gateway 使用 gatewayClassName 声明其使用的控制器,该控制器需要平台管理员创建,并允许客户端对 *.example.com 域名的请求。应用开发者可以在其服务所在的命名空间中,在此示例中是 default 创建路由规则,并通过 parentRefs 绑定到 Gateway 上,当然这必须是在 Gateway 明确允许其绑定的情况下(通过 allowRoutes 字段中的规则设置)。

当你应用上面的配置后,Istio 会自动为你创建一个负载均衡网关,下图展示了 Gateway API 的工作流程。

image Gateway API 工作流程

详细流程如下:

  1. 基础设施供应商提供了 GatewayClass 和 Gateway 控制器;
  2. 平台运维部署 Gateway(可以部署多个,或使用不同的 GatewayClass);
  3. Gateway Controller 会持续监视 Kubernetes API Server 中的 GatewayClassGateway 对象的变动;
  4. Gateway Controller 会根据集群运维的配置来创建对应的网关;
  5. 应用开发者应用 xRoute 并绑定服务上;
  6. 如果在云中,客户端会访问该入口网关的负载均衡器;
  7. 网关将根据流量请求中的匹配条件将路由到对应的后端服务;

从以上步骤中我们可以看出 Gateway API 相比 Ingress 有了明确的角色划分,而且路由规则可以与网关配置解耦,这大大增加了管理的灵活性。

下图展示了流量接入网关后经过处理的流程。

image 网关处理流程图

从图中我们可以看出路由是与网关绑定的,路由一般与其后端服务部署在同一个命名空间中,如果在不同的命名空间中时,需要在 ReferenceGrant 中明确赋予该路由跨命名空间的引用权限,例如下面的 foo 命名空间中的 HTTPRoute foo 可以引用 bar 命名空间中的 bar 服务。

   kind: HTTPRoute
metadata:
  name: foo
  namespace: foo
spec:
  rules:
  - matches:
    - path: /bar
    forwardTo:
      backend:
      - name: bar
        namespace: bar
---
kind: ReferenceGrant
metadata:
  name: bar
  namespace: bar
spec:
  from:
  - group: networking.gateway.k8s.io
    kind: HTTPRoute
    namespace: foo
  to:
  - group: ""
    kind: Service

目前,Gateway API 仅支持 HTTPRouteTCPRouteUDPRouteTLSRouteGRCPRoute 还在实验阶段。Gateway API 已经得到了大量的网关和服务网格项目的支持,请 在 Gateway 官方文档中查看支持状况

入口网关与服务网格

服务网格主要关注的是东西向流量,即 Kubernetes 集群内部的流量,但是大部分服务网格同样提供了入口网关功能,例如 Istio。但是 Istio 的功能和 API 过于复杂,在本文中我们就以 SMI 为例来说明入口网关和服务网格的关系。

SMI (Service Mesh Interface)是 CNCF 的孵化项目,开源与 2019 年,它定义了独立于供应商的在 Kubernetes 中运行的服务网格通用标准。

下图说明 Gateway API 与服务网格 API 的重叠点。

image Gateway API 与 SMI 有部分重合

从图中我们可以看到 Gateway API 与 SMI 在流量规范部分有明显的重叠。这些重叠导致同样的功能,需要在 Gateway API 和服务网格中重复实现。

Istio 服务网格

当然,并不是所有的服务网格是完全符合 SMI 标准,Istio 是目前最流行的服务网格实现,它提供了丰富的流量管理功能,但是没有对这些功能制定单独的策略 API,而是耦合在 VirtualServiceDestinationRule 中,如下所示。

VirtualService

  • 路由:金丝雀发布、基于用户身、URI、Header 等匹配路由等;
  • 错误注入:HTTP 错误代码注入、HTTP 延时注入;
  • 流量切分:基于百分比的流量切分路由;
  • 流量镜像:将一定百分比的流量镜像发送到其他集群;
  • 超时:设置超时时间,超过设置的时间请求将失败;
  • 重试:设置重试策略,如触发条件、重试次数、间隔时间等;

DestinationRule

  • 负载均衡:设置负载均衡策略,如简单负载均衡、区域感知负载均衡、区域权重负载均衡;
  • 熔断(Circuit Breaking):通过异常点检测(Outlier Detection)和连接池设置将异常节点从负载均衡池中剔除;

VirtualService 主要处理路由相关功能,而 DestinationRule 负责集群节点的开合和负载均衡。

Gateway API 融合 Kubernetes 和服务网格的入口网关

正如上文所述,Gateway API 与服务网格之间有部分功能交集,为了减少重复开发,促成对 Gateway API 与服务网格之间共同关注点的建模,Gateway API 工作组提出了 GAMMA (Gateway API Mesh Management and Administration)倡议。

在该倡议的倡导下,那些在不同网关实现中的细节各不相同的高级流量管理功能,例如超时、重试、健康检查等,全部通过 策略附件 (Policy Attachment)的方式将由各个提供商来实现。你可以通过通过 targetRef 字段指定策略附件所附加到的资源对象,例如下所示:

   apiVersion: networking.acme.io/v1alpha1
kind: RetryPolicy
metadata:
  name: foo
spec:
  override:
    maxRetries: 10
  default:
    maxRetries: 5
  targetRef:
    group: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    name: foo

在这里例子中重试策略被附加到了名为 fooHTTPRoute 上。策略附件附加到不同的资源对象上,其生效的优先级也不同,例如 GatewayClass 是集群级的资源,如果策略附件覆盖在它上面的话,将优先生效。

你可以给附加策略指定 overridedefault 值,其在入口和网格内不同资源上的层次结构的优先级是如下图所示。

image Kubernetes 入口与网格中的覆盖和默认值的优先级

目前,Gateway API 正在探索用来处理网格流量,并提出了一些 设计方案

Envoy Gateway

2022 年 10 月 Envoy Gateway 首个开源版本 v0.2 发布 ,这是一个基于 Envoy 代理的遵循 Gateway API 而创建的网关, Tetrate 是该项目的核心发起者之一。Envoy Gateway 的目标是降低用户采用 Envoy 作为 API 网关的障碍,以吸引更多用户采用 Envoy。它通过入口和 L4/L7 流量路由,表达式、可扩展、面向角色的 API 设计,使其成为供应商建立 API 网关增值产品的基础。

早在 Envoy Gateway 发布之前,Envoy 作为最流行了云原生代理之一,已被大规模采用,有多款 Gateway 软件基于 Envoy 构建,Istio 服务网格使用它作为默认的 sidecar 代理,并通过 xDS 协议来配置这些分布式代理。在 Envoy Gateway 中,它同样使用 xDS 来配置 Envoy 机群,下图展示了 Envoy Gateway 的架构。

image Envoy Gateway 架构图

基础设施供应商会为你提供 GatewayGlass,你可以通过创建一个 Gateway 声明来创建一个 Envoy Gateway,你在 Gateway 中的路由和策略附件会通过 xDS 协议发送给 Envoy 机群。

关于 Envoy Gateway 的进一步介绍,请阅读:

总结

Gateway API 作为下一代 Kubernetes Ingress API,为 Kubernetes 网关供应商提供一定程度上的 API 规范,在保证其可移植性的前提下丰富了入口网关的功能,同时通过关注点分离方便不同觉得对网关进行管理。最后GAMMA 倡议正在促进服务网格的入口网关与 Gateway API 的融合,策略附件可能将 Gateway API 的功能进一步扩展到东西向网关,我们拭目以待。

参考

相关 [gateway api kubernetes] 推荐:

Blog: Kubernetes Gateway API 进入 Beta 阶段

- - Kubernetes – 生产级别的容器编排系统
作者: Shane Utt (Kong)、Rob Scott (Google)、Nick Young (VMware)、Jeff Apple (HashiCorp). 我们很高兴地宣布 Gateway API 的 v0.5.0 版本发布. 我们最重要的几个 Gateway API 资源首次进入 Beta 阶段.

为什么说 Gateway API 是 Kubernetes 和服务网格入口中网关的未来?

- - Jimmy Song - 专注于探索后 Kubernetes 时代的云原生新范式 – 博客
本文将以 Kubernetes Ingress、Istio 和 Envoy Gateway 为例,向你介绍 Kubernetes 中的入口网关和 Gateway API,同时介绍 Gateway API 使得 Kubernetes 和服务网格入口网关融合的新趋势. Ingress 作为 Kubernetes 的初代入口网关,它的资源模型过于简单以致于无法适应当今的可编程网络;.

聊聊 API Gateway 和 Netflix Zuul

- - ScienJus's Blog
最近参与了公司 API Gateway 的搭建工作,技术选型是 Netflix Zuul,主要聊一聊其中的一些心得和体会. 本文主要是介绍使用 Zuul 且在不强制使用其他 Neflix OSS 组件时,如何搭建生产环境的 Gateway,以及能使用 Gateway 做哪些事. 不打算介绍任何关于如何快速搭建 Zuul,或是一些轻易集成 Eureka 之类的的方法,这些在官方文档上已经介绍的很明确了.

apache/apisix: The Cloud-Native API Gateway

- -
Health Checks: Enable health check on the upstream node and will automatically filter unhealthy nodes during load balancing to ensure system stability..

如何理解 Istio Ingress, 它与 API Gateway 有什么区别?

- - Jimmy Song - 云原生|开源|社区 – 博客
API 网关作为客户端访问后端的入口,已经存在很长时间了,它主要是用来管理”南北向“的流量;近几年服务网格开始流行,它主要是管理系统内部,即“东西向”流量,而像 Istio 这样的服务网格还内置了网关,从而将系统内外部的流量纳入了统一管控. 这经常给初次接触 Istio 的人带来困惑——服务网格与 API 网关之间是什么关系.

基于Kong和Kubernetes的Web API多版本解决方案

- - DockOne.io
今天分享一个我们正在使用的一个基于Kubernetes以及Kong网关的Web API多版本管理的解决方案,这种方案已经在我们的生产环境运行了将近两年,也迭代了很多个版本,我们觉得这个方案非常的适合用在微服务当中. 什么是Web API多版本. 版本的概念大家应该都知道,那么什么是Web API的版本呢.

有道Kubernetes容器API监控系统设计和实践

- - DockOne.io
【编者的话】本篇文章将分享有道容器服务API监控方案,这个方案同时具有轻量级和灵活性的特点,很好地体现了Kubernetes集群化管理的优势,解决了静态配置的监控不满足容器服务监控的需求. 并做了易用性和误报消减、可视化面板等一系列优化,目前已经超过80%的容器服务已经接入了该监控系统. Kubernetes 已经成为事实上的编排平台的领导者、下一代分布式架构的代表,其在自动化部署、监控、扩展性、以及管理容器化的应用中已经体现出独特的优势.

Kubernetes API探索之旅的正确姿势

- - DockOne.io
【编者的话】本文带你打开Kubernetes API的探索之旅的正确姿势,快来一睹为快吧. 使用CLI(如curl)或GUI(如postman)HTTP客户端调用Kubernetes API有很多理由. 例如,你可能需要对Kubernetes 对象进行比kubectl提供的更细粒度的控制,或者只是想在尝试从代码访问API之前探索它.

Spring Cloud Gateway(限流) | Wind Mt

- -
限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击. 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池、线程池)、限制瞬时并发数(如 nginx 的 limit_conn 模块,用来限制瞬时并发连接数)、限制时间窗口内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率);其他还有如限制远程接口调用速率、限制 MQ 的消费速率.

快速突击 Spring Cloud Gateway

- - 掘金后端
认识 Spring Cloud Gateway. Spring Cloud Gateway 是一款基于 Spring 5,Project Reactor 以及 Spring Boot 2 构建的 API 网关,是 Spring Cloud 微服务生态的主要组件之一. Spring Cloud Gateway 主要负责接口请求的路由分发,并且支持对请求的安全验证,流量监控和流量控制等扩展操作.