A Quick Introduction to Kustomize
Kustomize is a Kubernetes native configuration management tool that can be easily installed and used. If you are a DevOps engineer who writes Kubernetes manifest files for your organization, you might already know that handling Application manifest files for multiple environments is a tedious task. When I first started with Kubernetes, I used to create multiple copies of the same manifest file for different environments (like dev, staging, production, etc). In most of the cases, the only changes in manifest files of different environments are their resource name, namespace value, labels and images. Apart from that, most of the values are same in all the environment. If we use this approach, the disadvantage is, if we want to add a new container or change a port number to our existing manifest file, we need to change/add that value in the manifest file of every environments. This process is very error-prone also. If we forgot to make that change in any environment, that environment will fail while we apply that change. Given below is an example of the directory structure we used earlier for different environments:
Tools like Kustomize and Helm can be used to avoid these difficulties. Kustomize traverses a Kubernetes manifest to add, remove or update configuration options. Kustomize can be used to create manifest files for every environment from a base manifest file. i.e., If we have a set of manifest file for a certain environment, we can use Kustomize to make necessary changes to those manifest files and use that for other environments, without creating multiple copies of the base manifest files.
Kustomize use case
Consider a simple deployment of an application and we have its “deployment.yaml” file with us. Also, we need to deploy this application to 3 environments (i.e., dev, staging and production). In all these 3 environments, the base structure of the deployment.yaml file is same and there are changes in deployment name, namespace and maybe the image that we use. In normal situation, our option is to create 3 manifest file of deployment.yaml for the 3 environments. But, with the use of Kustomize tool, we can use the existing deployment.yaml file as base and then use a file called “kustomization.yaml” that contains the changes/patches for the 3 environments. In this way, we are avoiding the difficulty of creating and managing separate manifest file for each environments.
Install Kustomize
We can directly install Kustomize using the official documentation. It can be installed using source, binary, as a Docker image, Homebrew, Chocolatey, etc. Given below is the link to install Kustomize based on your operating system.
Link: https://kubectl.docs.kubernetes.io/installation/kustomize/
What is kustomization.yaml File
The “kustomization.yaml” file is the main file that is used by the Kustomize tool. In this file, we provide details of our required customizations. The customizations include:
- What are the resources that we are going to edit using Kustomize
- What are the patches that we are going to apply
Given below is a simple implementation of Kustomize. Consider we have a deployment file with us.
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
namespace: api-dev
spec:
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: neron/nginx-dev:1.0
The given deployment.yaml file is written for dev environment. We need to create manifest file for production environment as well. The only change that we need to do is changing the namespace to “api-prod” and the image to “neron/nginx-prod:1.0”. In order to do that, we can create a kuztomization.yaml file and provide required transformers or patches. Given below is a sample kustomization.yaml file to change the namespace and image value.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# resources section contains the resources that kustomize is handling
resources:
- deployment.yaml
namespace: api-prod
images:
- name: neron/nginx-dev:1.0
newName: neron/nginx-prod
newTag: "1.0"
In this case, both the deployment.yaml file and kustomization.yaml file must be on the same directory. We can generate the manifest file for production environment using the following command:
kustomize build base-directory/
This command will only print the generated manifest file for production environment. If we need to apply this to the Kubernetes cluster, we can use the following commands
kustomize build base-directory/ | kubectl apply -f -
OR
kubectl apply -k base-directory/
Note: Here, base-directory is the directory where deployment.yaml and kustomization.yaml file resides.
Transformers
Transformers are used to create new resources under manifest by applying a series of transformations to the original set of resources. Given below are some of the examples of Kustomize transformers
- commonLabel
This transformer will add labels to existing manifest file - namePrefix or nameSuffix
If we need to add prefix or suffix to existing resource names, we can use this transformer - namespace
If we need to add/update namespace value from a manifest file, we can use this transformer - images
To change the container image or tag, we can use this transformer
Similarly there are other transformers also. Given link contain more details about other transformer configuration.
Patches
In Kustomize, we can apply patches to manifest file instead of using “patches” function. Given below are the main 3 parameters for patches functionality
- target
To what target we are going to apply the patch - operation type
What type of operation that we are going to use (add/replace/remove) - path
In what exact resource we are going to apply patch - value
With what value we are going to apply the patch
A sample patch under the kustomization.yaml is given below:
patches:
- target:
kind: Deployment
name: api-deployment
patch: |-
- op: replace
path: /spec/template/spec/containers/0
value:
name: api
image: nginx
In this way, we can change the image name of our deployment to nginx using kustomize patch. There are other methods for patching. Use this link to learn more about Kustomize patches (https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/)
There is one more method for applying patch, its called Strategic merge patch where we can give direct yaml file content under the patch section. More details about the strategic merge patch can be read in this link: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/patchMultipleObjects.md
Bases and Overlays
Bases and Overlay are concepts in Kustomize where we can structure our application manifest based on different environments. Base is a directory in which all the base manifest files are stored along with a kustomization.yaml file. We can create overlays for different environments where we specify the base and it has its own kustomization.yaml file with their environment related patch. Given below is a sample directory structure with base and overlays:
For projects with multiple environments, the method of using base and overlay is mostly recommended. If you want to dig deep into this method, please use this link as reference: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/#bases-and-overlays
Conclusion
The above section describes a real quick and easy to understand introduction of Kustomize and some sample code using Kustomize tool. The main advantage that I saw in Kustomize is that it is very easy to start using, if we compare this with other tools like Helm.
Some samples of Kustomize codes are added in the GitHub repo for reference: https://github.com/NeronJoseph/Kustomize-Familiarization
Happy Learning ! ! !
References
- https://kubectl.docs.kubernetes.io/references/kustomize/
- KodeKloud video tutorial — Kustomize