How to watch a Pod api endpoint in a Kubernetes Operator using the SDK - kubernetes

Description
I have a CR associated with a POD with a container that is exposing an API, eg:
/available
returning for example
{"available":"true"}
Is there a way to create a controller watcher on that API call that whenever the response changes will trigger the reconcile function?
I believe it could be possible using a channel with the controller watcher, but I don't see any similar examples out there
Using
Kubernetes operator-sdk version v0.5.0+git

I'm afraid it's not as easy as you hope. The Kubernetes controller objects react to add/edit/delete operations of some kind of resource in the cluster. A value exposed inside an API of something running inside the Pod is not visible in the resource database. There is not event going off, notifying about the change either.
I see two things you can consider doing:
Create a regular controller that would have the reconcile function triggered fairly often, but would check the availability value inside it's reconcile function. If it changed, it would do something, if it didn't it would do nothing.
Just create a separate task, outside the controller domain, that would monitor this API value and do something.
Controllers work using notifications, they don't actively watch for changes, they are notified about them. That's different than what you want to do - periodically check the API response.

Related

Does a kubernetes reconcile have to be quick?

I'm writing a controller for a k8s CRD.
The job the controller has to do will usually be quick, but could on occasion take a really long time - let's say as much as an hour.
Is that ok for a Reconcile? Or should I move that work out of the controller into a separate pod, and have the controller monitor the process of that pod?
I see no reason why the reconcile loop couldn't take as long as you need.
Technically speaking a reconcile is just getting a copy of a resource i.e. an HTTP Get or an event if you're using the Watch API, followed by a change to the resource e.g updating the resource Status fields i.e an HTTP PUT/POST.
The only caveat is making sure the resource version you have is still the latest one when trying to change it. Including resource versions in your request should solve this problem.
More info here: https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions

Automatically creating resources/objects with creation of namespace in Kubernetes

I am trying to find a way? If I create a new namespace then I want it to create a RBAC rule for that serviceaccount automatically.
I know one way is to create an operator so, that there is an event that is traced by reconciler / api server and it creates the resources based on CRD's. Is there any other way?
While not really intended for this kind of thing you could use admission controllers (https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) to achieve something like that.
Due to it's nature the admission controller is called before the namespace exists and you would need to wait until its creation is finished to create objects within that namespace. For that the admission controller call needs to be completed, else the namespace can't be created. I.e. by calling a second service that waits until the namespace is actually created.
I asked a similar question here: Automatically create Kubernetes resources after namespace creation (I didn’t find yours at that time).
I ended up writing a controller that does exactly what you need: https://github.com/blakelead/nsinjector
In short, you deploy a custom resource specifying resources to deploy and patterns for namespace names you want to target.

Kubernetes: create events for custom resources

I have created a custom resource definition (CRD) and a custom resource (CR) in my Kubernetes cluster, but in my CR controller, how do I create Kubernetes events which are attached to my custom resource? I hope with events, users will be able to see important messages associated with the CR when they run kubectl describe <cr>.
You're looking for an operator. There are already a few pre-written ones out there, check OperatorHub. They are essentially controllers for custom resources, watching for events and acting on them.
You can also write your own, e.g. with the Operator SDK. When you write your own, you can update the status of the CR, depending on what your operator should do, which then shows up when calling kubectl describe.
A good start might be this post on Operators, and this here for listening to events from your custom resources.

kubernetes custom resource definition to keep track of the number of services/namespaces

I am trying to create a custom kubernetes controller which keeps the track of the number kubernetes resources, for example count the number services created in a cluster.
there are 2 parts to the above question:
1st I need to create a controller which listens to when a service is created, lets call this counter as svc_count. This is easy, as I can write a custom controller to listen on services.
I need to store the svc_count in the etcd, so that I can show the value
when some user queries for the svc_count. So I thought of using the CRD's. I can do that by following the example in https://github.com/yaronha/kube-crd. This has the Rest-API-client to POST,PUT,GET.
The 3rd part is relating the part 1 and part 2. Whenever a Service is created, then in the ADD eventhandler of the controller I need make changes to the CRD, so that the user can see the update.
Issue/Question: My question how to update a CRD from the custom controller's eventhandler??. Can I save the CRD rest-api-client in the custom controller and call the respective Update function.
Please, let me know if there is any other way of doing this.
Thanks

Where do I submit events on failure of my custom operator?

I'm working on a mysql users operator and I'm somewhat stuck on what's the proper way to report any issues.
The plan is to watch on CRD for MysqlUser and create Secrets and mysql users in the specified DB. Obviously, either of that can go wrong, at which point I need to report an error.
Some k8s object track events in the status.conditions. There's also the Event object, but I've only seen that used by kubelet / controllermanager insofar.
If say, I have a problem creating mysql user because my operator cannot talk to mysql, but otherwise the CRD is valid, should it go to event or to CRD's status?
CRDs do not have a status part yet (1.7). Notifying via events is perfectly fine, that's the reason for having them in the first place.
This sounds similar to events reported from volume plugin (kubelet) where, for example, kubelet is unable to mount a volume from NFS server because server address is invalid, thus can not take to it.
Tracking events in status.conditions is less useful in this scenario since users typically have no control over how kubelet (or operator in your case) interacts with underline resources. In general, status.conditions only signals the status of the object, not why it is in this condition.
This is just my understanding of how to make the choice. I don't know if there is any rules around it.