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

Pixiu Control Plane Support Service Mapping #485

Open
AlbumenJ opened this issue Sep 8, 2022 · 24 comments
Open

Pixiu Control Plane Support Service Mapping #485

AlbumenJ opened this issue Sep 8, 2022 · 24 comments
Assignees

Comments

@AlbumenJ
Copy link
Member

AlbumenJ commented Sep 8, 2022

What happened:

What you expected to happen:

How to reproduce it (as minimally and precisely as possible):

Anything else we need to know?:

@mark4z
Copy link
Member

mark4z commented Sep 8, 2022

I’m working on it

@AlbumenJ
Copy link
Member Author

AlbumenJ commented Sep 8, 2022

映射的逻辑是提供一个 com.example.DemoInterface => demo-application 的查找逻辑

涉及的接口样例如下:
set(interfaceName string, appName string)
get(interfaceName string) List
watch(interfaceName string) Obserable

需要定义新的 proto,绑定在和 xds 同样的 grpc Chanel

@yqxu
Copy link
Contributor

yqxu commented Sep 8, 2022

I’m working on it

@mark4z
Copy link
Member

mark4z commented Sep 13, 2022

对于基本的服务网格体系,首选的也是目前可以优先实现的选项是存储至k8s的注册中心。对此唯一的方式是创建一条该类型的CRD(k8s不允许执行操作其集群的etcd),然后自定义controller,通过informer来监听资源变动,大部分代码都可以用工具生成。

@mark4z
Copy link
Member

mark4z commented Sep 13, 2022

借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ

@AlbumenJ
Copy link
Member Author

借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ

control pannel 缓存就可以,数据量不会特别大

@mark4z
Copy link
Member

mark4z commented Sep 14, 2022

借助目前xds的渠道可以较为简单地推送至各个dubbo服务,借助CRD可以较为简单地实现com.example.DemoInterface级别的增量,但内部app name list的增量,直观的方式是由control pannel缓存当前客户端的当前列表,但对control pannel压力很大,要考虑这个级别的增量是否是必要的。cc @AlbumenJ

control pannel 缓存就可以,数据量不会特别大
okay

@mark4z
Copy link
Member

mark4z commented Sep 14, 2022

初版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: { }

@chickenlj
Copy link

接下来需要继续定义控制面与数据面的通信协议。

  1. 上报映射关系。数据面会上报 interface + app 到控制面。
  2. 查询&推送映射关系。数据面会基于interface主动查询映射关系数据;数据面会基于interface订阅映射关系数据,因此协议要具备推送能力。

特殊逻辑:

相同的接口可能有多条不同的映射关系,如 :
interface -> app1
interface -> app2
对于这种情况,可以存储为多条 CR,但控制面内部要能基于 interface 做聚合

@mark4z
Copy link
Member

mark4z commented Sep 15, 2022

接下来需要继续定义控制面与数据面的通信协议。

  1. 上报映射关系。数据面会上报 interface + app 到控制面。

  2. 查询&推送映射关系。数据面会基于interface主动查询映射关系数据;数据面会基于interface订阅映射关系数据,因此协议要具备推送能力。

特殊逻辑:

相同的接口可能有多条不同的映射关系,如 :

interface -> app1

interface -> app2

对于这种情况,可以存储为多条 CR,但控制面内部要能基于 interface 做聚合

CRD可以直接聚合的,上面的定义能看到appNane是个列表,比较复杂的部分是如何做增量下发

@mark4z
Copy link
Member

mark4z commented Sep 18, 2022

@mark4z
Copy link
Member

mark4z commented Sep 25, 2022

一个简单的上报接口,上报的内容在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{
}

@mark4z
Copy link
Member

mark4z commented Sep 25, 2022

服务映射的相应,定义单个即可,真实的响应会是数组的形式

syntax = "proto3";

package envoy.config.core.v3;
import "envoy/config/core/v3/base.proto";

message ServiceNameMapping{
  string interfaceName = 1;

  repeated string applicationNames = 2;
}

@mark4z
Copy link
Member

mark4z commented Oct 16, 2022

目前遇到的问题是,新增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资源定义。

@mark4z
Copy link
Member

mark4z commented Oct 16, 2022

使用方案1

@MasterKenway

@MasterKenway
Copy link
Contributor

使用方案1

@MasterKenway

了解

@mark4z
Copy link
Member

mark4z commented Oct 26, 2022

上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ

@AlbumenJ
Copy link
Member Author

上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ

上报的数据可以基于 namespace 隔离存储,下发的时候也可以支持跨 namespace 订阅。
可以修改下接口,添加 namespace 参数,订阅的时候不指定 namespace 默认就是当前 namespace 获取。

@mark4z
Copy link
Member

mark4z commented Nov 12, 2022

客户端已经可以成功使用delta拉取数据
image

@mark4z
Copy link
Member

mark4z commented Nov 16, 2022

上报部分也已经完成,剩余一些Bug和优化工作

@MasterKenway
Copy link
Contributor

上报时的namespace如何处理?下发时的namespace如何处理也是一个问题 cc @AlbumenJ

上报的数据可以基于 namespace 隔离存储,下发的时候也可以支持跨 namespace 订阅。 可以修改下接口,添加 namespace 参数,订阅的时候不指定 namespace 默认就是当前 namespace 获取。

ServiceMetadata 是否也是采用同样的处理方式?

@mark4z
Copy link
Member

mark4z commented Nov 29, 2022

上报时的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一个仓库,意义不大。

@mark4z
Copy link
Member

mark4z commented Dec 18, 2022

指定namespace的方式已经完成,形式为 a.b.c.hellowrold|dubbo-demo订阅来自dubbo-demo的对应service,a.b.c.hellowrold| 或者 a.b.c.hellowrold默认订阅订阅者所在的namespace

@mark4z
Copy link
Member

mark4z commented Dec 18, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

No branches or pull requests

5 participants