Kuma 通过 KDS(Kuma Discovery Service)进行 Global kuma-cp 和 Zone kuma-cp 的资源交换,以实现跨集群的通信。
在第一节首先会简要说明 KDS 中需要同步的资源,第二节说明 KDS 的实现。
资源
KDS 同步的资源按照资源的流向,可以分为两种类型:
- ZoneToGlobal:区域 cp 到全局 cp 同步的信息。
- GlobalToZone:全局 cp 到区域 cp 同步的信息。
ZoneToGlobal
Dataplane
Dataplane:允许 Zone kuma-cp -> Global kuma-cp,Dataplane 定义了一个数据面 sidecar 代理的配置,spec 包括:
- Network:网络,描述数据面代理的入站和出站地址。
- Metrics: 定义数据面收集的指标。
- Probes:暴露健康检查端口,健康检查配置。
1 | // Dataplane defines a configuration of a side-car proxy. |
DataplaneInsight:表示了数据平面的运行时状态,包括:
- Subscriptions:描述了由数据平面向控制平面创建的 ADS 订阅。
- MTLS:数据平面代理的 mTLS 状态,如证书过期时间,上次证书的生成时间等。
1 | // DataplaneInsight defines the observed state of a Dataplane. |
Egress
Egress:用于定义 Zone Egress。
- Zone:所属的 Zone 名称。
- Network:描述了 Egress 监听的地址和端口。
1 | // ZoneEgress allows us to configure dataplane in the Egress mode. |
EgressInsight:定义了 Zone Egress 的运行时状态,包括:
- DiscoverySubscription:定义了由 Zone kuma-cp 创建的 ADS 订阅。
1 | // ZoneEgressInsight defines the observed state of a Zone Egress. |
Ingress
Ingress:定义了 Zone Ingress。允许 Zone kuma-cp -> Global kuma-cp,和 Global kuma-cp -> Zone kuma-cp,Global kuma-cp 接收 Zone kuma-cp 的 Ingress 资源,并向其他 Zone kuma-cp 同步 Ingress 信息。
- Zone:标识 Ingress 服务于哪个区域。
- Networking:定义了 Zone Ingress 的监听地址和端口,以及公开的地址端口。
- AvailableServices:定义了可以通过该 Zone Ingress 访问的服务,是 Kuma 跨集群通信的基础。
- Tags:服务 tag。
- Instances:给定标签可用的服务实例数量。
- Mesh:给定标签可用的服务实例所属的服务网格名称。
- ExternalService:表明该服务是否为外部服务。
1 | // ZoneIngress allows us to configure dataplane in the Ingress mode. In this |
IngressInsight:定义了 ZoneIngress 的运行时状态。允许 Zone kuma-cp -> Global kuma-cp,和 Global kuma-cp -> Zone kuma-cp,Global kuma-cp 接收 Zone kuma-cp 的 IngressInsight 资源,并向其他 Zone kuma-cp 同步 IngressInsight 信息。
1 | // ZoneIngressInsight defines the observed state of a Zone Ingress. |
GlobalToZone
Global kuma-cp 到 zone kuma-cp 的资源,除了 Ingress 外剩下的均是来自于 Global kuma-cp 策略的更新。
如 CircuitBreaker,FaultInjection,HealthCheck,Retry 等,这里不再详细说明。
KDS
KDS v1
服务定义
在 KDS v1 中,global 和 zone 之间在一个双向 gRPC 流中进行资源同步,KDS 服务定义如下:
1 | service MultiplexService { |
流程
在 zone kuma-cp 和 global kuma-cp 建立连接后:
会创建 Session 对象,并启动两个协程用于读写 gRPC streaming。Session 底层抽象分离了 serverStream 和 clientStream 并实现了基于 buffer 的 streaming,用于表示 global 到 zone 和 zone 到 global 的连接。
接着调用 OnSessionStarted 回调函数,开启两个协程用于表示 server(global kuma-cp)和 client(global kuma-cp)。
server 实现了 xDS 服务器,用于响应客户端的 xDS 请求。
client 在建立时:
- 首先对所有需要从 zone 到 global(ZoneToGlobal)的资源发起 DiscoveryRequest。
- 接收 xDS 响应,并同步资源到缓存中。
server 和 client 所有读写的数据,均从 serverStream 和 clientStream 中读取/发送。
KDS v2
为什么引入 KDS v2
为什么要重新设计 KDS v2,因为 KDS v1 实现非常复杂并且可能存在一些 bug(如 issues #5373)。KDS v2 主要的变化如下:
- 分离 kds 中 zone 和 global 之间流的共用(这引入了复杂性和 bug)。
- 当数据从 zone 同步到 global 时,使用增量更新而不是全量更新。
KDS v1 使用一个双向流从同步 zone 和 global 之间的资源。KDS v2 引入 2 个独立的 RPC 来同步资源来简化逻辑,将简化逻辑和可读性,并且使用增量更新 Delta xDS。
1 | service KDSSyncService { |
KDS v1 zone 向 global 发送 DiscoveryRequest 并等待资源的更新通知。global 将状态存储在缓存中,并在发生变化时发送响应。在 global 到 zone 同步的情况下效果很好,但在大型部署中更多的流量来自从 zone 到 global 的同步。每当有变化时,zone 控制平面需要将所有数据平面资源发送到 global。所以,KDS v2 使用 delta xDS,可以用更高效的方式同步资源。
服务定义
KDS v2 分离出了两个接口,GlobalToZoneSync 和 ZoneToGlobalSync,用于 global 和 zone 之间的资源同步,使用 delta xDS。
1 | // KDSSyncService is a service exposed by the control-plane for the |
流程
GlobalToZoneSync 和 ZoneToGobalSync 在连接开始时,都从 EventBus 订阅了 ZoneWentOffline 事件,接着向 EventBus 发送 ZoneOpenStream 事件(用于通知 HealthCheck 对新的 zone 和 的健康检查),用于结束与 zone 之间的连接(如正常结束,发生错误,健康检查超时)。
在 GlobalToZoneSync 方法中,接着调用 OnGlobalToZoneSyncConnect 回调函数:
- 开启 delta xDS 服务器,用于响应 zone 到 global 对 GlobalToZone 资源的 xDS 请求。
ZoneToGobalSync 方法中,调用 OnGlobalToZoneSyncConnect 回调函数:
- 对所有 ZoneToGlobal 资源发起 DeltaDiscoveryRequest 请求。
- 接收 xDS 响应,并同步资源到缓存中。
其他服务
ZoneWatch
ZoneWatch 订阅 ZoneOpenStream 事件,用于添加活跃的 zone 列表,并通知 zone kuma-cp 下线。
- 每次都会轮询所有的 zone,检查上一次发送 HealthCheck 请求的时间是否超时。
- 如果超时,则会发送 ZoneWentOffline 事件,通知 KDS 服务器终止与 zone kuma-cp 的连接。
GlobalKDSService
Kuma 提供在在 Global Zone 上获取 zone xDS 配置、状态等信息的 API,所以需要通过 GlobalKDSService 收集 zone 的信息,并暴露方法以进行健康检查。