Goutham K

TIL: informers just subscribe to the API server's event stream

Every create, update, and delete that hits the API server becomes a watch event on that object’s resource version stream. The same stream kubectl get pods -w listens to — ADDED / MODIFIED / DELETED, delivered over a long-lived watch connection, no polling anywhere.

The informer pattern in client-go is what turns that stream into something usable. It keeps a local, thread-safe store in sync with the watch, and your event handlers mostly just push keys onto a workqueue:

factory := informers.NewSharedInformerFactory(clientset, 0)
podInformer := factory.Core().V1().Pods().Informer()

podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
    AddFunc:    func(obj interface{}) { /* enqueue key */ },
    UpdateFunc: func(old, new interface{}) { /* enqueue key */ },
    DeleteFunc: func(obj interface{}) { /* enqueue key */ },
})

go factory.Start(ctx.Done())
factory.WaitForCacheSync(ctx.Done())

The reconcile then reads from the local cache instead of hammering the API server on every event.

So “watching” in Kubernetes isn’t a metaphor. There is a real event stream coming off the API server, and informers are subscribers with a cache attached.