This is the first article to a series of articles to showcase how we use Operator that can leverage Kubernetes to create a stateful application such as Kafka Cluster.
An Operator is a way to package, run, and maintain a Kubernetes application. An Operator builds on Kubernetes to automate the entire lifecycle of the software it manages. Because Operators extend Kubernetes, they provide application-specific automation.
Before we begin to describe how Operators do these jobs, let’s define a few Kubernetes terms to provide context.
How Kubernetes Works
Kubernetes automates the lifecycle of a stateless application, such as a static web server. Without a state, any instances of an application are interchangeable. This simple web server retrieves files and sends them to a visitor’s browser. Because the server is not tracking state or storing input or data of any kind, when one server instance fails, Kubernetes can replace it with another. Kubernetes refers to these instances, each a copy of an application running on the cluster, as replicas.
A Kubernetes cluster is a collection of computers, called nodes. All cluster work runs on one, some, or all of a cluster’s nodes. A pod is a group of one or more containers with common resources like networking, storage, and access to shared memory.
At a high level, a Kubernetes cluster can be divided into two planes i.e. Control plane and Application Plan(Worker Nodes). The control plane is, in simple terms, Kubernetes itself. A collection of pods comprises the control plane and implements the Kubernetes application programming interface (API) and cluster orchestration logic.
On the other end the application plane, or data plane or worker nodes, is everything else. It is the group of nodes where application pods run. One or more nodes are usually dedicated to running applications, while one or more nodes are often sequestered to run only control plane pods.
The controllers of the control plane implement control loops that repeatedly compare the desired state of the cluster to its actual state. When the two diverge, a controller takes action to make them match.
Let’s see Kubernetes in action with a sample stateless application
Consider a cluster running a single replica of a stateless, static web server:
$ kubectl get pods
The output shows the number of pods running in your cluster
Let’s say we decide it should be three replicas, the cluster’s actual state differs from the desired state, and Kubernetes starts two new instances of the webserver to reconcile the two, scaling the webserver deployment:
$ kubectl scale deployment staticweb --replicas=3 $ kubectl get pods
This shows three pods are up and running.
Let’s say somehow we delete one of the webserver pods, which ultimately triggers work in the control plane to restore the desired state of three replicas. Kubernetes starts a new pod to replace the deleted ones.
$ kubectl delete pod staticweb-yourpod-id $ kubectl get pods
Now you can see the replacement pod shows a STATUS of “ContainerCreating”
This static site’s web server is interchangeable with any other replica, or with a new pod that replaces one of the replicas. It doesn’t store data or maintain the state in any way. Kubernetes doesn’t need to make any special arrangements to replace a failed pod or to scale the application by adding or removing replicas of the server.
Operators extend this behavior because Stateful Is Hard
Most applications have stated. They also have particulars of a startup, component interdependence, and configuration. They often have their own notion of what “cluster” means. They need to reliably store critical and sometimes voluminous data. Those are just three of the dimensions in which real-world applications must maintain state. It would be ideal to manage these applications with uniform mechanisms while automating their complex storage, networking, and cluster connection requirements. Kubernetes cannot know all about every stateful, complex, clustered application while also remaining general, adaptable, and simple. It aims instead to provide a set of flexible abstractions, covering the basic application concepts of scheduling, replication, and failover automation, while providing a clean extension mechanism for more advanced or application-specific operations. Kubernetes, on its own, does not and should not know the configuration values of a Kafka cluster let’s say, with its arranged memberships and stateful, persistent storage at Kafka Broker.
An Operator is like an automated Site Reliability Engineer for its application. It encodes in software the skills of an expert administrator. An Operator can manage a cluster of database servers, for example. It knows the details of configuring and managing its application, and it can install a database cluster of a declared software version and number of members. An Operator continues to monitor its application as it runs, and can back up data, recover from failures, and upgrade the application over time, automatically. Cluster users employ kubectl and other standard tools to work with Operators and the applications they manage because Operators extend Kubernetes.
Later I’ll explain How to create an Operator, How to use Operator, Deploy stateful service using Kafka Operator on Kubernetes.