DEV Community

Maxime Guilbert
Maxime Guilbert

Posted on

What is Kustomize ?

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>
Enter fullscreen mode Exit fullscreen mode

Then, we discover that we can directly target a complete folder instead of a file

kubectl apply -f <folder>
Enter fullscreen mode Exit fullscreen mode

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 }}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

configmap.yaml

 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: example-config
   namespace: example
 data:
   config.json: |
     {
       "environment" : "test"
     }
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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\
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • add the following bloc in kustomization.yaml
patchesStrategicMerge:
  - env.yaml
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)