K8s client go 创建CRD的informer

背景

需要监听K8s中CRD资源的变动, 做出相应的处理, 需要针对 CRD资源建立informer

实现

dynamicClient 是 创建的K8s的client, 这里使用的是 Unstructured 接収的CRD的结果,

加工的时候使用了convertUnstructuredProject 加工了一下, convertUnstructuredProject 实现下面提供

projectGvk 是 GroupVersionResource , 根据自己的CRD定义

go 复制代码
		// 创建sharedInformerFactory,第二个参数为同步周期,也就是多久从APIServer List一次,并更新到本地缓存
		informer := cache.NewSharedInformer(&cache.ListWatch{
			ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
				return dynamicClient.Resource(projectGvk).List(ctx, options)
			},
			WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
				return dynamicClient.Resource(projectGvk).Watch(ctx, options)
			},
		},
			&unstructured.Unstructured{},
			60*time.Second)
		// 创建informer

		if err != nil {
			log.Error("Failed to create informer", zap.Error(err))
			continue
		}
		// 注册资源事件处理方法
		informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {},
			UpdateFunc: func(oldObj, newObj interface{}) {
				newData, err := convertUnstructuredProject(newObj)
				if err != nil {
					log.Error("Failed to convert unstructured project", zap.Error(err))
				}
				oldData, err := convertUnstructuredProject(oldObj)
				if err != nil {
					log.Error("Failed to convert unstructured project", zap.Error(err))
				}
				if oldData.Generation != newData.Generation {
					fmt.Println("update", newData)
					saveProject(newData, clsuter.Platform)
				}
			},
			DeleteFunc: func(obj interface{}) {
				data, err := convertUnstructuredProject(obj)
				if err != nil {
					log.Error("Failed to convert unstructured project", zap.Error(err))
				}
				fmt.Println("delete", data)
				deleteProject(data, clsuter.Platform)
			},
		})
		// 启动
		stopCh := make(chan struct{})
		log.Info("Starting project informer factory")
		informer.Run(stopCh)
		// 等待父协程处理
		<-ctx.Done()
		close(stopCh)
		log.Info("Shutting down project informer factory")

convertUnstructuredProject的实现 Project 是实现的 runtime.Object 接口的struct

go 复制代码
func convertUnstructuredProject(obj interface{}) (crd *Project, err error) {
	// 将obj转换为*unstructured.Unstructured类型
	u, ok := obj.(*unstructured.Unstructured)
	if !ok {
		fmt.Println("Failed to convert object to *unstructured.Unstructured")
		return
	}

	// 将u对象转换为YourCRDType类型
	crd = &Project{}
	err = runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), crd)
	if err != nil {
		fmt.Println("Failed to convert object to YourCRDType")
		return
	}
	return
}
相关推荐
小Pawn爷7 小时前
1.Docker基础
运维·docker·容器
chinesegf7 小时前
清理docker残留镜像images
运维·docker·容器
小Pawn爷8 小时前
2.Docker的存储
运维·docker·容器
广州中轴线8 小时前
OpenStack on Kubernetes 生产部署实战(十七)
容器·kubernetes·openstack
礼拜天没时间.9 小时前
自定义镜像制作——从Dockerfile到镜像
linux·docker·容器·centos·bash
清云随笔9 小时前
Golang基础
golang
luffy54599 小时前
windows下通过docker-desktop创建redis实例
windows·redis·docker·容器
weixin_404679319 小时前
docker部署ollama
运维·docker·容器
牛奔12 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
不老刘16 小时前
LiveKit 本地部署全流程指南(含 HTTPS/WSS)
golang·实时音视频·livekit