Manage and deploy your Microservices with a single helm chart using Helm operators
Microservice architecture is a trend these days, and many companies are adopting this architecture for building and managing their service. In addition, engineers prefer this architecture over monolithic architecture for several reasons, such as the separation of duties and the higher maintainability achieved by following this pattern for developing software applications. However, every architecture has its downside and challenges. Below are three of the top challenges for the microservice architecture;
- Tracing requests: A single application usually processes the incoming requests on the monolithic architecture, making it easy to trace requests by following the application logs. On the other hand, several services may contribute to the response of a single request in a microservice architecture. As a result, the logs for a single request will span over several applications, and hence there is a need to correlate the request logs from different services.
- Managing shared source code: Microservices share the same basic functionality in most cases despite the project or the programming language used to develop the services. For instance, every service needs to write log messages, provide a health check for its API endpoints, and many other features. Developing these features on the service level would be time-consuming and introduce inconsistency between the services. A better way to maintain shared code is to use libraries if possible.
- Deployment Configurations and Pipelines: It is clear that deploying software that follows microservice architecture is more complex than deploying a monolithic application simply because it involves deploying several services that may have deployment dependencies on each other.
Deploying services to Kubernetes clusters requires defining resources for each managed service. Below is a list of some resources needed to deploy service in Kubernetes:
Createing these resources one by one is a time-consuming and error-prone task. That is why we have a tool called Helm, a package manager for services that run on Kubernetes. Helm enables us to deploy an application to Kubernetes with a single command without creating all the needed Kubernetes resources for that application. However, suppose you have several services (which is the case for the microservice architecture). In that case, you need to define a helm chart for each application which will introduce a lot of effort for deploying the services and managing the helm charts for the following reasons:
- Each service needs its Helm chart.
- Updating standard deployment configurations may result in touching every single chart.
- Helm charts can be inconsistent and don’t follow any standards if multiple teams maintain the charts.
To solve the problem mentioned above, we have a couple of options that we can follow:
- Use CICD tools such as Argo CD to manage the Kubernetes resources and deployments.
- Build a deployment tool to generate Kubernetes resources and deploy them to the clusters.
- Use a Helm Operator to manage and deploy services.
This blog post will walk you step by step to build a Helm operator that can deploy several microservices.
Kubernetes operators are software applications running in the Kubernetes clusters and managing the life cycle of custom Kubernetes resources. There are several frameworks in the market that you can use to build your Kubernetes controller, such as:
One of the best frameworks to build Kubernetes operators is the Operator Framework. This framework enables us to develop operators using three different methods as described below:
- Using the Go programming language.
- Using Ansible
- Using Helm chart.
Using a Helm chart to build a Kubernetes operator is a simple task compared to developing the Kubernetes operator using Go programming language or other frameworks. And it can reduce the efforts needed for developing and maintaining the Kubernetes operator.
The Operator Framework enables us to create Kubernetes operators for managing by only defining a Helm Chart that deploys and manages the application resource. There is no additional development required for building the operator. This section will walk you step by step to create a Helm chart and generate a Kubernetes operator based on the chart.
Before we start building the Kubernetes operator, ensure that you have the following requirements:
- User authorized with cluster-admin permissions for a Kubernetes cluster.
- An accessible image registry such as hub.docker.com.
Once you setup the above requirements, you can proceed with the following steps to build the operator:
First, you need to install the
operator-sdk command line on your machine. You can use the below command to install it on macOS
$> brew install operator-sdk
If you use other operating systems, check this page for installing instructions.
Next, we need to create a Helm chart for our operator. If you already have an existing Helm chart and would like to make an operator based on it, you can skip this step. The below command will create a new Helm chart using the Helm command line. The Helm chart will manage the following Kubernetes resources.
- ServiceAccount: Define the service account used for the deployments.
- Deployment: Define an Nginx deployment object.
- Service: Define a service object to access the Nginx pods.
- Ingress: Define Ingress object to expose the Nginx service.
HorizontalPodAutoscaler: Scale the Nginx pods horizontally based on RAM and CPU resources.
$> mkdir microservice-operator && cd microservice-operator
$> helm create microservice
Then, Initialize the operator using the following command (replace the domain and project flags if needed):
$> operator-sdk init --plugins=helm --domain wshihadeh.dev
The above command will create a bunch of files locally, below is a brief description of the most important ones
- Dockerfile: The operator dockerfile.
- Makefile: Provides a set of commands for managing the operator life cycle, such as building the Docker image and pushing it.
- Config: This folder contains all the Kubernetes resources needed to deploy the operator.
- Helm-charts: contains the Helm charts managed by the operators.
Next, create the API resources for the operator using the below command (make sure you update the group, version, and helm-chart flags):
$> operator-sdk create api --group=deployments --version=v1
Now we generated the needed files for the operator. We can build the docker image for the operator and push it to the registry using the flowing command.
$> make docker-build docker-push
Next, Install the operator CRDs into the K8s cluster specified in
$> make install
Then, deploy the operator to the K8s cluster specified in
$> make deploy IMG=wshihadeh/microservice-operator:v0.1
At this stage, the operator should be up and running in the Kubernetes cluster and ready to manage custom resources. You can verify the installation process using the below commands:
$> kubectl get ns | grep microservice-operator-system
$> kubectl -n microservice-operator-system get pods
Finally, you can start deploying resources to Kubernetes using the Kubernetes
apply command. You can find a sample of the resources under the directory
config/samples and you can deploy it as shown below:
$> kubectl apply -f config/samples/deployments_v1_microservice.yaml
Once you create new resources with the above command, the running operator will install the release on the cluster. You can verify the installation process using one of the below commands:
$> kubectl get pods
$> kubectl -n microservice-operator-system
logs -f $conatiner manager
Using the Operator Framework build Kubernetes operators based on Helm charts have the following benefits
- Development is easy since it only involves updating the Helm chart and requires only standard Kubernetes configurations knowledge.
- Building and deploying the operator can be automated using CICD pipelines.
On the other hand, the downside for developing operators with Helm and Operator Framework are:
- Operator functionality is limited to the capabilities and features available in Helm.
Managing software that implements a microserver architecture can be a complex task, especially if several routine tasks need to be done for each service individually. Managing Kubernetes service can be one of these tasks that can be complex. You can quickly build a Kubernetes operator that installs and manages microservices using Helm and Operator Framework. The Operator Framework lets us convert a Helm chart to software that deploys resources based on the Helm chart templates.