k8s-operator-node
k8s-operator-node copied to clipboard
[Info/Feature] Watcher vs Informer
Hi,
I have noticed that the watchResource does not contain any cache which helps while re-listing and re-watching k8s resources. This functionality already exists in the underlying kubernetes@client-node but was surprised to see not being used in this project.
Any idea as to why?
Was simply not aware of the informer existing 😉 I see it uses an internal cache, so it might indeed be interesting to switch to this instead.
@thejasbabu Can you point me to a working example that uses Informer to watch custom resources?
I'm getting this error:
[DEBUG] Reconciler - init: Watching group 'mk8.farberg.de', version 'v1', plural 'microkeights'
./node_modules/@kubernetes/client-node/dist/cache.js:77
const list = result.body;
^
TypeError: Cannot read property 'body' of undefined
at ListWatch.<anonymous> (./node_modules/@kubernetes/client-node/dist/cache.js:77:33)
at Generator.next (<anonymous>)
at fulfilled (./node_modules/tslib/tslib.js:112:62)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
when using this code:
async init() {
//Create K8s Client
this.logger.debug(`init: Creating kubeconfig`)
this.kubeConfig = new k8s.KubeConfig();
this.kubeConfig.loadFromDefault();
this.k8sApi = this.kubeConfig.makeApiClient(k8s.CoreV1Api);
this.customObjectsApi = this.kubeConfig.makeApiClient(k8s.CustomObjectsApi)
// Register custom resource definition
// registerCustomResourceDefinition @ https://github.com/dot-i/k8s-operator-node/blob/master/src/operator.ts
this.logger.debug(`init: Registering CRD from file ${this.options.crdFile}`)
const { group, versions, plural } = await this.registerCustomResourceDefinition(this.options.crdFile);
this.crdGroup = group;
this.crdVersions = versions;
this.crdPlural = plural;
console.log("XXX", await this.customObjectsApi.listClusterCustomObject(this.crdGroup, versions[0].name, this.crdPlural))
this.logger.debug(`init: Watching group '${this.crdGroup}', version '${this.crdVersions[0].name}', plural '${this.crdPlural}'`)
const informer = k8s.makeInformer(this.kubeConfig, `/apis/${this.crdGroup}/${versions[0].name}/${this.crdPlural}`, () => {
console.log("Called")
})
}
@pfisterer A sample informer code for a CRD Foo
const kubeConfig = new k8s.KubeConfig();
const credentials = fs.readFileSync(path.join(__dirname, 'kubeconfig'), 'utf8');
kubeConfig.loadFromString(credentials);
const k8sApi = kubeConfig.makeApiClient(k8s.CustomObjectsApi);
const apiGroup = 'samplecontroller.k8s.io';
const apiVersion = 'v1alpha1';
const namespace = 'foo-namespace';
const plural = 'foos';
async function start() {
let apiPaths = `/apis/${apiGroup}/${apiVersion}/namespaces/${namespace}/${plural}`;
const listFn = () => {
return k8sApi.listNamespacedCustomObject(
apiGroup,
apiVersion,
namespace,
plural
);
}
const informer = k8s.makeInformer(kubeConfig, apiPaths, listFn);
return informer.start()
}
@thejasbabu Great, thanks a lot!