监听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())
}
一开始运行时结果如下
删除资源
可以看到收到了删除的通知,也能看到收到 1分钟自动同步资源数据
新增资源
可以看到收到了 新增的通知,所以 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分钟就能接收到变更信息。