Kubernetes boasts a wide range of features aimed at automating and facilitating the deployment of containerized applications. While the standard Kubernetes installation satisfies most users' needs, many use cases could benefit from additional functionalities.
This article will introduce you to Kubernetes operators and the various ways in which they extend the essential Kubernetes experience.
What Is Kubernetes Operator?
A Kubernetes operator is a software extension that utilizes custom resources to improve the management of a specific complex workload. Custom resources differ from regular Kubernetes resources like Pods, Services, and Deployments in that they cover a specific use case and provide functionality beyond the scope of Kubernetes resources.
Each Kubernetes operator consists of two primary components:
- Custom Resource Definition (CRD). A CRD provides the specification for a custom resource and enables the creation of custom resource instances as part of application deployment. Below is an example of a section of a YAML file that creates a CRD for the phoenixNAP BMC Kubernetes Controller.
- Controller. As with any other Kubernetes Controller, an operator Controller is a control loop that enforces the desired state of a specific resource. In this case, it is the resource defined through the CRD.
Why Does Kubernetes Need Operators?
The primary function of the operators in Kubernetes is to extend the core system and provide an environment tailor-made for specific application deployment. Through operators, developers can leverage automation and scaling capabilities beyond those offered by standard Kubernetes resources.
The following are the three most important benefits of working with operators:
- Application management. Each application has specific management requirements throughout its SDLC. Using operators helps developers fine-tune their Kubernetes deployments and facilitate application maintenance, updates, and scaling.
- Standardized deployments. Operators allow users to create consistent deployment patterns and management procedures to facilitate enforcing standards across all of their applications and services.
- Deployment automation. Operator Controllers can contain domain-specific knowledge that enables the deployment and management of an application without having to know details about its architecture and design.
Some common scenarios where operators are helpful are:
- Creating and applying backups of an application state.
- Establishing communication with apps that do not support Kubernetes APIs.
- Performing simulations when resilience testing.
How Kubernetes Operator Works
The primary mechanism behind any Kubernetes operator is the reconciliation loop. This loop is an iterative process in which the operator ensures the actual state of the system matches the desired state specified by a user.
The operator's Controller is in charge of executing the reconciliation loop. Once the Controller is deployed, it monitors the state of custom resource instances in the cluster. If an instance is deleted or updated, the Controller scans the state of the cluster, compares it to the desired state, and makes any necessary changes. The operators can also perform self-healing and restore the application or any of its components to a healthy state.
To interact with the operator, users create, update, and remove custom resource instances. Since the custom resources are API objects, the Kubernetes API detects user-made changes, which triggers the operator to perform the automatic management actions.
How to Deploy Operator?
Each operator has a deployment procedure specific to the use case it covers. However, there are some standard procedures involved in operator deployment:
- Building and packaging the operator. If the user develops the operator, they must package the code necessary to run the operator in a container.
- Creating operator manifest. The basic operator YAML manifest should contain two sections:
- Custom Resource Definition. The CRD defines the custom resource and the schema of the custom operator.
- Controller. The manifest provides configuration for the Controller and connects it with the CRD.
- Applying the manifest. Using the kubectl interface, the user can apply the operator to create the custom resource and the Controller in their cluster.
Note: Some operators come prepackaged in Helm charts, significantly shortening the deployment process.
How to Use Operator?
Using an operator in your workflow involves additional cluster management tasks. While the tasks are often specific to each operator, below you can find some general operator-related activities:
- Creating custom resource instances. Since the operator works through the custom Kubernetes resources, creating and managing the resources is fundamental to utilizing the operator's functionality.
- Monitoring the status of the operator. The operator's Controller runs as a Pod in the cluster. Monitoring the health of the Controller Pod allows the user to check whether the operator works as it should.
- Monitoring the reconciliation process. Another way to monitor the operator is to check whether it properly maintains the desired state of the cluster. The user can perform this action by manually inspecting the number and health of custom resource instances created in the cluster.
Note: Use the following kubectl command to see the available custom resource instances in your cluster:
kubectl get [custom-resource-name]
The custom resource name is the name specified in the CRD.
Top Kubernetes Operators
There are many pre-made operators available for extending Kubernetes functionality. Some help connect a specific application to your cluster, while others provide more general assistance. Below is the list of the most popular Kubernetes operators.
- Istio Operator. Installs and configures Istio, a service mesh platform that functions as a control plane.
- Prometheus Operator. Facilitates the deployment of Prometheus, an instrumentation framework for monitoring complex workloads.
- etcd Operator. Manages etcd key-value stores.
- Elasticsearch Operator. Helps the deployment of Elasticsearch clusters for real-time scalable search.
- MySQL Operator. Automates provisioning, scaling, and backups of MySQL databases on Kubernetes.
- Vault Operator. Manages HashiCorp Vault, a sensitive data-management tool.
- KubeDB Operator. Facilitates working with databases, such as MongoDB, MySQL, and PostgreSQL.
- Argo CD Operator. Installs and configures Argo CD, a Continuous Delivery tool for Kubernetes applications.
- Nginx Ingress Controller Operator. Assists with the management of Nginx Ingress Controller for routing HTTP traffic to services in a cluster.
- Flux Operator. Automates Kubernetes manifest CD, syncing the cluster with a desired state in a Git repository.
An extensive list of operators with installation instructions is available in the Operator Hub.
Can You Write Your Own Operator?
It is possible to design a custom operator if the particular functionality you need has not been covered by the operators in the ecosystem. While you can write an operator from scratch by utilizing Kubernetes controller-runtime project alone, it is easier to employ tools such as Kubebuilder, KUDO, or Kopf (Kubernetes Operator Pythonic Framework).
One frequently used tool is Operator SDK, an open-source solution for building, testing, and packaging operators. It employs the SDK CLI and the controller-runtime library to provide high-level APIs and extensions for more straightforward operator creation.
Writing Kubernetes Operators - Best Practices
Operator designers must learn and follow best practices to create effective and maintainable operators. The sections below contain the most essential best practices for writing your Kubernetes operators.
Write Operators Specific to Application or Application Type
One Unix design principle promotes the view that each application must have a specific purpose and perform a single function well. When writing an operator, design it for a specific application or application type since attempting to cover multiple apps and services may result in unnecessary complexity and maintenance problems.
Maintain One Operator per CRD
Similarly to the previous best practice, each operator should control only one CRD. Having multiple CRDs controlled by a single operator may result in problems with mixed domains of responsibility.
Create Controller for Each Feature
If an operator has more than one feature (scaling, restoring, monitoring, etc.), it should have that many Controllers. Each Controller should be dedicated to a single feature, thereby compartmentalizing the action inside the operator and making it easier to maintain.
Write Declarative APIs
Just like in Kubernetes, writing APIs declaratively allows you to shift most of the work to the operator itself. In contrast, imperative writing requires you to know each step of the underlying process, creating unnecessary complexity.
Write Using SDKs
The various SDKs available on the market aim to simplify the process of operator creation. Using them can help you avoid many of the bugs that stem from the complexity of the controller-runtime project.
After reading this guide, you should understand the role of Kubernetes operators in creating a more streamlined Kubernetes experience.
The article explained what operators are and how they work and provided tips and best practices for writing an operator.