Kustomize 101

Kustomize introduces a template-free way to customize application configuration that simplifies the use of off-the-shelf applications.

– kustomize.io

Kustomize for Kubernetes application customization

The first time I read that statement, well…. I read it again…and again. It never really sank in until I started to play with some examples. Hopefully this brief article can clear up any confusion and showcase the power of using Kustomize.

Kustomize allows you to “patch” existing manifest files with your own customizations. The idea is that you have a set of base manifests that contain the core of your application and have pieces of it swapped out on the fly. For example, you can create customizations that allow you to change out the image tag of your deployment. This will allow you to introduce changes without every modifying the source material.

Kustomize is built-in to kubectl as of version 1.14 so there is not requirement to download any additional files to start using it. It can still be installed separaely if you like, but for our purposes here I will use the kubectl commands.

The heart of Kustomize is the kustomization.yaml file. This is used to declare your resources (manifests) and any customization such as new annotations or custom lables.

Let’s start simple with an echo deployment/service. The files for this article can be downloaded from our git page and will act as our base config.

git clone https://github.com/gleamingthekube/kustomize.git

Change to the kustomize/kubernetes-echo folder. In here we have two folders, app and development. The app folder contains 3 files:

  • echo-deployment.yaml – A basic Kubernetes deployment using the echoserver image
  • echo-service.yaml – A Kubernetes service definition to expose the Kubernetes deployment
  • kustomization.yaml – A file telling Kustomize what manifests (resources) we should include in this build

Open up the kustomization.yaml and inspect the content, it is very basic. This will just tell kustomize to include the echo-service and echo-deployment manifests.

resources:
  - echo-service.yaml
  - echo-deployment.yaml

If you run the below it will instruct Kustomize to build the app folder.

$ kubectl kustomize app/

However, because we have not made any modifications yet all you will see is a concatenation of the service and deployment yaml. Note that nothing is actually created in the cluster in this step, this simply displays the merged manifest and nothing else.

Ok, so what was fairly boring, but necessary to setup the rest of the article. Continuing on, our app folder will be our base, that is where our main/base manifests live that we want to remain intact.

What about customizations? For that, we will move in to Overlays. The development folder will be used for customizations in our dev environment. The name is arbitrary and can be changed and/or nested as you see fit. This folder will also have it’s own kustomization.yaml file instructing Kustomize where to find the source material as well as your overrides.

Take a look at the development/kustomization.yaml, the first few lines define the base manifests we will work with. The path can be set as relative or absolute, in the example it is relative to the development folder (i.e, one level up and in the app/ folder). “bases” has been deprecated in newer releases and should be replaced with “resources”.

resources: 
  - ../app

Great! We have our base configured and a development branch where we will making making some customizations. We will make a minor modification to get a feel for the power of Kustomize. Currently, our base deployment is using the image echoserver:2.2, but we would like to run some tests against a slightly older version to make sure our code still works.

To do this, the image.yaml will be used to hold some of our overrides. The name can be whatever you like but I prefer to keep it as descriptive as possible for the customization I plan to make with it. We have copied part of the echo-deployment.yaml to this file so Kustomize knows how to find the data we want to update. This allows Kustomize to find the deployment by name, echo, and a path to the changes we are making.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  template:
     spec:
      containers:
      - image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
        name: echo

If we go ahead and run the kustomize build we will see our image has changed:

kubectl kustomize development/
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
        name: echo
        ports:
        - containerPort: 8080

Again, this just gives us a visual confirmation that we have applied the patches we wanted in place. We can use the kubectl apply command to create the resources.

kubectl apply -k development/

You will now have the echo service running with image version 2.1 in your cluster. A look back to the original manifests in the /app folder will show nothing has changed on the original files. This barely scratches the surface of what Kustomize has to offer. It will be revisited again in future articles to detail more of the config changes that can be applied.