client-go
Basic Usage(without using Shared Informer)
https://pkg.go.dev/k8s.io/client-go@v0.20.0/kubernetes
Listing and getting ConfigMaps
clientset := kubernetes.New(cfg)
resp, err := clientset.CoreV1().ConfigMaps(ns).List(...)
cm, err := clientset.CoreV1().ConfigMaps(ns).Get(...)
Each call to List
or Get
makes a new connection to the API server and reads from etcd. These calls are subject to API Priority and Fairness, rate limits, exponential backoff, etc.
Watching ConfigMap changes
w, err := clientset.CoreV1().ConfigMaps(ns).Watch(...)
for e := range w.ResultChan() {
cm, ok := e.Object.(*corev1.ConfigMap)
switch e.Type {
case watch.Added:
// TODO: handle new ConfigMap
case watch.Modified:
// TODO: handle updated ConfigMap
}
}
And to stop:
w.Stop()
Each call to Watch
opens a long-running connection to the API server, which is closed when you Stop
.
https://pkg.go.dev/k8s.io/client-go@v0.20.0/informers#NewSharedInformerFactoryWithOptions
Instead of using the client directly, you can pass it to a SharedInformerFactory
, which you can use to create "Informers", which you can use to watch for updates:
sif := NewSharedInformerFactoryWithOptions(...)
cminf := sif.Core().V1().ConfigMaps()
stopCh := make(chan struct{})
inf := cminf.Informer()
inf.AddEventHandler(cache.ResourceEventHandlerFuncs{
OnAdd: func(obj interface{}) {
cm, ok := obj.(*corev1.ConfigMap)
},
OnUpdate: func(oldCM, newCM interface{}) {
// TODO: do something with the update.
},
OnDelete: func(obj interface{}) { ... },
})
inf.Run(stopCh)
And to stop the watcher:
close(stopCh)
Or, to list or get objects:
// List all ConfigMaps in a namespace, or get one by name.
lis := cminf.Lister()
resp, err := lis.ConfigMaps(ns).List(...)
cm, err := lis.ConfigMaps(ns).Get(...)
...
These calls are served from the shared informer's cache, which it keeps up-to-date by initiating a single Watch
request.
SharedInformerFactory
old
and new
, don't require another API call to get previous version
old
can also be ignored, it didn't really cost anything to read itWatch
on the type and populates a shared indexed cacheNewSharedInformerFactoryWithOptions
can also take a TweakListOptions
to further limit the scope of the watch, if you only care about objects with a specific label, for example.
Make sure to use a single SharedInformerFactory
which you pass around and reuse, which lets all informers/listers created from it share a cache and index. Each SharedInformerFactory
makes its own Watch connections and keeps its own cache.