Detect Spec update in the reconcile function

1/21/2020

I am starting now with Kubernetes and the Operator SDK and I am trying to build my first operator and I have probably a simple question.

Question

How to detect a configuration change in the custom resource yaml in the reconcile loop and take an action according to the change?

I have some config properties specified in the my CR Spec:

apiVersion: my.example.com/v1alpha1
kind: StoreApp
metadata:
  name: mystoreapp
spec:
  username: technicalUser
  password: abcd1234
  catalogs:
    - name: Bikes
       description: Bikes_description
    - name: Cars
      description: Cars_description

I want when I add new custom resource of this kind my controller to create a new pod with my app image running inside (in a webserver). When my app is up and running for the first time I want to configure it (to add the catalogs from the spec) via HTTP request from the operator. So far it's ok but I also what to change these catalogs while my app is up and running.

For example I want to add new catalog in the spec (through kubectl patch). My operator's reconcile method will be called and how can I understand that the spec is changed? I am not sure it's a good idea to make HTTP calls to my app to get all catalogs and compare them with the catalogs from the spec. Is this the correct way to understand there is a change?

I am thinking about two other ways to find that something is updated but I am not sure if they will work properly and are they the best way to do this.

  1. First idea is to request the instance of StoreApp with client.Get(...) but as far as I understand this will call the API server and will get the updated version of mystoreapp. I read about some local index which acts like cache for these objects and I can check is there a difference between the cached object and the object returned from the API server. But I did not find how to get the object from this local index so I was not able to compare the two objects.

  2. To create map in which I store the hash of the hole spec object and to check every time this hash with the hash of the object got with client.Get(...). I think this will work but there should be a better way to do this.

I read some Java Operators for K8s and there were methods like onAdd, onUpdate, onDelete. I couldn't find something similar in the Operatod SDK. Is there anything like this in the Operator SDK?

Every answer will be helpful. Thank you in advance!

Best Regards, Hristiyan

-- aliench0
go
kubernetes
kubernetes-custom-resources
kubernetes-operator
operator-sdk

1 Answer

2/6/2020

The recommended practice is to look at the spec you received, and compare it to the state of the world/cluster, so retrieving the catalogs and comparing them to the spec is indeed the proper way to do it.

The reasoning for this recommandation is that the order of the events you get from Kubernetes is not guaranteed to be consistent, and it's also not guaranteed that you'll necessarily receive every event in a reasonable amount of time, or that you'll only receive each event once, so it's best to base your decision making on what was requested as compared to what is, rather than what specific event triggered the reconciliation.

-- fabianvf
Source: StackOverflow