Kustomize a reasonable alternative to Helm Charts

First of all, I would like to tell you, I like so much Helm Charts, and I have great experiences using this tool.

The usability for the users is very impressive with a simple command everything is up and running. The community is very active and you can find many recipes at Github, we need to look carefully but in general, work, as expected.

I’ve deployed a couple of applications and I had very successful deployments with that tool, but in my first experience to “write” the recipe and I’ve found the truth. Templates a lot, much, many brackets everywhere and then I’ve got a little bit disappointed.

For sure it is not a big problem, because I do that one time, at the beginning of the project, after I need some improvements and keep the evolution.

When I start to write operation stuff for projects, every time I asked myself. There should a simple way to do that the same stuff.

Yes, I’ve found that tool, without a template, goodbye fu*** brackets I don’t like you. Also, that tool is more declarative than helm, I got my yaml if I need them, I don’t need to run something to get them.

Introducing…..

Introducing Kustomize

From the kustomize website “Kustomize introduces a template-free way to customize application configuration that simplifies the use of off-the-shelf applications.”

It means there are no brackets anymore, there is no tool to “process” my recipe anymore and I have it on the kubectl tool, like a native for kubernetes.

Also, it brings the declarative way to create things, I’m able to navigate in my yamls and then find what is deployed in my kubernetes. Everything in kustomize is a plain yaml, all the people are able to read them. Humans and tools.

We need to follow a simple folder structure and a couple of new nodes in yaml, that is all as we need.

Let’s see how it works. I’ll show it on an open-source project called APIrator that helps developers to create API Mocks for development and tests purpose. The recipe will deploy it on the cluster.

Let’s understand a little bit deeper.

Kustomize Folder Structure

Before to understand how it works let’s explore the folder structure to organize our kubernetes manifests

I’ll use a simple example, that I’ve worked on the last couple days, the APIrator kustomize project

The folder structure should be like this

There are important folders here. The base folder and overlays.

It will consider our environments, we have two, development and production.

It is pretty simple to understand. The base folder contains the commons configuration which will be shared by different environments.

The overlays/development contains configuration for the development environment.

Finally, the overlays/production contains configuration for the production environment.

With kustomize, we are able to handle different environments, like the example below

Kustomize Files and Examples

In each folder has the kustomization.yaml file that describes some customizations. Let’s see the kustomization present on the base folder

As we can see we can define the commons labels for all resources prevenient from this recipe. The resources attribute lists all resources necessary to install this application.

The ConfigMaps declared as resource are treated the same way as other resources. Kustomize doesn’t append any hash to the ConfigMap name. The ConfigMap declared from a ConfigMapGenerator is treated differently. A hash is appended to the name and any change in the ConfigMap will trigger a rolling update.

Let’s see the kustomization for the production environment

The bases attribute indicates the base for this customization

The patchesStrategicMerge indicates the names of the files that will be merged and generate the “updated” file with changed by the desired environment or overlay in our case.

Some important notes, the patchesStrategicMerge will use the strategic merge patch in kubernetes APIs which means it will use the Patch Method and following the REST architecture model.

You can find the full Strategic Merge Patch in the Reference topic.

Another important part is the names of resources inside in the elements to be patched should be the same as the declared in the base folder. Let’s see an example.

The piece of kustomization located in the base folder

kustomization.yaml located in the base folder
The ConfigMap element declared in the production folder

As we can see the name of the ConfigMap object should be the same in the base and environment it is very important.

The last one is the attribute of the image, it is pretty simple. It describes the tag of the docker image that we want to deploy in a production environment.

Awesome, our configuration stuff is ready, let’s see how to apply it!!!

Running with kustomize

Now we are ready to run through the command line.

kustomize build

Kustomize build helps us to see the updated manifests with the desired environment configuration. We are able to run kustomize build in any folder that has the kustomization.yaml file. We will configure the manifests for the production environment.

Let’s check the files that will be updated. Go to the production folder and use the following command line

The output should be the manifests updated for the production environment. But as we can see it is a simple text, there is no file generated.

Applying the manifests

The kustomize build command line updates our manifests with the desired customization, but it produces simple text output. We can use this output and invoke the kubectl tool to apply this customization. Let’s do it right now

This command will apply the generated stuff on the desired namespace.

Conclusions

I’m still learning the kustomize stuff, but the simplicity imposed by the kustomize caught my attention.

Also, it keeps the kubernetes things in a declarative way and helps me a lot to follow the Infra-as-Code concerns.

Finally, as I said I don’t like the billions of brackets that I need in the helm charts

References

https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md

https://kustomize.io/

https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/

Kubernetes Patterns – Sidecar

Motivation

On the last week, I’ve blogged about Ambassador Pattern.

This pattern is very important when we are trying to solve network issues in the Microservices architecture, in a few words Ambassador is a kind of proxy, to help in the service-to-service communications.

Today we’ll talk about Sidecar Pattern, it’s an interesting pattern when we are looking for help with network issues, but as we will see during this post, there are more features which this pattern enable for us.

 

