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 runningkubectl 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