opensergo / opensergo-control-plane

Universal cloud-native microservice governance control plane (微服务治理控制面)
Apache License 2.0
35 stars 23 forks source link

Add extension mechanism for CRDMetadata registry | 新增扩展机制,支持注册自定义的 CRDMetadata #15

Open sczyh30 opened 1 year ago

sczyh30 commented 1 year ago

Add extension mechanism for CRDMetadata registry, so that we could register CRDMetadata outside the control plane pkg.

Related code: https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/crd_meta.go


新增扩展机制,支持注册自定义的 CRDMetadata,以便其他 control plane 能够更方便地扩展使用 OpenSergo 控制面模块。

shawnh2 commented 1 year ago

请问这个扩展机制期望实现的效果是怎么样的呢?

jnan806 commented 1 year ago

请问这个扩展机制期望实现的效果是怎么样的呢?

@ShawnHXH

当 OpenSergo Control Plane 接收到 OpenSergoClient 发起 subscribe 自定义 CRD 资源的请求时,OpenSergo Control Plane 对 K8s 中的 资源 addWatch 时,能够找到 对应自定义CRDMetadata,即 在 AddWatch 方法内部调用的 GetCrdMetadata` 方法能够找到对应的 自定义 CRDMetadata。

AddWatch 方法内部内部调用 GetCrdMetadata` 代码位于: https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/k8s_operator.go#L173

GetCrdMetadata 方法位于 https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/crd_meta.go#L75-L79

GetCrdMetadata 方法能够找到 对应的 自定义 CRD 信息,的前提是提前向 crdMetadataMap 缓存 存入相关 CRDMetadata.

crdMetadataMap 缓存位于: https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/crd_meta.go#L56-L73

因此,最终效果就是,将 OpenSergo 自身不支持的、用户自定义的 CRDMetadata 注册 至crdMetadataMap 缓存。 然后在 OpenSergoClient 发起 subscribe 请求时,OpenSergo Control Plane 能 在 crdMetadata 缓存中够找到对应的 CRDMetadata 对应的资源信息并且返回。

PS: 自定义的 CRDMetadata 的缓存 设计时可以与crdMetadataMap 区分开,只需要在上面提到的 GetCrdMetadata方法 能够找到、并且 OpenSergo Control Plane 能够如期实现 自定义 CRD 资源的 订阅效果即可。

jnan806 commented 1 year ago

@ShawnHXH Are you interested in contributing it ? 😃

shawnh2 commented 1 year ago

Sure, please assign it to me.

shawnh2 commented 1 year ago

Hi, 我阐述一下初步的实现思路,若有不妥请指正。

GetCrdMetadata 方法不只在 KubernetesOperator.AddWatcher 中调用,在 KubernetesOperator.RegisterWatcher 方法中也有调用:

https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/k8s_operator.go#L120-L139

也就是说在 ControlPlane.handleSubscribeRequest 之前,自定义的 CRDMetadata 就要被注册。

考虑到上述 handler 是在 NewControlPlane 时创建,并按注册顺序执行:

https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/control_plane.go#L37-L45

https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/transport/grpc/server.go#L143-L149

所以可以在 ControlPlane.handleSubscribeRequest 这个 handler 注册之前,再注册一个用于检测自定义 CRDMetadata 的 Handler,其基本功能如下:

  1. 检查 SubscribeTargetKind 是否为 OpenSergo 预定义的 metadata,若是则跳过
  2. 若不是,则新建一个 CRDMetadata 并存储

这里规定 crdMetadataMap 是存储 OpenSergo 预定义的 CRDMetadata,然后再另创建一个全局 map 变量存储自定义的 CRDMetadata

这样的话,基本需求即可实现。

但是,我还有一个问题:CRDMetadata 结构体是由两个字段组成的,其中第一个字段可以使用 SubscribeTarget.Kind,但第二个字段该如何初始化呢?

https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/crd_meta.go#L25-L29

https://github.com/opensergo/opensergo-control-plane/blob/91ef7e92e2745c646f294f248c5c4249ef488af2/pkg/controller/crd_meta.go#L23

jnan806 commented 1 year ago

Hi, 我阐述一下初步的实现思路,若有不妥请指正。

cc @sczyh30 PTAL