Kustomize is a configuration management solution that leverages layering to preserve the base settings of your applications and components by overlaying declarative yaml artifacts (called patches) that selectively override default settings without actually changing the original files.
This approach to configuration management is incredibly powerful because most organizations rely on a combination of internally created (which Kustomize supports with bespoke) and common off-the-shelf (which Kustomize supports with COTS) applications to build their products. Overly customizing your source configuration files to satisfy individual use cases not only dramatically minimizes their reusability, it also makes ingesting upgrades either impossible or incredibly painful.
With kustomize, your team can ingest any base file updates for your underlying components while keeping use-case specific customization overrides intact. Another benefit of utilizing patch overlays is that they add dimensionality to your configuration settings, which can be isolated for troubleshooting misconfigurations or layered to create a framework of most-broad to most-specific configuration specifications.
To recap, Kustomize relies on the following system of configuration management layering to achieve reusability:
Let’s say that you are using a Helm chart from a particular vendor. It’s a close fit for your use case, but not perfect, and requires some customizations. So you fork the Helm chart, make your configuration changes, and apply it to your cluster. A few months later, your vendor releases a new version of the chart you’re using that includes some important features you need. In order to leverage those new features, you have to fork the new Helm chart and re-apply your configuration changes.
At scale, re-forking and re-customizing these Helm charts becomes a large source of overhead with an increased risk of misconfigurations, threatening the stability of your product and services.
The above diagram shows a common use case of a continuous delivery pipeline which starts with a git event. The event may be a push, merge or create a new branch. In this case, Helm is used to generate the yaml files and Kustomize will patch it with environment specific values based on the events. For example: if the branch is master and tied to the production environment, then kustomize will apply the values applicable to production.
Kustomize is often used in conjunction with Helm as described above, and it's been embedded in Kubernetes since its March 2019 release of version 1.14 (invoked by the command
Kustomize offers the following valuable attributes:
Before we dive into Kustomize’s features, let’s compare Kustomize to native Helm and native Kubectl to better highlight the differentiated functionality that it offers.
|Functionality||Kustomize||Native Helm||Native Kubectl|
|Templating||No templating||Complex templating||No templating|
|Setup||No separate setup||Needs setup||No separate setup|
|Configuration||Manage multiple configurations with one base file||Manage multiple configurations with one base file||Should have separate files for each different configuration|
|Ease of Use||Easy learning curve||More difficult compared to the other two||Easy learning curve|
Kustomize allows you to reuse one base file across all of your environments (development, staging, production) and then overlay unique specifications for each.
Since Kustomize has no templating language, you can use standard YAML to quickly declare your configurations.
YAML itself is easy to understand and debug when things go wrong. Pair that with the fact that your configurations are isolated in patches, and you’ll be able to triangulate the root cause of performance issues in no time. Simply compare performance to your base configuration and any other variations that are running.
Let’s step through how Kustomize works using a deployment scenario involving 3 different environments: dev, staging, and production. In this example we’ll use service, deployment, and horizontal pod autoscaler resources. For the dev and staging environments, there won't be any HPA involved. All of the environments will use different types of services:
They each will have different HPA settings. This is how directory structure looks:
The base folder holds the common resources, such as the standard deployment.yaml, service.yaml, and hpa.yaml resource configuration files. We’ll explore each of their contents in the following sections.
The kustmization.yaml file is the most important file in the base folder and it describes what resources you use.
The overlays folder houses environment-specific overlays. It has 3 sub-folders (one for each environment).
This file defines which base configuration to reference and patch using patchesStrategicMerge, which allows partial YAML files to be defined and overlaid on top of the base.
This file has the same resource name as the one located in the base file. This helps in matching the file for patching. This file also contains important values, such as min/max replicas, for the dev environment.
If you compare the previous hpa.yaml file with base/hpa.yaml, you’ll notice differences in minReplicas, maxReplicas, and averageUtilization values.
To confirm that your patch config file changes are correct before applying to the cluster, you can run
kustomize build overlays/dev:
Once you have confirmed that your overlays are correct, use the
kubectl apply -k overlays/dev command to apply the the settings to your cluster:
After handling the dev environment, we will demo the production environment as in our case it’s superset if staging(in terms of k8s resources).
In our production hpa.yaml, let’s say we want to allow up to 10 replicas, with new replicas triggered by a resource utilization threshold of 70% avg CPU usage. This is how that would look:
There's also a
rollout-replicas.yaml file in our production directory which specifies our rolling strategy:
We use this file to change the service type to LoadBalancer (whereas in
staging/service-nodeport.yaml, it is being patched as NodePort).
This file operates the same way in the production folder as it does in your base folder: it defines which base file to reference and which patches to apply for your production environment. In this case, it includes two more files: rollout-replica.yaml and service-loadbalancer.yaml.
kustomize build overlays/production
kubectl apply -k overlays/production
bases/for base files and
overlays/for environment-specific files.
kubectl kustomize cfg fmt file_nameto format the file and set the indentation right.
Kustomize comes pre bundled with kubectl version >= 1.14. You can check your version using
kubectl version. If version is 1.14 or greater there's no need to take any steps.
For a stand alone Kustomize installation(aka Kustomize cli) , use the following to set it up.
kustomize -hto verify:
For more installation options, see the Kubectl documentation.