Table of contents
- What is JsonPatches6902?
- Example with gitea
- Project structure
- Kustomization file overview
Kustomize is a supplement and very useful tool for kuberentes that is responsible for template management. One of the core functionalities is to create overriding rules on top of an existing template without changing the latter. While official documentation provides a great overview of the basic features such as adding namespace, prefixes, annotations, labels, it lacks an explanation of common scenarios where the need to add, remove or replace values of a base template. More precisely, I'll be focusing on
JsonPatches6902 and how to create them in, native for kubernetes, yaml format.
What is JsonPatches6902?
Let's start with the number first. There is an RFC6902 standard defines how to apply JSON patches. The original purpose of this standard is to eliminate bandwidth and CPU waste while processing large resources for HTTP requests: instead of sending entire JSON object (resource) via HTTP PUT/POST method, it allows to send only the modified part (patch).
According to the standard, there are 6 types of operations that can be performed on an object:
test. We will take a look at the first three since they have a more applicable sense to our use case. From a syntactical point of view, each operation must have
op member indicating one of the mentioned types, e.g.
In addition to that, operations must include a
path key. The value of the path is a location within the JSON document need to be modified and standardized by RFC6901:
The other key-value pairs of operation depend on the particular operation being performed.
Example with gitea
After we had a brief overview of the official standard, let's switch to kubernetes and see how this functionality can be used within kustomize.
Sometimes it's best to explain the concept by example and that's what we're going to do. Out test subject will be represented by gitea - self-hosted git service. This docker image is an excellent candidate for the scenario as it does support multiple environment variables and have a front-facing UI interface allows to see the changes applied through the patches.
As it's in the case for most of my articles, the full project can be found on GitHub. The structure can be represented in the following diagram:
|-- base gitea-pod.yaml gitea-service.yaml kustomization.yaml |-- overlays |-- add ... kustomization.yaml |-- remove ... kustomization.yaml |-- replace ... kustomization.yaml
At the simplest level, the codebase contains gitea pod and gitea service where both represent the base layer. There are two ways of how to deploy this configuration to, let's say, minikube environment:
kustomizepackage is installed:
kustomize build ./base | kubectl apply -f -
- if kubernetes version is higher than 1.14:
kubectl apply -k ./base
The base might not very useful in the beginning since the service is only reachable within kubernetes environment. In the next section, we will see how patches can help to expose the service so we can see a nice UI in the browser.
Going further through the overview, we have "overlays" that modify a common base. Each overlay is represented by a specific operation such as
replace which customizes and applies patches on top of the base while leaving the latter untouched. Later we will take a look into details of each operation.
To remove deployed configuration at any point of time run:
Kustomization file overview
kustomize can work properly only when
kustomization.yaml is present in the target folder. Here's an example from the codebase:
As you may notice, each key under the
target uses exactly the same value from the resource it's being applied to.
However, for some type of kubernetes primitives with the prefix before the slash (which called a "group") in
apiVersion field it's required to specify additional property called
group. Here's an example of
The full list of such objects and groups can be found in the article: Which Kubernetes
apiVersion Should I Use?
To apply this configuration, run:
kubectl apply -k ./overlays/add
When kubernetes finishes to prepare the environment you should be able to see gitea homepage by navigating to
http://<minikube-url>:30000 (usually, but not always, minikube IP is
192.168.99.100). Thanks to one of the applied patches which turned regular kuberetes service into a NodePort service, it became possible to reach the web-page from the browser. However, there are different types of
add operations and let's look at them at a closer level.
Add a member to an object
The patch illustrating this functionality is
gitea-pod-http-app-name-patch.yaml. It changes the default gitea website title to the value of
APP_NAME environment variable:
path field specifies a place in an object where to insert the required property:
containers is an array, we need to specify the item of the array needed to be updated. We only have one item and that's why the number is
0. Alternatively, we can indicate an exact index of an element or use
- which represents the last element of the array.
Patches applied to a service, work in exactly the same way:
By turning simple
Append to a List
gitea-pod-patch-sidecar-container.yaml patch appends sidecar container to the containers list in the pod:
Which results in the following output:
The sidecar container is not very useful in this particular example, but it demonstrates very well how to append an object to a list.
Replace allows changing a value on specified path. This particular patch changes the image version of the gitea. To apply the patch:
As a name suggests, removes a key on a specified path. To apply the configuration, run
This example removes
name key from the ports item within a service:
In this project, we used the name of the operations such as
remove as overlays. This allows to highlight the syntactical part in great detail, however, in the real world scenario, you may consider using more descriptive name relative such as
staging for overlays.