探索 Gateway API 在 Service Mesh 中的工作机制

探索 Gateway API 在 Service Mesh 中的工作机制

前几天 Gateway API 宣布在 0.8.0 中支持服务网格,这意味着 GAMMAGateway API for Mesh Management and Administration)有了新进展,虽然目前还是实验阶段。去年 6 月 Gateway API 发布 0.5.0 时,我还写了一篇 SMI 与 Gateway API 的 GAMMA 倡议意味着什么?。如今,SMI 作为 sandbox 项目的年度审查已经 过了几个月仍未提交,唏嘘。

废话不多说,我们来看下 0.8.0 下的 Gateway API 如何在 Service Mesh 中工作。

TL;DR

Gateway API 对服务网格的支持仍然是实验阶段,但是已经有厂商跟进(当然也都是实验阶段)。

相比 Gateway API 处理南北向流量将路由绑定到 Gateway 资源 相比,在网格中路由则是与 Service 进行绑定。简单理解成 Service 代理了 Gateway 的角色,不过该 Service 是目标 Service。

Gateway API 中的服务网格

要说服务网格,我们先来看下服务 Service

抽象 Service

Service 中 Kubernetes 中是一个独立的资源,这里说的抽象是从逻辑上进行抽象,抽象成前端和后端两部分。

前端(Frontend)通常就是 Service 的 DNS 名字或者 ClusterIP;后端(Backend)则是通过标签选择器选择的 Endpoint 或者 EndpointSlice

路由与服务

把路由直接绑定到 Service 上,被认为是当下最优的选择。Service 与其他资源的耦合度太高,比如 IP 分配、DNS、端点集合、负载均衡等等,但在目前的网格设计中也是唯一的最优选择,未来会寻求更好的选择,比如 ServiceBinding(见后文)

这样做的好处呢,就是将服务的前后端分别与现在的 xRoute API 中的 parentRefbackendRef 关联,无需引入额外的 API。

不同的时候,在 xRoute API 中的 backendRef 也可以是一个 Service,但是最终在路由请求时,目标还是 Endpoint 或者 EndpointSlice,只不过他们与 parentRef 中的 Service 不是强关联的。

kind: HTTPRoute
metadata:
  name: smiley-route
  namespace: faces
spec:
  parentRefs:
    - name: smiley
      kind: Service
      group: core
      port: 80
  rules:
    ...

如果一个 Service 上配置了多个路由,匹配到多条路由的请求将被拒绝。

请求流程

  1. 客户端发送请求
  2. 网格数据面代理拦截请求
  3. 通过虚拟 IP 地址、DNS 主机名、或者名字来确认流量是属于哪个 Service(不会使用 xRoute 上的 hostname 字段)
  4. 如果 Service 没有配置路由,将使用请求的原始目的地进行转发
  5. 找到匹配的优先级最高(消费者路由高于生产者路由,见下文)的路由进行转发
  6. 如果配置了路由,但都无法匹配,则拒绝请求

路由的命名空间

为什么要提命名空间,是因为路由与服务在相同或者不同命名空间下所代表的含义不同。

同命名空间

路由 smiley-route 与 Service smiley 位于同一个命名空间 faces,该路由上设置了请求超时时间 100ms。这意味着,所有访问 Service smiley (来自任一命名空间下的任一工作负载)并匹配 smiley-route 路由规则的请求,都受该超时配置的影响。

这种路由被称为 生产者路由(Producer Route),影响目标为该服务的所有请求。

kind: HTTPRoute
metadata:
  name: smiley-route
  namespace: faces
spec:
  parentRefs:
  - name: smiley
    namespace: faces
    kind: Service
    group: core
    port: 80
  rules:
    ...
    timeouts:
      request: 100ms

不同命名空间

路由 smiley-route 与 Service smiley 位于不同的命名空间,与上面不同的是,所有访问 Service smiley (来自命名空间 fast-clients 下的任一工作负载)并匹配 smiley-route 路由规则的请求,都受该超时配置的影响。

这种路由被称为 消费者路由(Consumer Route),影响同命名空间下访问木雕服务的所有请求。

kind: HTTPRoute
metadata:
  name: smiley-route
  namespace: fast-clients
spec:
  parentRefs:
  - name: smiley
    namespace: faces
    kind: Service
    group: core
    port: 80
  rules:
    ...
    timeouts:
      request: 100ms

同一 Service 上的多个路由

这里的前提条件是这些路由都位于同一命名空间下,即同为生产者路由,或同为消费者路由。这种情况将会遵循 路由合并规则 多这个路由进行合并,如果要为同一命名空间下的多个工作负载配置不同的消费者路由,目前还无法实现。唯一的

比如下面定义了两个消费者路由 smiley-route-50smiley-route-100

kind: HTTPRoute
metadata:
  name: smiley-route-50
  namespace: fast-clients
spec:
  parentRefs:
  - name: smiley
    namespace: faces
    kind: Service
    group: core
    port: 80
  rules:
    ...
    timeouts:
      request: 50ms
---
kind: HTTPRoute
metadata:
  name: smiley-route-100
  namespace: fast-clients
spec:
  parentRefs:
  - name: smiley
    namespace: faces
    kind: Service
    group: core
    port: 80
  rules:
    ...
    timeouts:
      request: 100ms

路由与策略

之前也写文介绍过 Gateway API 中的策略,有兴趣的可以看一下 一文搞懂 Kubernetes Gateway API 的 Policy Attachment

在网格中策略附加可以非常简单。策略可以应用于任何命名空间中的任何资源,但如果目标位于不同的命名空间中,则它只能应用于来自同一命名空间的请求(跟随消费者路由的逻辑)。

网格一致性测试

首先来看下何为 一致性配置文件

Gateway API 会提供用于一致性测试的配置文件,在运行一致性测试可以选择这些配置文件。然后将一致性结果报告回网关 API 项目并获得认证(例如徽章)。除了测试核心的功能,也可以自主添加厂商的特定实现中的扩展功能进行测试。

这些 Gateway API 的实现会将测试报告提交到 官方仓库的一致性测试报告目录 中,可以作为大家选型时的依据之一。

目前有 HTTPTLSTLSPassthrough(基本上都是根据 xRoute 来进行组织,因此后续也会有 GRPCTCPUDP)。针对服务网格,也提出了 mesh 配置文件

官方博客 中提到 Kuma 2.3+、Linkerd 2.14+、和 Istio 1.16+ 中的 Gateway API 实现已经全部通过 mesh 一致性测试,但截止目前未看到测试报告,估计还在上传中。

(转载本站文章请注明作者和出处乱世浮生,请勿用于任何商业用途)

comments powered by Disqus