dubbo-go-pixiu
dubbo-go-pixiu copied to clipboard
Pixiu Control Plane Support Service Mapping
What happened:
What you expected to happen:
How to reproduce it (as minimally and precisely as possible):
Anything else we need to know?:
I’m working on it
映射的逻辑是提供一个 com.example.DemoInterface => demo-application 的查找逻辑
涉及的接口样例如下: set(interfaceName string, appName string) get(interfaceName string) List watch(interfaceName string) Obserable<List>
需要定义新的 proto,绑定在和 xds 同样的 grpc Chanel
I’m working on it
对于基本的服务网格体系,首选的也是目前可以优先实现的选项是存储至k8s的注册中心。对此唯一的方式是创建一条该类型的CRD(k8s不允许执行操作其集群的etcd),然后自定义controller,通过informer来监听资源变动,大部分代码都可以用工具生成。
借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ
借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ
control pannel 缓存就可以,数据量不会特别大
借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ
control pannel 缓存就可以,数据量不会特别大 okay
初版CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: servicenamemappings.networking.dubbo.io
spec:
group: networking.dubbo.io
scope: Namespaced
names:
kind: ServiceNameMapping
plural: servicenamemappings
singular: servicenamemapping
shortNames:
- snp
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
description: >-
it's the spec of Service Name Mapping, which is used to map the interface name
to the application name in application discovery.
type: object
properties:
interfaceName:
type: string
applicationName:
type: array
items:
type: string
status:
type: object
# subresources for the custom resource
subresources:
# enables the status subresource
status: { }
接下来需要继续定义控制面与数据面的通信协议。
- 上报映射关系。数据面会上报 interface + app 到控制面。
- 查询&推送映射关系。数据面会基于interface主动查询映射关系数据;数据面会基于interface订阅映射关系数据,因此协议要具备推送能力。
特殊逻辑:
相同的接口可能有多条不同的映射关系,如 : interface -> app1 interface -> app2 对于这种情况,可以存储为多条 CR,但控制面内部要能基于 interface 做聚合
接下来需要继续定义控制面与数据面的通信协议。
上报映射关系。数据面会上报 interface + app 到控制面。
查询&推送映射关系。数据面会基于interface主动查询映射关系数据;数据面会基于interface订阅映射关系数据,因此协议要具备推送能力。
特殊逻辑:
相同的接口可能有多条不同的映射关系,如 :
interface -> app1
interface -> app2
对于这种情况,可以存储为多条 CR,但控制面内部要能基于 interface 做聚合
CRD可以直接聚合的,上面的定义能看到appNane是个列表,比较复杂的部分是如何做增量下发
https://dubbogoproxy.yuque.com/dubbogoproxy/vld1hq/rv5321
一个简单的上报接口,上报的内容在POD生命周期内应当是静态的,项目启动时一次性上报即可。
syntax = "proto3";
package dubbo.config.metadata.v1;
// Provides an service for reporting the mapping relationship between interface => cluster
// the cluster name will be versioned FQDN. such as "demo.default.svc.cluster.local"
service ServiceNameMappingService{
rpc registerServiceAppMapping(stream ServiceMappingRequest) returns (ServiceMappingResponse);
}
message ServiceMappingRequest{
string applicationName = 1;
repeated string interfaceName = 2;
}
message ServiceMappingResponse{
}
服务映射的相应,定义单个即可,真实的响应会是数组的形式
syntax = "proto3";
package envoy.config.core.v3;
import "envoy/config/core/v3/base.proto";
message ServiceNameMapping{
string interfaceName = 1;
repeated string applicationNames = 2;
}
目前遇到的问题是,新增ServiceNameMapping的CRD,有两种方式:
一种方式是fork isito关于自定义CRD的两个repo并修改: https://github.com/istio/api (存储了proto+tag形式的CRD定义,可以生成yaml格式的CRD) https://github.com/istio/client-go (通过前者API生成的Client) 最后通过pilot内部的codegen生成所需的crdcontroller,复用性较好。
另一个种是通过 https://github.com/kubernetes/sample-controller 生成,但是这样集成进pilot会多相当多的冗余代码,并且需要修改由原本生成的代码和CRD资源定义。
使用方案1
@MasterKenway
使用方案1
@MasterKenway
了解
上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ
上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ
上报的数据可以基于 namespace 隔离存储,下发的时候也可以支持跨 namespace 订阅。 可以修改下接口,添加 namespace 参数,订阅的时候不指定 namespace 默认就是当前 namespace 获取。
客户端已经可以成功使用delta拉取数据
上报部分也已经完成,剩余一些Bug和优化工作
上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ
上报的数据可以基于 namespace 隔离存储,下发的时候也可以支持跨 namespace 订阅。 可以修改下接口,添加 namespace 参数,订阅的时候不指定 namespace 默认就是当前 namespace 获取。
ServiceMetadata 是否也是采用同样的处理方式?
上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ
上报的数据可以基于 namespace 隔离存储,下发的时候也可以支持跨 namespace 订阅。 可以修改下接口,添加 namespace 参数,订阅的时候不指定 namespace 默认就是当前 namespace 获取。
@AlbumenJ 对于订阅,通常会使用ads的ResourceNames来指定资源,这里我建议使用形如 a.b.c.hellowrold|dubbo-demo的形式来订阅跨namespace的interface,dubbo-demo即要订阅的namespace。因为ads里要增加字段略微有些复杂,ads的定义在envoy的组织下,需要再fork一个仓库,意义不大。
指定namespace的方式已经完成,形式为 a.b.c.hellowrold|dubbo-demo订阅来自dubbo-demo的对应service,a.b.c.hellowrold| 或者 a.b.c.hellowrold默认订阅订阅者所在的namespace
接入文档 https://dubbogoproxy.yuque.com/dubbogoproxy/vld1hq/srgix1anpmpin444/edit