Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Kitex support xDS Protocol #461

Closed
2 of 3 tasks
CoderPoet opened this issue May 20, 2022 · 5 comments
Closed
2 of 3 tasks

Proposal: Kitex support xDS Protocol #461

CoderPoet opened this issue May 20, 2022 · 5 comments
Labels
proposal A proposal need to discuss and will do implementation.

Comments

@CoderPoet
Copy link
Member

CoderPoet commented May 20, 2022

背景

希望 Kitex 能够原生支持 xDS 协议 ,让 Kitex 服务能够以 Proxyless 的模式被服务网格统一纳管,从而丰富网格数据面部署架构形态,让用户可以在不同场景下有更多更适合特定场景的部署形态选择

目标

  • 完成 Kitex 对接 xDS 之后整体架构形态设计
  • 完成 Kitex 框架治理能力如何适配 xDS 模型的概要设计

设计介绍

整体架构

image

整体主要有几个模块组成:

  • Control Plane:控制面,负责管理数据面并基于 xDS 协议下发治理规则
  • Kitex Application:Kitex 内部整体主要分为两层
    • xDS 层:
      • xDS Client:封装基于 xDS 协议与控制面交互逻辑
      • xDS Resource Manger:管理 xDS 各协议资源的缓存,并对外提供发布订阅能力
    • 治理能力层:基于框架提供的治理能力拓展机制,来适配 xDS 模型,实现各种数据面治理能力

框架治理能力适配

为了对接治理能力,框架需要做的适配包括以下几部分:

  • 添加 RouterMW,顺序在内置中间件的第一位(动态路由后才能确定之后的配置)。
  • 扩展 Resolver 接口实现 XdsResolver,判断服务发现类型,基于 eds 获取实例信息。
  • 扩展 LoadBalancer 接口实现 XdsLoadbalancer,根据 cds 动态调整负载均衡策略。

各种治理能力适配思路如下

1. 服务注册

Istio 虽然本身不提供服务注册中心,但是内部维护了统一的服务模型和服务注册表,并且支持集成两种类型的服务注册中心 Provider

  • Kubernetes:基于 K8S APIServer List-Watch ,注册并发现 Kubernetes 上的服务
  • External:注册并发现外部服务,其中外部服务以 ServiceEntries 的形式定义,可以直接 ServiceEntry CRD 描述,也可以通过 MCP-over-xDS 的方式,以外部数据源的方式注册进来

因此,我们在该方案中无需去设计并实现一套服务注册流程了,只需要直接去对接现有的服务注册中心即可。

2. 动态路由

流程大致如下所示:
image

  1. 增加一个 xDS Router MW 来负责 Pick Cluster(路由),watch 目标服务的 LDS 及 RDS
  2. 感知 LDS 变化,并提取目标服务的 LDS 中的 Filter Chain 及其 inline RDS
  3. 感知 RDS 变化,根据 VirtualHost 和 ServiceName 来匹配(支持前缀、后缀、精确、通配),获取目标服务的路由配置
  4. 遍历处理匹配到的 RDS 中的路由规则,路由规则主要分为两部分(参考:路由规范定义):
  5. Match(支持前缀、后缀、精确、通配等),目前版本我们支持以下两种即可:
    1. Path(必须项):从 rpcinfo 提取 Method进行匹配
    2. HeaderMatcher(可选项):可自定义需要匹配的元数据,比如 metainfo 内的 key-value。
  6. Route:
    1. Cluster:标准 Cluster
    2. WeightedClusters(权重路由):MW 内根据权重来选择 cluster
    3. 将选择到的 Cluster 写入 EndpointInfo.Tag,用于之后的服务发现。

3. 服务发现

基于 Kitex 的 Resolver 接口,拓展一个 XDSResolver 来进行服务发现。

  • 根据 RDS 找到对应的 CDS (Pick Cluster)之后,进入 Resolve 阶段,通过根据 CDS 获取对应的 Cluster 配置,包括负载均衡策略、熔断等。之后拉取 EDS 资源以获取实例信息,并根据对应的 LB 策略,pick 出最终的一个 Endpoint。

