背景
需要監聽K8s中CRD資源的變動, 做出相應的處理, 需要針對 CRD資源建立informer
實現
dynamicClient 是 創建的K8s的client, 這里使用的是 Unstructured 接収的CRD的結果,
加工的時候使用了convertUnstructuredProject
加工了一下, convertUnstructuredProject 實現下面提供
// 創建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)// 創建informerif 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
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
}