Getting Started

Kustomize For Kubernetes

Kustomize is a standalone tool to customise the creation of Kubernetes objects through a file called kustomization.yaml. It introduces a template-free way to customize application configuration. I think Helm is too much complicated, when you just want to update the name of the image in your manifest files. Let us explore Kustomize ❤️


Introduction


Kustomize lets you customize an entire Kubernetes application without touching the actual YAML files. All the customization can be specified and can also be overridden in a special file called kustomization.yaml file.

You have many layers and each of those is modifying the previous ones. Thanks to that, you can constantly write things above others without adding complexity inside your configuration. The result of the build will be the addition of the base and the different layers you applied over it.


Installation


Form Version 1.12 of Kubernetes, Kustomize is included in the Kubernetes installation file.


Setting Up


To start with Kustomize, you need to have your original yaml files describing any resources you want to deploy into your cluster. Those files will be stored for this example in the folder ./k8s/base/. Those files will NEVER (EVER) be touched, we will just apply customization above them to create new resources definitions.

You can build base templates (e.g. for dev environment) at any point in time using the command kubectl apply -f ./k8s/base/.

In this example, we will work with a service and a deployment resources:

apiVersion: v1
kind: Service
metadata:  
    name: kustomService
spec:  
    ports:    
      - port: 80
        targetport: 5000  
    selector:    
      app: Flask-app
apiVersion: apps/v1
kind: Deploy
mentmetadata:  
    name: Flask-app
spec:  
    selector:    
        matchLabels:     
             app: Flask-app  
    template:    
        metadata:      
            labels:        
                app: Flask-app    
        spec:      
            containers:      
                - name: app        
                image: kumar1996/anime        
                ports:        
                    - name: http          
                    containerPort: 5000          
                    protocol: TCP

We wil add a new file inside this folder, named kustomization.yaml :

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:  
    - service.yaml  
    - deployment.yaml

This file will be the central point of your base and it describes the resources you use. Those resources are the path to the files relatively to the current file.

This kustomization.yaml file could lead to errors when running kubectl apply -f ./k8s/base/, you can either run it with the parameter —validate=false or simply not running the command against the whole folder.

To apply your base template to your cluster, you just have to execute the following command:

$ kubectl apply -k k8s/base

To see what will be applied in your cluster, we will mainly use in this article the command kustomize build instead of kubectl apply -k.

The result of kustomize build k8s/base command will be the following, which is for now only the two files previously seen, concatenated:

apiVersion: v1
kind: Service
metadata:
  name: kustomService
spec:
  ports:
  - port: 80
    targetport: 5000
  selector:
    app: Flask-app 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: Flask-app 
spec:
  selector:
    matchLabels:
      app: Flask-app 
  template:
    metadata:
      labels:
        app: Flask-app 
    spec:
      containers:
      - image: kumar1996/anime
        name: app
        ports:
        - containerPort: 5000
          name: http
          protocol: TCP

Kustomization


Now, we want to kustomize our app for a specific case, for example, for our prod environement. In each step, we will see how to enhance our base with some modification.

The main goal of this article is not to cover the whole set of functionnalities of Kustomize but to be a standard example to show you the phiplosophy behind this tool.

First of all, we will create the folder k8s/overlays/prod with a kustomization.yaml inside it.

The k8s/overlays/prod/kustomization.yaml has the following content:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
- ../../base

If we build it, we will see the same result as before when building the base.

$ kustomize build k8s/overlays/prod

This will output the following yaml:

apiVersion: v1
kind: Service
metadata:
  name: kustomService
spec:
  ports:
  - port: 80
    targetport: 5000
  selector:
    app: Flask-app 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: Flask-app 
spec:
  selector:
    matchLabels:
      app: Flask-app 
  template:
    metadata:
      labels:
        app: Flask-app 
    spec:
      containers:
      - image: kumar1996/anime
        name: app
        ports:
        - containerPort: 5000
          name: http
          protocol: TCP

Change the number of replica


we will extend our base to define variables not already defined.Here, we would like to add information about the number of replica. Like before, a chunk or yaml with just the extra info needed for defining replica will be enough.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: Flask-app
spec:
  replicas: 10
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate

Now we add it to the list of patchesStrategicMerge in the kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
- ../../base

patchesStrategicMerge:
- replica-and-rollout-strategy.yaml

The result of the command kustomize build k8s/overlays/prod give us the following result

apiVersion: v1
kind: Service
metadata:
  name: kustomService
spec:
  ports:
  - port: 80
    targetport: 5000
  selector:
    app: Flask-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: Flask-app
spec:
  replicas: 10
  selector:
    matchLabels:
      app: Flask-app
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: Flask-app
    spec:
      containers:
      - env:
        - name: CUSTOM_ENV_VARIABLE
          value: Value defined by Kustomize ❤️
        image: kumar1996/anime
        name: app
        ports:
        - containerPort: 5000
          name: http
          protocol: TCP

And you can see the replica number and rollingUpdate strategy have been applied above our base.


Conclusion


We see in these example how we can leverage the power of Kustomize to define your Kubernetes files without even using a templating system. All the modification files you made will be applied above the original files without altering it with curly braces and imperative modification.

There is a lot of advanced topic in Kustomize, like the mixins and inheritance logic or other directive allowing to define a name, label or namespace to every created object… You can follow the official Kustomize github repository to see advanced examples and documentation.

Subscribe to Developer Stack

Get the latest posts delivered right to your inbox