Kubernetes Configuration with Kustomize.
Tags: kustomize, kubernetes, devops, gitops
Published: 2023-07-28 01:25:29

Kubernetes is undeniably one of the most popular container orchestration tools available today, due to its ability to manage complex containerized applications seamlessly. Despite its powerful feature set, managing Kubernetes configurations can be a daunting task, particularly when dealing with environments that have minor differences. This is where Kustomize comes into play. Kustomize, a standalone tool now native to Kubernetes via `kubectl`, makes it easy to handle and organize Kubernetes configurations.

## What is Kustomize?

Kustomize is a configuration management tool designed specifically for Kubernetes. It was developed to solve the problem of customizing application configurations without the need to edit them directly. It works by allowing you to create a base configuration and then apply overlays to customize it for different environments.

With Kustomize, you can define a "base" configuration with common configuration settings, and then define "overlays" for each of your environments, e.g., development, staging, and production, that modify those base configurations as necessary.

## The Benefits of Kustomize
__1. Declarative Configuration Management__

Kustomize offers a fully declarative approach to configuration management. This means you declare the final state that you want, and Kustomize makes it happen. This model reduces the risk of human error, simplifies application management, and increases the predictability and repeatability of your deployments.

__2. Decoupling Configuration__

Kustomize helps decouple configuration from the application, which allows you to manage and scale your applications more effectively. This is achieved through the use of "base" and "overlay" configurations, providing a structured and clear separation between common and environment-specific configurations.

__3. Reduced Configuration Duplication__

By allowing the definition of base configurations, Kustomize helps to reduce duplication. You define common configurations once and apply overlays for specific environments, significantly decreasing the amount of copied and pasted configuration code.

__4. Secret and ConfigMap Generation__

Kustomize can create Kubernetes Secret and ConfigMap resources from files or literals without requiring you to write the configuration YAML directly. This feature is particularly useful for managing sensitive data, such as API keys or passwords, and reduces the risk of accidentally exposing such data.

__5. Template-Free__

Unlike Helm, another popular Kubernetes package manager, Kustomize doesn’t rely on templates. Instead, it uses standard Kubernetes YAML files that can be easily validated and processed. This reduces complexity and makes it easier for developers to understand and work with the configurations.

__6. Native Integration with kubectl__

Kustomize is integrated natively into kubectl from Kubernetes v1.14 onwards. This allows you to use Kustomize’s features directly with kubectl apply -k, making it easier to work with without the need to install additional software.

## A Simple Example

Below is a basic example of using Kustomize to handle multi-environment configuration.

First, create a base configuration. Let's say it's a simple deployment of a Nginx server:

### Base Configuration

```yaml
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
```
```yaml
# base/kustomization.yaml
resources:
- deployment.yaml
```
### Development Environment
In the development environment, you want to increase the number of replicas to 3:

```yaml
# overlays/development/kustomization.yaml
bases:
- ../../base
patchesStrategicMerge:
- patch.yaml
```
```yaml
# overlays/development/patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
```
### Staging Environment
In the Q&A environment, you want to keep the number of replicas at 1, but use a different image version:
```yaml
# overlays/staging/kustomization.yaml
bases:
- ../../base
patchesStrategicMerge:
- patch.yaml
```
```yaml
# overlays/staging/patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.16.1
```
### Production Environment
In the production environment, you want to increase the number of replicas to 5 and use the latest stable Nginx image:
```yaml
# overlays/production/kustomization.yaml
bases:
- ../../base
patchesStrategicMerge:
- patch.yaml
```
```yaml
# overlays/production/patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.18.0
```
Now, you can build and apply these configurations with kustomize and kubectl. Here's how you do it for each environment:

```sh
~/the-solution
.
├── base
│   ├── deployment.yaml
│   └── kustomization.yaml
└── overlays
    ├── development
    │   ├── kustomization.yaml
    │   └── patch.yaml
    ├── production
    │   ├── kustomization.yaml
    │   └── patch.yaml
    └── staging
        ├── kustomization.yaml
        └── patch.yaml
```

```sh
# Apply the development configuration
kustomize build overlays/development | kubectl apply -f -

# Apply the Q&A configuration
kustomize build overlays/staging | kubectl apply -f -

# Apply the production configuration
kustomize build overlays/production | kubectl apply -f -
```
With this kind of setup, Kustomize lets you manage your different environments in an organized and efficient manner, keeping your base configuration clean and clear and minimizing duplication.