Kubes vs Kustomize

Though both Kubes and Kustomize build YAML files, they are quite different beasts. Kustomize is more like a kubectl feature that decorates YAML. Kubes is more like a tool. Kubes also builds YAML, but it also provides additional features.

Kustomize lets you customize your Kubernetes YAML files with additional kustomization.yaml files. The kustomization.yaml files contain configs that tell kubectl how to decorate existing Kubernetes YAML files in a template-free way.

Kubes lets you create Kubernetes files more directly. It handles layering and merging YAML files via a conventional structure. It also supports additional conveniences like building Docker images, CLI Customizations, Hooks, etc.

This article also covers more differences in detail: Kustomize vs Helm vs Kubes: Kubernetes Deploy Tools

Project Structures

Kustomize Project Structure

Kustomize doesn’t define a strict a project folder structure. You define any project structure you wish and use kustomization.yaml files to connect things together. Here’s a possible Kustomize example project structure:

├── base
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── dev
    │   ├── deployment.yaml
    │   ├── kustomization.yaml
    │   └── namespace.yaml
    └── prod
        ├── deployment.yaml
        ├── kustomization.yaml
        └── namespace.yaml

The provided structure allows you to use the same code to create different environments with overlays. The overlays/dev/kustomization.yaml file stitches the structure together.

overlays/dev/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
  - ../../base
patchesStrategicMerge:
  - deployment.yaml
namespace: demo-dev
resources:
- ./namespace.yaml

Kubes Project Structure

On the other hand, Kubes defines a conventional project structure. Here’s a project directory example:

.kubes/resources
├── base
│   ├── all.yaml
│   └── deployment.yaml
├── shared
│   └── namespace.yaml
└── web
    ├── deployment
    │   ├── dev.yaml
    │   └── prod.yaml
    ├── deployment.yaml
    └── service.yaml

A Kubes project structure also supports introduces a role concept or folder. The folder structure only shows a web role for simplicity. You can always add more roles. For example:

.kubes/resources/ROLE/deployment.yaml
.kubes/resources/clock/deployment.yaml
.kubes/resources/web/deployment.yaml
.kubes/resources/worker/deployment.yaml

Multiple Environments: Overlays vs Layering

Both Kustomize and Kubes allow you to use the same code to create multiple environments. They take different approaches, though.

Kustomize Overlays

Kustomize achieves multiple environments via kustomization.yaml and manually specifying and wiring how the files should merge. To create different dev and prod environments, we use overlays:

kubectl apply -k overlays/dev
kubectl apply -k overlays/prod

Kubes Layering

To deploy and create multiple environments like dev and prod with the same YAML, we use a different KUBES_ENV setting:

KUBES_ENV=dev  kubes deploy
KUBES_ENV=prod kubes deploy

The layering is achieved thanks to the conventional project structure. You don’t have to do any extra work, you just create pre-process base layer files or post-process environment specific layer files.

DRY Differences

DRY with Kustomize

Both Kubes and Kustomize try to achieve DRY YAML code. It tries to avoid YAML duplication.

Kustomize takes a purist viewpoint. You use kustomization.yaml to decorate original YAML. The original files are untouched and left as-is. Here are example overlays files.

overlays/dev/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
  - ../../base
patchesStrategicMerge:
  - deployment.yaml
namespace: demo-dev
resources:
- ./namespace.yaml

overlays/prod/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
  - ../../base
patchesStrategicMerge:
  - deployment.yaml
namespace: demo-prod
resources:
- ./namespace.yaml

While duplication is reduced since the original base/deployment.yaml is left untouched, there is duplication in the kustomization.yaml files.

DRY with Kubes

With Kubes, DRY has handled by layering and templating support. Let’s first take a look at how layering removes duplication.

Let’s focus on deployment.yaml to explain and understand layering. Here are the files that get layered.

.kubes/resources/base/all.yaml            # common YAML for all files
.kubes/resources/base/deployment.yaml     # common YAML for deployment kind
.kubes/resources/web/deployment.yaml
.kubes/resources/web/deployment/dev.yaml  # env-specific that overrides YAML

Each file is merged together and produces a resulting YAML file:

.kubes/output/web/deployment.yaml

Additionally, you can use ERB templating to keep things DRY. Here’s an example:

.kubes/resources/shared/namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: demo-<%= Kubes.env %>
  labels:
    app: demo

Notice the <%= Kubes.env %> templating logic. When is KUBES_ENV=dev, then name: demo-dev. When is KUBES_ENV=prod, then name: demo-prod.

You can even define your own custom helpers for even more control. See: Helpers Docs

Kubes Features

Kubes does a lot more than building YAML files. Here’s a list of features:

  • Automation: Builds the Docker image and updates the compiled YAML files
  • Syntactic Sugar: Use an ERB/YAML or a DSL to write your Kubernetes YAML files. You can use a mix of DSL and YAML definitions in the .kubes/resources folder.
  • Layering: Use the same Kubernetes YAML to build multiple environments like dev and prod with layering.
  • Secrets: Use helpers like aws_secret, aws_ssm, and google_secret to build Kubernetes secrets.yaml from secret providers designed for it.
  • Generators: Kubes ships with a few generators to help you get building with Kubernetes quickly. See: Generator Docs.
  • CLI Customizations: You can customize the cli args.
  • Hooks: You can also run hooks before and after kubes and kubectl commands.
  • Automated Suffix Hashes: Automatically appends a suffix hash to ConfigMap and Secret resources. More details in ConfigMap and Secret docs.
  • Kustomize Support: If you’re a kustomization user, you can use it with Kubes. More details in Kustomize Support Docs.
  • Auto Context Switching: Map dev to a specific kubectl context and prod to another kubectl context and Kubes can switch them automatically so you won’t have to remember. More details in Auto Context Docs.
  • Ordering: Kubes run kubectl apply to create resources in the correct order. For deleting, it kubes will run kubectl delete in the correct reverse order. The order is also customizable.

Kubes Kustomize Support

All of that being said, Kubes also supports Kustomize. So if you’re a Kustomize user, you can use it with Kubes. Here’s an example Kustomize structure with Kubes.

.kubes/resources
├── base
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── dev
    │   └── kustomization.yaml
    └── prod
        └── kustomization.yaml

In Kustomize mode, Kubes will call kubectl apply -k. Here’s an example:

kubes deploy overlays/dev

This calls:

kubectl apply -k .kubes/output/overlays/dev

Summary

Kustomize and Kubes are quite different. Kustomize is more of a feature to kubectl and takes on a purist view on changing YAML files for deployment. Kubes has similar merging concepts as Kustomize in the form of layering. Kustomize is more about control things with additional kustomization.yaml configurations. Whereas, Kubes takes more of a convention-over-configuration approach, so it just works without having to do extra prewiring work. Kubes additionally helps you build your Docker images.