概要
- 什么是
SharedInformer - 演示
SharedInformer监听资源变化的过程
什么是SharedInformer
首先先要解释下Informer。 在k8s中,需要保证controller中持有object的准确信息。为了实现这一点,就需要与apiserver进行通讯,来保证状态一致。Informer就是用来完成这个功能的。
前置提到的Reflector, Indexer,DeltaFIFO 都属于Informer的一部分。
每个controller都持有一个Informer,如果每个Informer的cache都是独占的,无疑会造成很大的性能损耗。为了提升性能,降低损耗。 这里使用了SharedInformer。
详情 shared informer
主要作用
- 缓存资源的最新数据。创建Indexer/Clientset(通过listerwatcher)/DeltaFIFO/Controller(包含Reflector),将各个资源连接起来。
- 根据资源对象的变化事件来通知我们注册的事件处理方法
创建
- NewSharedIndexInformer:创建Informer的基本方法
- NewDeploymentInformer:创建内建资源对象对应的Informer的方法
- NewSharedInformerFactory:通过map存储创建过的Informer,达到复用共享的目的。
type sharedIndexInformer struct {
indexer Indexer
controller Controller
processor *sharedProcessor
cacheMutationDetector MutationDetector
listerWatcher ListerWatcher
objectType runtime.Object
resyncCheckPeriod time.Duration
defaultEventHandlerResyncPeriod time.Duration
clock clock.Clock
started, stopped bool
startedLock sync.Mutex
blockDeltas sync.Mutex
watchErrorHandler WatchErrorHandler
transform TransformFunc
}
实践
通过如下代码,创建一个informmer,观察资源的变化情况。将要进行如下操作
- 执行程序,预期:观察到现有资源的add
- 创建pod,预期:观察到add和update
- 删除pod,预期:观察到delete和update
代码
package main
import (
"fmt"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
//create config
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
if err != nil {
panic(err)
}
//create client
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err)
}
//create informer in namespace "default"
//factory := informers.NewSharedInformerFactory(clientset, 0) // in all namespace
factory := informers.NewSharedInformerFactoryWithOptions(clientset, 0, informers.WithNamespace("default"))
// 拿到Pod对应的informer,注册EventHandler
// 当Pod发生变化时,会触发EventHandler
// 未注册的handler,不会触发,可以在 `ResourceEventHandler`中看到
informer := factory.Core().V1().Pods().Informer()
//register event handler
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
fmt.Println("add Event")
},
UpdateFunc: func(old, new interface{}) {
fmt.Println("update Event")
},
DeleteFunc: func(obj interface{}) {
fmt.Println("delete Event")
},
})
//start factory
stopCh := make(chan struct{})
factory.Start(stopCh)
// 等待同步完成
factory.WaitForCacheSync(stopCh)
<-stopCh
}
执行结果
如下图,整体执行结果符合预期
参考
Understanding Kubernetes controllers part III – informers – LeftAsExercise