监听k8s所有的 Deployment 资源

package main

import (
	"context"
	"fmt"
	v1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/util/json"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"time"
)

func main() {
	config, err := clientcmd.BuildConfigFromFlags("", "D:\\development\\goWorkSpace\\transport\\cmd\\deploy\\config")
	if err != nil {
		fmt.Println(err)
		return
	}
	client, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Println(err)
		return
	}
    # defaultResync 参数在 NewSharedInformerFactoryWithOptions 函数中是用来设定资源重新同步(resync)的默认时间间隔。在 Kubernetes 的客户端库 client-go 中,Informer 是一种用于高效监听和缓存 API 资源变化的组件。它通过定期与 Kubernetes API 服务器同步资源列表来确保本地缓存与集群状态保持一致,即使错过了某些事件通知。
    #重同步(Resync): 默认的重同步间隔定义了Informer多久强制与API服务器同步一次资源列表,即使在此期间没有观察到任何资源变化事件。这对于处理潜在的通知丢失、恢复因网络问题导致的不一致状态非常有用。简而言之,这是一种确保数据最终一致性的机制。
    #时间间隔(defaultResync): time.Duration 类型的 defaultResync 参数指定了这个默认的重同步周期。例如,如果你设置为 5 * time.Minute,则每五分钟Informer会自动请求API以获取最新的资源列表并与本地缓存对比,进行必要的更新
    #自定义重同步: 注意,在创建具体的 Informer 时,还可以针对每个资源类型覆盖这个默认的重同步间隔,这就是为什么在代码中还提供了 customResync 字典来存储特定资源类型的自定义重同步时间。
    #通过合理设置 defaultResync,可以在保持数据新鲜度与减少API服务器负载之间找到平衡。对于资源变化频繁且对实时性要求高的场景,可能需要较短的重同步间隔;而对于相对静态的资源,较长的间隔有助于减轻集群负担。

    # 当 defaultResync 设置为 0 时,这意味着不启用默认的自动重同步功能。换句话说,Informer 不会按照固定的时间间隔主动与 Kubernetes API 服务器同步资源列表,除非有明确的资源变动事件触发更新。

    # 下面这个意思是说 每隔10秒资源重新同步
	informerFactory := informers.NewSharedInformerFactory(client, time.Second*10)
	informer := informerFactory.Apps().V1().Deployments().Informer()
	informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			object := obj.(*v1.Deployment)
			marshal, _ := json.Marshal(object)
			fmt.Println("AddFunc", string(marshal))
		},
		UpdateFunc: func(old, new interface{}) {
			object := old.(*v1.Deployment)
			marshal, _ := json.Marshal(object)
			fmt.Println()
			fmt.Println("UpdateFunc", string(marshal))
		},
		DeleteFunc: func(obj interface{}) {
			fmt.Println("DeleteFunc")
		},
	})
	informer.Run(context.Background().Done())

}

监听指定命名空间的 Deployment 资源

package main

import (
	"context"
	"encoding/json"
	"fmt"
	v1 "k8s.io/api/apps/v1"
	"k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/cache"
	"k8s.io/client-go/tools/clientcmd"
	"time"
)

func main() {
	config, _ := clientcmd.BuildConfigFromFlags("", "D:\\development\\goWorkSpace\\transport\\cmd\\deploy\\config")
	clientset, _ := kubernetes.NewForConfig(config)

	options := informers.NewSharedInformerFactoryWithOptions(clientset, time.Minute*1, informers.WithNamespace("default"))
	informer := options.Apps().V1().Deployments().Informer()
	informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			object := obj.(*v1.Deployment)
			marshal, _ := json.Marshal(object)
			fmt.Println("AddFunc", string(marshal))
		},
		UpdateFunc: func(old, new interface{}) {
			object := old.(*v1.Deployment)
			marshal, _ := json.Marshal(object)
			fmt.Println()
			fmt.Println("UpdateFunc", string(marshal))
		},
		DeleteFunc: func(obj interface{}) {
			object := obj.(*v1.Deployment)
			marshal, _ := json.Marshal(object)
			fmt.Println("DeleteFunc", string(marshal))
		},
	})
	informer.Run(context.Background().Done())
}
一开始运行时结果如下

image.png

删除资源

image.png
可以看到收到了删除的通知,也能看到收到 1分钟自动同步资源数据
image.png

新增资源

image.png
image.png
可以看到收到了 新增的通知,所以 defaultResync 并不会影响 实时的通知,可以得出如下结论:

结论

defaultResync 参数代表了Informer在没有其他配置干预的情况下,与Kubernetes API服务器进行资源列表全量同步的默认时间间隔。当你设置 defaultResync 为1分钟时,这意味着如果没有更具体的自定义同步策略或其他因素影响,Informer将会每1分钟主动请求API服务器来检查资源是否有变化,并更新其本地缓存。
然而,这并不直接意味着如果Kubernetes资源在这1分钟内发生变化,你的程序需要等待整整1分钟后才能收到通知。实际上,Informer的设计不仅仅是依赖于这个全量同步(resync)来获取更新,它还依赖于基于事件的机制来实现近乎实时的更新
当资源发生变化时(如创建、更新或删除),Kubernetes API服务器会通过Watch机制即时推送给监听该资源的Informer,这样你的程序几乎可以立即(网络延迟范围内)通过之前注册的事件处理器(如 AddFunc, UpdateFunc, DeleteFunc)收到这些变更通知。
总结来说,defaultResync 设置为1分钟意味着至少每分钟Informer会做一次全量检查以确保数据的最终一致性,但这不影响它通过实时事件机制在资源变化时迅速得到通知。所以,如果你的程序已经正确设置了事件处理器,资源变化后通常无需等待1分钟就能接收到变更信息。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