kustomize-controller
Published on February 12, 2024
The kustomize-controller
is looking at a Kustomization
custom resource in the cluster (One entry point Kustomization
was created on flux bootstrap
).
Kustomization
custom resource will contain a sourceRef
and a path
to a folder.
That folder can contain a kustomization.yaml
file, which will contain a list of resources, and the kustomize-controller
will strive to get the cluster state according to those resources.
If the kustomization.yaml
file is not present, then the kustomize-controller
will generate a kustomization.yaml
file based on the resources in the folder.
kustomize and kustomize-controller do not get confused
There is the kustomize
tool, and the kustomize-controller
which is part of the flux
project.
In addition There are two different Kustomization
resources, one from the kustomize.config.k8s.io/v1beta1
API group, which is client only and not created in the cluster, and one from the kustomize.toolkit.fluxcd.io/v1
API group which is a custom resource added to our cluster.
We need to understand each of these components and how they relate to each other.
kustomize
kustomize
kind of remind me of a very simplified version of helm
. You feed kustomize with a Kustomization
resource that looks like so:
Here’s an example of a Kustomization
resource, kustomize
based on this file will create the group of resources which we can feed kubectl
and those resources will be created.
It’s important to note that this Kustomization
resource is not a custom resource in the cluster, it’s just a file that kustomize
will use to generate resources.
kustomize
can be externally installed but it’s also now baked as part of kubectl
.
Will show you the resources that will be created.
Will create the resources.
This is not a kustomize
lesson and there are plenty good lessons about this tool, and I’m assuming you have a bit of experience with it.
We will however do a recap of the important features of this tool which we are going to utilize.
Install kustomize
Although kustomize
is now baked into kubectl
, you can still install it separately.
The easiest way is using homebrew
:
After installation you will have the kustomize
command available. This command will not effect your cluster, and personally I love to use it as a tool to understand what is created, and patched.
kustomization.yaml
There is a special meaning for files named kustomization.yaml
in a directory. Kustomize is given a directory, and it will look for a file named kustomization.yaml
in that directory. If that file does not exist then kustomize will fail to generate the resources.
kustomize create
kustomize can help you create a kustomization.yaml
file based on the resources in a directory.
You can cd into a directory containing yaml
resources, and you can run kustomize create --autodetect --recursive
and it will generate a kustomization.yaml
file based on the resources in that directory.
This is a very useful feature, and it’s the feature that the kustomize-controller
will use if the kustomization.yaml
file is not present.
kustomize build
I use this command often, it’s a way to see the resources that will be created by kustomize-controller
.
The command will not actually create the resources, it will just show you the resources that will be created.
patch
It’s important to go over this feature in the Kustomization
resource since we will use it often, especially when we have similar configurations between clusters.
For example we might have a base infastructure configuration between the clusters, but there are some minor configuration changes in that base infastructure between the clusters, often
kustomization patches will allow us that distinction.
There are 2 types of patches, patchesStrategicMerge
and patchesJson6902
.
patchesStrategicMerge
This is a list of file paths, and kustomize will merge these files with the resources in the kustomization.yaml
file.
In this example we will use the patch.yaml
to add annotation to the source-controller
ServiceAccount
This is the content of the file patch.yaml
, and it will add the annotation to the source-controller
ServiceAccount
.
It will look for the ServiceAccount
with the name source-controller
in the flux-system
namespace and it will add the annotation.
patchesJson6902
In this merge type, we can use a json
patch to merge with the resources in the kustomization.yaml
file.
This can be used for a more surgical approach to patching a field or multiple fields instead of merging bulk of data.
and in the patch.yaml
file we can have the following content:
We will use this patch technique when we talk about workload identity and accessing out private helm repository.
overlays
Another feature we will use often is the overlays
feature. This is a way to have a base configuration and then have different configurations for different clusters.
Let’s examine the following simple example. In the root directory create a folder called apps
, this folder will contain our clusters app configurations.
Later in the course we will have a slight difference between the staging
and production
apps, they will be installed by our private helm which we will configure in future lesson, and we will distinguish between chart versions with canary that will be loaded to staging
cluster and the stable version that will be loaded to production
cluster.
In the apps
directory create a base
directory, which will contain app configurations that are common to all clusters.
Let’s create the file release.yaml
in the apps/base
directory with the following content:
Notice that we omitted the version
field, we will use the overlays
feature to add this field per cluster, loading canary
versions to the staging cluster.
In the apps/base
create also a kustomization.yaml
file with the following content:
For now this kustomization.yaml
file only package all the resources in the directory, but we will use it later to add common labels, namespace and other configurations that relates to all the resources in this directory.
In the apps
directory create a staging
directory, which will contain app configurations that are specific to the staging
cluster.
In the apps/staging
directory create a kustomization.yaml
file with the following content:
We added a patches
field that targets the HelmRelease
kind, and we will use this field to add the version
field to the HelmRelease
resource.
Create the file release.yaml
in the apps/staging
directory with the following content:
We will create the same files in the apps/staging
also in the apps/production
directory, but the version
field will be different.
Modify the file apps/production/release.yaml
to have the following content:
We can test our overlays by running the following command:
You should see how the configurations for the 2 clusters are identical except for the version
field. Overlays usually combines with patches
to create similar clusters with slight differences.
This is the recap we need about the kustomize
tool, Now let’s move to the kustomize-controller
and the Kustomization
custom resource.
kustomize-controller
The kustomize-controller
is a kubernetes operator which is using a Kustomization
custom resource that points a path in a source (usually a git repository).
Based on kustomization.yaml
in the path (or if not present it is generated) resources are created in the cluster, and the state of our cluster is maintained.
Kustomization custom resource
After installing flux we now have 2 Kustomization
resources, one from the kustomize.config.k8s.io/v1beta1
API group, and one from the kustomize.toolkit.fluxcd.io/v1
API group.
It was confusing for me at first, and it’s important to understand the difference between the two, and look at the apiVersion
field to distinguish.
Remember that flux resources have <controller>.toolkit.fluxcd.io
in the apiVersion
.
Here’s an example of a flux Kustomization
resource and we will go over the important fields:
Let’s go over the important fields:
- metadata.namespace - The
Kustomization
resource doesn’t have to be in theflux-system
namespace, Although I usually put it there. - spec.interval - The interval in which the
kustomize-controller
will examine the resource, check the cluster, and correct any drifting to match the cluster state to the resources in thekustomization.yaml
file. - spec.path - The path to the folder in the source (git repository in this case) that contains the
kustomization.yaml
file (if nokustomization.yaml
it will be generated - more on that later). - spec.prune - If set to
true
removed resources will be garbage collected, I turn this on must of the times. - spec.sourceRef - The
sourceRef
field is a reference to asource-controller
custom resource, in this course we will useGitRepository
custom resource - this points to where thepath
directory is located, and where our yaml files to apply reside.
kustomize-controller entry point
When we ran flux bootstrap
a flux Kustomization
resource was created in the flux-system
namespace:
This is our entry point for the kustomize-controller
and the path is set to ./clusters/staging
according to the --path
flag in the flux bootstrap
command.
kustomization.yaml generation
Notice that the path ./clusters/staging
does not contain a kustomization.yaml
yet the kustomize-controller
did not complain.
If the Kustomization
resource is pointing to a path that does not contain a kustomization.yaml
file, then the kustomize-controller
will generate a kustomization.yaml
(virtually not as an actual file).
The way it creates the kustomization.yaml
is by running kustomize create --autodetect --recursive
on the path.
Let’s try to run it ourselves:
You will see that a kustomization.yaml
file was created in the clusters/staging
directory, and it contains the resources in the directory and also the subdirectories (like flux-system
dir). It also included the namespace.yaml
from the first lesson, this is how our namespace was created in the first lesson, by the kustomize-controller
automatically generating a Kustomization
resource, in the clusters/staging
folder.
Arranging the repository
Now that we understand the kustomize-controller
and the Kustomization
resource, let’s arrange our repository, to be more fitting for larger projects.
Move the clusters/staging/namespace.yaml
to the folder: apps/base/namespace.yaml
this will represent the namespace where we will place our apps (It’s important to note that I usually recommend not to throw all the apps in a single namespace if you have a large project, more logical seperation is recommended, but for the sake of simplicity we will use a single namespace for all our apps in this course).
We do need to modify the apps/base/kustomization.yaml
file to include the namespace.yaml
file:
Delete all the release.yaml
resources that we created, those were just for demonstration purposes, we will create them again in future lesson when we learn about the helm-controller
.
Modify the apps/staging/kustomization.yaml
and apps/production/kustomization.yaml
file to include the apps/base
directory:
Also make sure you have a clusters/staging/apps.yaml
with the following code:
we prepared an apps overlay, and place the namespace creation in that directory. If we push our code we should see a namespace as well as an additional Kustomization
resource created:
Summary
In this lesson we learned about:
kustomize
- a tool that can generate resources based on akustomization.yaml
file, built-in in ourkubectl
client.kustomize-controller
which responds toKustomization
custom resource and keeps the cluster state in sync with the resources defined in akustomization.yaml
file.
We also learned about the Kustomization
resource, and created a basic overlay for our apps
as well as learned how to use patches
which will be handy to create slight differences in our overlays.
The full source code is available here