Context

In the containers world, we need to follow the container Golden Rule, the container should have one single purpose to exist. That is the most important thing to follow.

When we are developing applications using the microservice as an Architectural guide, we shouldn’t worry about concerns related to infrastructures, like log collector, network handlings and other orthogonal concerns. These concerns are more related to the platform where we are running our service than our application code.

We should use our platform to help us with these activities. Kubernetes is a “de-facto” platform to run containers workloads. We can use Kubernetes to deploy a dedicated infrastructure to handle internal network traffic, ISTIO for an example. In this case, ISTIO is our “platform” to help with network handlings.

I’ve blogged about my first impressions about ISTIO and Service Mesh

Kubernetes has the primitive called PODs, the small unit of computational resources in the kubernetes ecosystem, the POD is able to have multiple containers, in that scenario the Sidecar Pattern is a perfect solution to help the main container.

Let’s look at the POD anatomy (the yellow one)

Solution

The Sidecar container should add some additional functionalities to the microservice container. The important part to pay attention here is the sidecar should run in a different process and is not able to change anything in the microservice container.

In the same POD, containers are able to share the volumes and the same network, it means the containers can reach each other via “localhost” for an example.

Let’s analyze an example.

In the real microservices architecture, we might have different services and many instances of these services, but, how we are able to look effectively at the logs?

We need a centralized tool that collects these logs, also we need an effective way to query these data to find something that helps us to troubleshoot and debug distributed systems.

Is that role of the main container to send these logs for service in the cloud? Maybe a Sidecar container is able to collect these logs, they are sharing the volumes, and send these data to the cloud.

The sidecar “enrich” the main container functionalities sending data to the cloud systems. That is the main role of Sidecar Container.

Look at the image below:

As we can see, the logger container sends the data to the cloud storage, the logger read data from POD volumes, because they are sharing the disk.

The microservice container doesn’t care about the logs, the main container should play to service our business only.

That is one example where sidecar container can help us adding extra functionalities for our main container.

In the Service Mesh Infrastructure, the sidecar container can help us adding some extra functionalities to help us to handle network issues, it is another example.

Conclusion

The Sidecar Pattern is very useful when we are working in distributed systems, especially in containers world.

It will increase our productivity because we don’t need to pay attention to infrastructure stuff and it makes our code more concise than ever without infrastructure handlings.

Then, it is time to say goodbye to Netflix Ribbon, Netflix Eureka and Netflix Hystrix and put their responsibilities to sidecar container.

References

Kubernetes Pattern Book

Microsoft Azure Docs

Kubernetes Patterns – Ambassador

 

Motivation

Recently, I’m studying kubernetes in-depth, mainly in part about how to use platform features to help me to work with distributed architectures.

During this journey, for my surprise, I’ve found many books of Kubernetes Patterns, and my god, these books opened my mind about “How to use Kubernetes effectively”.

My favorite one is Kubernetes Patterns, the book is awesome, it’s a kind of guide for me right now. The book describes many patterns and categorizes them in principles like Predictable Demands, Declarative Deployments, Health Probe, Managed Lifecycle and Automated Placement.

Today, I’ll talk about an important pattern related to network management techniques.

Let’s talk about Ambassador Pattern.

Ambassador

Context

When we are working with distributed systems, the network is the biggest challenge to solve, remember The Fallacies of Distributed Computing.

We need to do an effective strategy to work with outages, service discovery, circuit breakers, intelligent and dynamic routing rules, and time-outs.

In general, these things require a lot of configuration files envolving connection, authentication and authorization. These configurations should be dynamic as well, because in the distributed systems, addresses for instances, changes a lot during a certain timebox.

Of course, sometimes we are not able to handle these issues because our “application” is not able to handle it, our framework which the application is coded doesn’t support these features.

Also, we need to remember the containers Golden Rule, the container should exist for one single and small reason.

Maybe, handle these challenges into our application code cannot be a good idea, especially because sometimes we need to integrate with legacy applications.

The ambassador help us exactly at this point, let’s see how it happening.

Solution

Ambassador acts as “proxy” and hides all the complexities of accessing the external services.

We will put the ambassador container between our main application and external services connections. Just to remind, our ambassador container should be deployed in the same Kubernetes POD, which resides our main application container.

Using this simple approach we able to handle network failures, security, resiliency in the ambassador container, simple and effective way to handle these hards things to solve.

Look at the image below

The Ambassador Container should handle configurations related to Service Discovery, Time-outs, Circuit Breaker, Smart Routing and Security

Conclusion

The ambassador Pattern is very useful when we are working with distributed systems. It will reduce our main application complexity taking off the network management in our application code.

Remember: It will add some latency overhead. If network latency is a critical point for you, maybe you need to think about the ambassador adoption.

 

References

Kubernetes Patterns book

https://docs.microsoft.com/pt-br/azure/architecture/patterns/ambassador