Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Info/Feature] Watcher vs Informer #8

Open
thejasbabu opened this issue Dec 14, 2020 · 4 comments
Open

[Info/Feature] Watcher vs Informer #8

thejasbabu opened this issue Dec 14, 2020 · 4 comments

Comments

@thejasbabu
Copy link

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?

@dot-i
Copy link
Owner

dot-i commented Dec 14, 2020

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.

@pfisterer
Copy link

@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")
  })
}

@thejasbabu
Copy link
Author

thejasbabu commented Apr 2, 2021

@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()
}

@pfisterer
Copy link

@thejasbabu Great, thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants