🔭Dive into Kustomize: A Minikube-Powered Hands-On Guide

This guide helps you get familiar with the cloud-native tool Kustomize in a Minikube environment.

Hello, and welcome to your Aiden's Lab Notebook.

In our last post, we got hands-on with Kubernetes Ingress on our local minikube cluster and even experienced some basic traffic routing.

This time, we're shifting gears from Kubernetes resources to a cloud-native tool within our minikube cluster. Specifically, we'll dive into simple Kubernetes configuration management using Kustomize.

Through this guide, you'll get to experience:

  • What Kustomize is, and

  • How it can help you manage Kubernetes deployment configurations systematically and easily

...all within your minikube environment.

I've designed this guide to be as intuitive as possible so you can follow along without a hitch. If you've been curious about Kustomize or interested in managing Kubernetes deployment configurations, be sure to check this out!

What is Kustomize?

Kustomize is a tool that helps you manage Kubernetes application configurations using plain YAML files, without needing templates.

Instead of having to learn a complex templating language, you use your existing YAML files for resource deployment and only modify the parts that need to change for different environments.

Plus, Kustomize is built into kubectl (version 1.14 and above), meaning you can use it right away without any separate installation, making it very accessible.

To use Kustomize, you'll typically work with Base configurationsOverlay configurations, and a manifest file called kustomization.yaml:

  • Base configuration: The fundamental YAML files for deploying Kubernetes resources (e.g., Deployment, Service).

  • Overlay configuration: Directories (e.g., dev, staging, prod) containing files that define environment-specific changes to the Base configuration.

  • kustomization.yaml:

    • Defines the list of resources, image information, etc., that Kustomize will reference.

    • Needed in both the directory containing the Base configuration and the directories for Overlay configurations.

By adopting Kustomize, you define your standard Kubernetes resource YAML files just once in the Base configuration. This helps avoid code duplication and makes maintenance easier.

Furthermore, because you can specify and manage only the necessary changes for each environment separately, it becomes easy to identify and track differences between environments.

These characteristics align well with GitOps workflows, aiding in the declarative management of Kubernetes resources.

Managing Nginx App Deployment Configurations with Kustomize

Alright, let's get hands-on and use Kustomize to manage our Kubernetes deployment configurations. We'll be doing this on the minikube cluster we've been using.

Here's the plan:

  1. First, define a basic Nginx app using a Base configuration.

  2. Then, specify different Nginx app replica counts for different environments (dev, prod).

  3. Finally, use kubectl's Kustomize commands to modify the Nginx app according to the dev or prod environment.

1. Creating YAML Files for the Base Configuration

As we just discussed, let's start by creating the Base configurations that will be common across all environments.

For this exercise, I first created a kustomize-test directory.

Inside it, I'll create a base directory and set up the configuration files like this:

base/
├── nginx-deployment.yaml # Defines Nginx Deployment and Service
└── kustomization.yaml

Before creating the Nginx Deployment manifest, let's first create a test Namespace in the terminal with the following command:

kubectl create ns kustomize-test

It's a good practice to create a separate Namespace for exercises or tests like this and work within it.

Back to our Nginx app manifest. In base/nginx-deployment.yaml, we'll define a Deployment that runs two Nginx Pods and a ClusterIP type Service.

# base/nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  namespace: kustomize-test # Specify our test Namespace
  labels:
    app: nginx
spec:
  replicas: 2 # Default number of replicas
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: kustomize-test
spec:
  type: ClusterIP
  selector:
    app: nginx # Matches the Pod labels in the Deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

And here's the content for the base/kustomization.yaml file, which includes the manifest for our Nginx deployment:

# base/kustomization.yaml

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

This will result in a base directory structure like the one below:

The configurations we've created in this base directory will serve as the foundation when we apply environment-specific changes.

2. Creating YAML Files for Overlay Configurations

With our Base configuration for the Nginx app deployment complete, let's now define how we want to modify this Nginx app for different environments.

Let's say we want to change the replica count of the Nginx Deployment (default is 2 in base) to 1 for the development (dev) environment and 4 for the production (prod) environment.

  • dev: Modify Nginx Deployment's replica count to 1.

  • prod: Modify Nginx Deployment's replica count to 4.

First, to create the Overlay configurations for each environment, navigate back to the kustomize-test directory and create a new overlays directory.

Inside the overlays directory, create dev and prod subdirectories. These directories will hold the definitions for our environment-specific changes.

So far, the structure of our kustomize-test directory should look like this:

