<p>I need my Go app to <strong>monitor some resources</strong> in a Kubernetes cluster and react to their changes. Based on numerous articles and examples, I seem to have found a few ways to do it; however, I'm relatively new to Kubernetes, and they're described in terms much too complex to me, such that I'm still <strong>unable to grasp the difference</strong> between them — and thus, to know which one to use, so that I don't get some unexpected behaviors... Specifically:</p>

<ol>
<li><a href="https://godoc.org/k8s.io/apimachinery/pkg/watch#Interface" rel="noreferrer"><code>watch.Interface.ResultChan()</code></a> — (acquired through e.g. <a href="https://godoc.org/k8s.io/client-go/rest#Request.Watch" rel="noreferrer"><code>rest.Request.Watch()</code></a>) — this already seems to let me react to changes happening to a resource, by providing <code>Added</code>/<code>Modified</code>/<code>Deleted</code> events;</li>
<li><p><a href="https://godoc.org/k8s.io/client-go/tools/cache#NewInformer" rel="noreferrer"><code>cache.NewInformer()</code></a> — when I implement a <a href="https://godoc.org/k8s.io/client-go/tools/cache#ResourceEventHandler" rel="noreferrer"><code>cache.ResourceEventHandler</code></a>, I can pass it as last argument in:</p>

<pre><code>cache.NewInformer(
        cache.NewListWatchFromClient(clientset.Batch().RESTClient(), "jobs", ...),
        &amp;batchv1.Job{},
        0,
        myHandler)
</code></pre>

<p>— then, the <code>myHandler</code> object will receive <code>OnAdd()</code>/<code>OnUpdate()</code>/<code>OnDelete()</code> calls.</p>

<p>To me, this seems more or less equivalent to the <code>ResultChan</code> I got in (1.) above; one difference is that apparently now I get the "before" state of the resource as a bonus, whereas with <code>ResultChan</code> I would only get its "after" state.</p>

<p>Also, IIUC, this is actually somehow built on the <code>watch.Interface</code> mentioned above (through <code>NewListWatchFromClient</code>) — so I guess it brings some value over it, and/or fixes some (what?) deficiencies of a raw <code>watch.Interface</code>?</p></li>
<li><a href="https://godoc.org/k8s.io/client-go/tools/cache#NewSharedInformer" rel="noreferrer"><code>cache.NewSharedInformer()</code></a> and <a href="https://godoc.org/k8s.io/client-go/tools/cache#NewSharedIndexInformer" rel="noreferrer"><code>cache.NewSharedIndexInformer()</code></a> — <sub><sup>(uh wow, now <em>those</em> are a mouthful...)</sup></sub> I tried to dig through the godocs, but I feel completely overloaded with terminology I don't understand, such that I don't seem to be able to grasp the subtle (?) differences between a "regular" <code>NewInformer</code> vs. <code>NewSharedInformer</code> vs. <code>NewSharedIndexInformer</code>... 😞</li>
</ol>

<p>Could someone please help me <strong>understand the differences</strong> between above APIs in the Kubernetes client-go package?</p>

akavel
<p>These methods differ in the <strong>level of abstraction</strong>. If a higher level abstraction fits your need, you should use it, as many lower level problems is solved for you.</p>

<p><strong>Informers</strong> is a higher level of abstraction than <em>watch</em> that also include <em>listers</em>. In most use cases you should use any kind of Informer instead of lower level abstraction. An Informer internally consists of a <em>watcher</em>, a <em>lister</em> and an <em>in-memory cache</em>.</p>

<p><strong>SharedInformers</strong> share the connection with the API server and other resources between your informers.</p>

<p><strong>SharedIndexInformers</strong> add an index to your data cache, in case you work with a larger dataset.</p>

<p>It is recommended to use SharedInformers instead of the lower level abstractions. Instantiate new SharedInformes from the same <strong>SharedInformerFactory</strong>. Theres is an example in <a href="https://github.com/feiskyer/kubernetes-handbook/blob/master/examples/client/informer/informer.go" rel="noreferrer">Kubernetes Handbook example</a></p>

<pre><code>informerFactory := informers.NewSharedInformerFactory(clientset, time.Second*30)

podInformer := informerFactory.Core().V1().Pods()
serviceInformer := informerFactory.Core().V1().Services()

podInformer.Informer().AddEventHandler(
    // add your event handling 
)

// add event handling for serviceInformer

informerFactory.Start(wait.NeverStop)
informerFactory.WaitForCacheSync(wait.NeverStop)
</code></pre>
