写点什么

SMI 与 Gateway API 的 GAMMA 倡议意味着什么?

作者:张晓辉
  • 2022 年 7 月 30 日
  • 本文字数:3654 字

    阅读完需:约 12 分钟

SMI 与 Gateway API 的 GAMMA 倡议意味着什么?

就在上周 Gateway API 发布版本 0.5.0,其中几个最重要的 CRD GatewayGatewayClass 以及 HTTPRoute 第一次升级到了 beta 版本。升级的详细内容这里不做详谈,我也想说说的是与版本一同发布的,也是很容易被忽略的社区合作倡议 GAMMA


GAMMA 是 Gateway API Mesh Management and Administration 的简写,这个计划是 Gateway API 子项目中的一个专用工作流。这个小组的目标是调研、设计和跟踪 Gateway API 资源、语义和其他与服务网格技术和用例相关的组件。此外,小组还努力倡导服务网格项目的 Gateway API 实现之间的一致性,无论使用何种技术栈或者代理。


可能你会有疑问如此简单一个倡议,有什么特别?有两点:


  • 规范的参与:这个倡议由 SIG Network(Gateway API 所在的 Kubernetes SIG)与服务网格社区共同发起,服务网格社区有来自 Cilium Service Mesh、Consul、Istio、Kuma、Linkerd、SMI、NGINX Service Mesh 和 Open Service Mesh 的代表。SMI 与其他几个不同,它是服务网格的规范 API,并非是实现,Gateway API 也一样。

  • 面向东西向流量:小组的首个工作探索使用 Gateway API 处理东西向流量已经开始。东西向流量,也就是服务网格中服务到服务的流量。


可见,服务网格部分 API 的统一将迈进一步,且成为 Kubernetes 原生 API 的一员。当然现在还言之过早,还需看各个厂商的跟进程度。


接下来,我们分别从规范,以及当前的实现两个角度进行分析。

规范

SMI 与 Gateway API 一样都是规范,前者用于服务网格,而后者用于网关。但二者在流量规范的部分存在明显重叠(见下图中红色的部分),流量规范可以可以理解为流量标识(traffic identify)。流量标识作为流量管理的关键,将流量标识之后才能进行流量路由、分流、限流等操作。


SMI issue 249 发起了讨论,关于 SMI 能否使用 Gateway API 的流量规范,将精力集中在服务网格的规范中。


只能说 Gateway API 作为 Kubernetes 的原生 API,有着更强的说服力,其他服务网格厂商更容易接纳。


已经对 SMI 和 Gateway API 有了解的同学,可以直接跳过规范的介绍。

服务网格的规范 SMI

SMI(Service Mesh Interface) 首次登场在 2019 年,并于 2020 年加入 CNCF。


开放服务网格 Open Service Mesh 如何开放一文中曾介绍过 SMI,有兴趣的可以浏览各个 API 的说明及示例。


SMI 是服务网格的规范,重点关注在 Kubernetes 上运行的服务网格。它定义了一个可以由各种供应商使用的通用标准。允许最终用户的标准化和服务网格技术提供商的创新。SMI 实现了灵活性和互操作性,并涵盖了最常见的服务网格功能。


SMI 提供了 Kubernetes 服务网格的标准接口、常见服务网格场景的基本功能集、支持服务网格新功能的灵活性,以及服务网格技术生态的创新空间。


SMI 的目标是将概念与实现隔离开来,像软件开发过去一直做的那样,将复杂的东西分层抽象。


SMI 规范的最新版本是 0.6.0,覆盖了常见的流量访问控制、遥测、管理等基础服务网格能力。与规范对应的是 API,各个网格供应商基于该 API 进行实现。


Kubernetes Gateway API

Kubernetes Gateway API是由SIG-NETWORK 社区管理的开源项目,是一种规范,不提供实现。Gateway API 被认为是 Kubernetes Ingress API 的继任者,在 2019 年的Ingress 革命中首次被提出,并在 2020 年 11 月发布了第一个版本。



Gateway API 是一系列资源的集合,相比 Ingress API,Gateway API 最大的进步就是将流量规范独立成 API,大大提升了扩展性和灵活性。目前提供了 HTTPRouteTCPRouteUDPRouteTLSRoute 规范来匹配特定协议的规则。


流量规范独立之后,网关的实现、基础设施的管理以及流量路由的定义得到了解耦合,这得益于 Gateway API 面向角色的 API 设计:


  • 厂商实现了 Gateway API 并定义了自己 GatewayClass 类型,一系列的实现可供选择。

  • 集群管理员安装 Gateway API 的实现,部署跨命名空间的共享网关实例,或者命名空间独享的网关实例。如下图,集群管理员部署了跨 storesite 命名空间的网关 foo

  • 开发人员创建 HTTPRoute 资源将流量路由到指定的后端服务。


现有的流量规范

这里主要讨论的是服务网格中所面对的东西向流量,部分代码片段来自探索使用 Gateway API 处理东西向流量


从代码片段不难看出,几乎各家都有各自特别的实现。

SMI TrafficSplit

