Kubernetes Controllers Overview
At the core of Kubernetes itself, there is a large set of controllers. A controller ensures that a specific resource is (and remains) at the desired state dictated by a declared definition. If a resource deviates from the desired state, the controller is triggered to do the necessary actions to get the resource state back to where it should be. But, how do controllers “know” that a change happened? For example, when you scale up a deployment, you actually send a request to the API server with the new desired configuration. The API server in return publishes the change to all its event subscribers (any component that listens for changes in the API server). Thus, the Deployment controller creates one or more Pod to conform to the new definition. A new Pod creation is, in itself, a new change that the API server also broadcasts to the event listeners. So, if there are any actions that should get triggered on new Pod creation, they kick in automatically. Notice that Kubernetes uses the declarative programming methodology, not the imperative one. This means that the API server only publishes the new definition. It does not instruct the controller or any event listener about how they should act. The implementation is left to the controller.
While native Kubernetes controllers like Deployments, StatefulSets, Services, Job, etc. are enough on their own to handle most application needs, sometimes you want to implement your own custom controller. Kubernetes allows you to extend and build upon the existing functionality without having to break or change Kubernetes’s source code. In this article, we discuss how we can do this and the best practices.
Custom Controller Or Operator?
From the origin of Kubernetes, it was thought of controllers as the way developers can extend Kubernetes functionality by providing new behavior. Because of the many phases that extended-controllers has passed through, we can roughly classify them into two main categories:
Custom Controllers: those are controllers that act upon the standard Kubernetes resources. They are used to enhance the platform and add new features.
Operator: at their heart, they are custom controllers. However, instead of using the standard K8s resources, they act upon custom resource definitions (CRDs). Those are resources that were created specifically for the operator. Together, an operator and its CRD can handle complex business logic that a native or an extended controller cannot handle.
The above classification is only used to differentiate between different concepts that you need to understand in each model. But in the end, the concept stays the same; we are extending Kubernetes by creating a new controller. In this article, we are interested in the first type; custom controllers.