服务发现类型包括以下几种:

  • Static:直接返回实例的地址
  • Static DNS:数据面需要执行 DNS 解析,以获得所有的实例信息。(异步、周期性地解析)
  • Logical DNS:执行 DNS 解析,只有当需要建立连接时才使用返回实例信息中的第一个。static DNS 的返回结果是完整的实例信息,当两次的结果不同,则需要清理连接。而 logic DNS 则会维持连接,直至被回收。
  • EDS:与控制面交互,发送 eds 请求,以获得实例信息。

4. 负载均衡

Lb policy 包含在 CDS 内,所以 lb 策略的变化是在动态路由选定 cluster 之后获取并应用的。
Kitex 支持自定义 LoadBalancer,实际上就是根据lb策略,从服务发现获得的实例列表内选取一个实例进行调用。

type Loadbalancer interface {
   GetPicker(discovery.Result) Picker // 之后添加入参ctx
   Name() string // unique key
}

如果希望动态调整 lb 策略,需要扩展一个 XDSLoadBalancer 。
在 GetPicker 的实现内完成 lb 策略的获取 (CDS),及不同策略的实现。

5. 超时控制

根据 RDS 中的 timeout 配置来动态调整 RPC Timeout Middleware 的 RPCInfo 中的超时时间即可,实现方式:

  1. xdsRouterMW 内获取到 timeout 配置,设置到 rpcinfo 的 config 中,之后会被用于请求的超时时间设置。

6. 熔断器

Istio 支持的熔断配置相较于 Kitex 会更丰富些,除了异常检测之外,还额外支持对连接池的控制,并且每种熔断策略支持的可配置项也非常完备

我们这期先支持基础的异常检测熔断策略,大致流程如下:

  1. 在 xDS Router MW 中,我们完成 Pick Cluster 的同时,也会拿到相应目标 Cluster 的熔断策略,比如连续请求错误个数(这期我们只考虑异常检测这种熔断策略)
  2. 启用熔断,并调用 CBSuite 的 UpdateServiceCBConfig 和 UpdateInstanceCBConfig 来动态更新 Key 的阈值

7. 重试

RDS 中会携带 retry policy 规则,Kitex 可以根据这个动态调整其客户端重试策略

@Jacob953
Copy link
Contributor

Hi, @CoderPoet! I am interested in this proposal, is there anything I could help with?

@CoderPoet
Copy link
Member Author

Hi, @CoderPoet! I am interested in this proposal, is there anything I could help with?

Very welcome, I have drawn you into the working group, we will dismantle some tasks later!

@dongpoge
Copy link

Istio 服务发现是基于 Kubernetes 实现的.
Istio 控制面中,Pilot 组件负责管理服务网格内部的服务和流量策略。Pilot 将服务信息和路由策略转换为 xDS 接口的标准数据结构,下发到数据面的 Envoy.
个人理解,如果只是简单的应用开发,其实不用考虑 xDS 协议底层到底做了些什么,“应用” 和 “网络” 做到解耦。过不过kitex 能从底层支持 xDS 协议,是最好不过了,这样更贴近“云原生”,在相关场景下的应用会更广泛。

@CoderPoet
Copy link
Member Author

Istio 服务发现是基于 Kubernetes 实现的. Istio 控制面中,Pilot 组件负责管理服务网格内部的服务和流量策略。Pilot 将服务信息和路由策略转换为 xDS 接口的标准数据结构,下发到数据面的 Envoy. 个人理解,如果只是简单的应用开发,其实不用考虑 xDS 协议底层到底做了些什么,“应用” 和 “网络” 做到解耦。过不过kitex 能从底层支持 xDS 协议,是最好不过了,这样更贴近“云原生”,在相关场景下的应用会更广泛。

嗯嗯,对的,目的就是为了丰富网格数据面部署架构形态,让用户可以在不同场景下有更多更适合特定场景的部署形态选择

另外稍微补充下 Kubernetes 只是 istio 的服务注册及发现的其中一种,并作为默认的 provider 存在,其实还可以对接外部注册中心的哈

@GuangmingLuo
Copy link
Member

目前所有功能基本完成,详见文档,用户如果有问题欢迎提交 Issue 反馈:https://www.cloudwego.io/zh/docs/kitex/tutorials/advanced-feature/xds/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal A proposal need to discuss and will do implementation.
Development

No branches or pull requests

6 participants