SMI 的 TrafficSplit 定义了流量与后端服务(service)的映射关系(路由)。通过 serviceClusterIP 进行流量的匹配,然后进一步使用 HTTPRouteGroup 对 HTTP 流量进行匹配。并且,服务的映射限制在同一个命名空间下。


比如下面示例将访问 service website 的全部 Firefox 流量路由到 website-v2 服务。


SMI 的实现 osm 会穷举出 spec.service 上指定的 service 的所有 FQDN。


kind: TrafficSplitmetadata:  name: ab-testspec:  service: website  matches:  - kind: HTTPRouteGroup    name: ab-test  backends:  - service: website-v1    weight: 0  - service: website-v2    weight: 100---kind: HTTPRouteGroupmetadata:  name: ab-testmatches:- name: firefox-users  headers:    user-agent: ".*Firefox.*"
复制代码

Istio VirtualService

VirtualService 中的流量匹配使用了 hosts,进一步通过一些基于协议的规则进行匹配。不同的是,协议规则的匹配不是通过独立的 CRD 来维护的,而是耦合在 VirtualService中。


spec:  hosts:  - reviews.prod.svc.cluster.local # could also be just "reviews"  http:  - match:    - uri:        prefix: "/frontpage"    route:    - destination:        host: frontpage.prod.svc.cluster.local
复制代码

Kuma TrafficRoute

从配置上可以看出流量的匹配是通过 serviceClusterIP 实现的。


spec:  sources:    - match:        kuma.io/service: backend_default_svc_80  destinations:    - match:        kuma.io/service: redis_default_svc_6379  conf:    http:    - match: …
复制代码

Cilium CiliumEnvoyConfig

与 Kuma 一样,通过 serviceClusterIP 进行流量匹配。但不同的是,提供了跨命名空间的流量路由。


spec:  services:  - name: httpbin    namespace: default    listener: envoy-lb-listener  backendServices:  - name: echo    namespace: default  resources: …
复制代码

Consul ServiceRouter

使用 ServiceRouter 资源名(web)作为 service 名,然后通过其 ClusterIP 进行流量匹配。


apiVersion: consul.hashicorp.com/v1alpha1kind: ServiceRoutermetadata:  name: webspec:  routes:    - match:        http:          pathPrefix: /admin      destination:        service: admin
复制代码

Linkerd ServiceProfile

ServiceProfile 将名字与请求的 Host 头进行匹配。然后 routes 下挂不同的 endpoint 定义(如 /admin/store ),在 endpoint 的粒度上进行 HTTP 协议属性的匹配、超时、重试等策略的配置。


apiVersion: linkerd.io/v1alpha2kind: ServiceProfilemetadata:  name: webapp.my-service-namespace.svc.cluster.localspec:  routes: …
复制代码

未来的设计

在看未来的可能设计之前,先看下 Kubernetes Gateway API 如何完成流量匹配的:


apiVersion: gateway.networking.k8s.io/v1beta1kind: HTTPRoutemetadata:  name: my-route  namespace: gateway-api-example-ns2spec:  parentRefs:  - kind: Gateway    name: foo-gateway    namespace: gateway-api-example-ns1  hostnames:  - foo.example.com  rules:  - backendRefs:    - name: foo-svc      port: 8080
复制代码


HTTPRoute 的定义来看,存在着两个映射(这里的映射,也可以看做附着点):


  • 与<u>网关实现</u>(foo-gateway.gateway-api-example-ns1)的映射(通过 parentRefs 实现),也就是说将流量匹配规则写入到哪个网关实例。

  • 与<u>服务</u>(foo-svc:8080)的映射(通过 hostnames 实现)。


通过 HTTPRoute 上的附着点,将通过网关实现进入的流量,与后端服务进行关联。先通过 spec.hostnames 进行流量的匹配,然后再由 spec.rules 中的匹配规则完成协议属性的匹配。HTTP 协议可以使用 methodpath、参数、请求头进行匹配,完成 7 层的路由。

东西向流量

在东西向流量的场景,需要实现:


  • 与<u>网格实现</u>的映射,将流量匹配规则写入到某种网格的 sidecar 中。

  • 与<u>服务</u>的映射,如何将进入到网格 sidecar 流量与目标服务(网格内的服务,或者网格外的服务)进行匹配。


因此需要一种设计或者 CRD 来承载如上的关系,截止发稿时目前在探索使用 Gateway API 处理东西向流量中已经有 5 种方式来实现,有兴趣的同学可以了解一下。

总结

还是那句话,最终会使用何种方式,都为时尚早。


但已知的是,目前社区也意识到服务网格是实现上的分裂,而未来服务网格的标准有可能全部或者部分以 Kubernetes 原生 API 的方式存在。如果是后者,我认为 SMI 会有走出来的可能。正如在开放服务网格 Open Service Mesh 如何开放中,谈及较多的标准开放关乎着生态的发展、创新、扩展性和灵活性。


发布于: 2022 年 07 月 30 日阅读数: 56
用户头像

张晓辉

关注

大胆尝试,小心求证 2018.04.09 加入

胡说八道

评论

发布
暂无评论
SMI 与 Gateway API 的 GAMMA 倡议意味着什么?_Kubernetes_张晓辉_InfoQ写作社区