Now, let's define the change for the dev environment – reducing the Nginx app's replica count to 1 – in a YAML file.

We'll name this YAML file replicas-patch.yaml.

In replicas-patch.yaml, we'll specify that the spec.replicas value in the Deployment defined in base should be changed to 1, like so:

The values for metadata.name and metadata.namespace fields in replicas-patch.yaml must match the values defined in the base Deployment.

# overlays/dev/replicas-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app # Name of the Deployment defined in base
  namespace: kustomize-test # Specify our test Namespace
spec:
  replicas: 1 # Specify the desired replica count for the dev environment

Next, in the same directory, create a kustomization.yaml file with the following content:

# overlays/dev/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base # Path to the base directory
patches:
  - path: replicas-patch.yaml

Here, patches is a field used to selectively modify or add specific parts of the resource YAML files defined in base.

In this exercise, we're applying a resource patch using replicas-patch.yaml, which only contains the change to the replica count from the base/nginx-deployment.yaml file.

Similarly, create replicas-patch.yaml and kustomization.yaml files inside the prod directory as follows:

# overlays/prod/replicas-patch.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app # Name of the Deployment defined in base
  namespace: kustomize-test # Specify our test Namespace
spec:
  replicas: 4 # Specify the desired replica count for the prod environment
# overlays/prod/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base # Path to the base directory
patches:
  - path: replicas-patch.yaml

Now, all our Overlay configuration files should be ready, looking something like this:

It's time to use kubectl commands to deploy the Nginx Deployment according to each environment.

3. Deploying the Nginx App for Each Environment

First, let's deploy the Nginx app using the default manifest files we defined in the base directory.

From your current terminal path, deploy the Nginx Deployment and Service with the following command:

kubectl apply -f base/nginx-deployment.yaml

As you can see in the image above, the Deployment (with 2 replicas) and Service defined in the base directory's manifest have been deployed.

Now, let's apply the Overlay configuration for the dev environment.

To deploy a specific environment's configuration defined with Kustomize to a Kubernetes cluster, you use the command kubectl apply -k {overlay_directory_path} in your terminal, targeting the corresponding Overlay directory.

Since we want to use the dev environment's Overlay configuration, we'll run the following command:

kubectl apply -k overlays/dev

If the dev environment's configuration we just defined was applied correctly, the Deployment's replica count should decrease to 1. Did it actually happen?

Success! The Nginx app deployment configuration for the dev environment has been applied correctly.

If we look at the Deployment's Events using the kubectl -n kustomize-test describe deployment nginx-app command, it shows that the replica count decreased from 2 to 1.

Now, let's apply the configuration for the prod environment. This configuration specifies an Nginx Deployment replica count of 4. Let's see if it's reflected.

Just like when we applied the dev environment, we'll use the kubectl apply -k {overlay_directory_path} command. This time, we'll specify the prod directory path, like so:

kubectl apply -k overlays/prod

After running the command in the terminal...

Just as we expected, the number of Pods for the Nginx Deployment has increased to 4 and they are starting up nicely!

If we check the Nginx Deployment's Event status with the kubectl describe command, it shows that the replica count increased from 1 to 4! 🎉

As we've seen, using Kustomize allows you to update resources deployed on a Kubernetes cluster differently for each environment, enabling flexible resource management based on the situation.

In this guide, we covered only simple settings like replica counts to help you quickly get a feel for and understand Kustomize.

In reality, you can also manage Kubernetes resources like ConfigMaps and Secrets with Kustomize. So, if you're operating or learning Kubernetes, I highly recommend getting to know Kustomize.

Wrapping Up

In this article, we went through a hands-on exercise of deploying an app differently for various environments using Kustomize, all on our minikube cluster.

Over a series of three posts, we've covered everything from minikube installation to Kubernetes practice and Cloud Native tool practice.

Given how widely Kubernetes is used and its importance, I wanted to provide you with an opportunity to study and test Kubernetes using minikube.

This concludes our minikube hands-on guide series. If you have any questions or topics related to minikube, Kubernetes, or Cloud Native tools that you'd like me to cover, please feel free to let me know.

I'll be back with a new topic in the next article.

Thanks for reading today!

✨Enjoyed this issue?

How about this newsletter? I’d love to hear your thought about this issue in the below form!

👉 Feedback Form

Your input will be help improve Aiden’s Lab Notebook and make it more useful for you.

Thanks again for reading this notebook from Aiden’s Lab :)