When we start with Kubernetes and use YAML config files, generally we begin to install them one by one with the following command.
kubectl apply -f <file>
Then, we discover that we can directly target a complete folder instead of a file
kubectl apply -f <folder>
But, if we are doing it in each environment that we have, it can quickly be annoying to duplicate all the configs or update it each time we switch. That's why, in these cases, we start to use some tools to generate the configs dynamically.
Today, we will speak about one of them, Kustomize.
What is Kustomize?
Kustomize is a configuration management tool embeded in Kubernetes!
So if you already have kubectl setup, you can directly use it.
Unlike Helm, it's not a templating tool, but really a config management tool.
To give you a quick example to compare both tool, Helm will use a template (like behind) and the user will define a value for each variable.
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
spec:
replicas: 5
template:
containers:
- name: {{ .Values.containerName }}
image: {{ .Values.containerImage }}
In this example, the user can define the container name and its image. But, they can't update the number of replicas.
Once called, Helm will generate a yaml file from the template and the values given by the user.
Kustomize will allow the user to override any configuration value. (We will see how later.)
Before going further, here is the context for our next examples.
- /kubernetes
- /application
- deployment.yaml
- configmap.yaml
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 1
template:
containers:
- name: my-container
image: ubuntu:latest
env:
- name: TEST
value: TOTO
volumeMounts:
- name: config-volume
mountPath: /configs/
volumes:
- name: config-volume
configMap:
name: example-config
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
namespace: example
data:
config.json: |
{
"environment" : "test"
}
How works Kustomize ?
First, Kustomize needs a kustomization.yaml file which will contain all the configurations that it needs to know.
Base
In our example context, we will add this file in the /application folder with this content :
resources:
- deployment.yaml
- configmap.yaml
Here, we indicate to Kustomize which files are the Kubernetes config files that we want to apply when this kustomization file is called. This folder become our base for our next configurations.
Therefore, if we use one of the following commands, we will generate the deployment and the configmap as defined in our YAML files.
kubectl kustomize .\kubernetes\application\ | kubectl apply -f -
# Or
kubectl apply -k .\kubernetes\application\
Customization
Now that we have our base, we can create our custom configurations for each environment that we have.
In the /kubernetes folder, we create a folder /environments. Then, in this folder, we create two folders /dev and /prod (representing each environment that we have), and we create a kustomization.yaml file in both /dev and /prod.
In both files, we add this content
bases:
- ../../application
This bloc define which is the configuration basis for our customization. (In this example, it targets the previous folder that we configured)
So, if we are using the same command to use Kustomize but targeting one of the environment folder, the deployment and configmap defined in the base will be created.
kubectl kustomize .\kubernetes\environments\dev | kubectl apply -f -
# Or
kubectl apply -k .\kubernetes\environments\dev
Possible updates
Searching through the Kustomize documentation, you will see each and every update available, but now we will only see the principal ones.
Patch
A patch in Kustomize is a file which will contains a partial configuration of a component which will override the base configuration.
For example, in production we want to increase the number of replicas and define how much resources a pod can use. So we create the two following files in the /prod folder.
replica_count.yaml (Note: Kustomize doesn't care about the name)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment # Name of the deployment to update
spec:
replicas: 6 # The new value
resources.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
containers:
- name: my-container
resources:
requests:
memory: "50Mi"
cpu: "50m"
limits:
memory: "500Mi"
cpu: "500m"
Now, to be sure that they will be used as patches, we must add the following code bloc in kustomization.yaml in the /prod folder.
patches:
- replica_count.yaml
- resources.yaml
We listed the two newly created files containing the new values.
Patch Strategic Merge
Sometimes, we don't want to override the value of a list, but add something in the list. In this case, we use patchesStrategicMerge.
For example, if I want to add an environment variable to my container, I should :
- create a file with the new environment variables to add in the /prod folder
env.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
containers:
- name: my-container
env:
- name: ENVIRONMENT
value: Production
- add the following bloc in kustomization.yaml
patchesStrategicMerge:
- env.yaml
Then, when it will be deployed in production, the container will have these environment variables :
- TEST : TODO
- ENVIRONMENT : Production
Generators
In Kustomize, some parameters exist to generate configmaps and secrets. Both are similar, so we will do the example with the configMapGenerator.
configMapGenerator:
- name: example-config
namespace: example
#behavior: replace
files:
- configs/config.json
In this code that we can found in the kustomization.yaml file, a configmap named "example-config" will be created in the example* namespace with the content of **configs/config.json as value.
In the commented line, we can see the parameter behavior which allows us to replace an existing configmap instead of creating a new one.
Images
The last parameter that we will see today allows us to do some updates about the images used in our configurations
Definition example in kustomization.yaml
images:
- name: hello-world
newTag: linux
newName: ubuntu
In this example, we see 3 parameters:
- name - To find all the images matching this name where the override will occur
- newTag - The new tag of the image to use
- newName - The new name of the image to use
If you are curious and wanted to go further, please go check the documentation. We only saw a part of Kustomize.
I hope it will help you! 🍺
Don’t hesitate to give me feedback here, on twitter or by LinkedIn, I will be glad to read it. You can use the same links if you want to contact me or want to collaborate with me.
Top comments (0)