Kubernetes: create events for custom resources - kubernetes

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.

Related

Should Kubernetes operator delete resources which are not managed by it?

I have my application deployed on Kubernetes cluster, managed by operator (A). I am mounting secrets with ssl key materials to the deployment, so application could access to the content.
I have separate operator (B) deployment, which is responsible to create those secrets with the ssl key materials. Now I have a use case where my secrets are recreated by operator (B), and it deletes/restarts the pods, which managed by operator (A).
I am trying understand - is it common practice to allow separately deployed operator delete pods?
My perception was that operator should work only with resources it manages, nothing more.
Community wiki to summarise the topic.
If it is as you say:
both operators are proprietary,
it is impossible to give a definite yes or no answer. Everything will depend on what is really going on there, and we are not able to check and evaluate it.
Look at the well provided comments by David Maze:
That sort of seems like a bug...but also, Pods are pretty disposable and the usual expectation is that a ReplicaSet or another controller will recreate them...?
Note that the essence of the Kubernetes controller model is that the controller looks at the current state of the Kubernetes configuration store (not changes or events, just which objects exist and which don't) and tries to make the things it manages match that, so if the controller believes it should manage some external resource and there's not a matching Kubernetes object, it could delete it.

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 dynamic pod provisioning

I have an app I'm building on Kubernetes which needs to dynamically add and remove worker pods (which can't be known at initial deployment time). These pods are not interchangeable (so increasing the replica count wouldn't make sense). My question is: what is the right way to do this?
One possible solution would be to call the Kubernetes API to dynamically start and stop these worker pods as needed. However, I've heard that this might be a bad way to go since, if those dynamically-created pods are not in a replica set or deployment, then if they die, nothing is around to restart them (I have not yet verified for certain if this is true or not).
Alternatively, I could use the Kubernetes API to dynamically spin up a higher-level abstraction (like a replica set or deployment). Is this a better solution? Or is there some other more preferable alternative?
If I understand you correctly you need ConfigMaps.
From the official documentation:
The ConfigMap API resource stores configuration data as key-value
pairs. The data can be consumed in pods or provide the configurations
for system components such as controllers. ConfigMap is similar to
Secrets, but provides a means of working with strings that don’t
contain sensitive information. Users and system components alike can
store configuration data in ConfigMap.
Here you can find some examples of how to setup it.
Please try it and let me know if that helped.

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

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.

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.