0

I'd understood that Kustomize would be the solution to my Kubernetes configuration management needs where, for example, if I want maxReplicas for a resource to be 3 on my dev and test environments but 7 in production, I could do that easily. I imagined there'd be a base file, and then an overlay file that would respecify just the values needing changing. My goal is that if I have multiple configurations (configurations? nodes? clusters? I'm still having trouble with K8s terminology. I mean dev, test, prod.), any time a value common to all of them needed changing, I could change it in one place, the base configuration, instead of in three different config files. Essentially, just as in programming, I want to factor out what's common to all the environments.

But I'm looking at https://www.densify.com/kubernetes-tools/kustomize/ and getting a different impression. Here, the dev version of an hpa.yml file is only meant to change the values of maxReplicas and averageUtilization. So I'd thought the overlay would look as follows, in the same way that, in a .NET Core application, appsettings.dev.json only needs to specify the settings from appsettings.json that it's overriding:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-deployment-hpa
spec:
  maxReplicas: 2
    target:
      averageUtilization: 90

instead of the whole definition that's in the example given. So, if I started with all instances having minReplicas = 1 and I wanted to change it to 3 for all of them, I'd have make that change in every overlay instead of just in the base.

Is this correct? If so, is there a tool that will allow configuration management to work as I'm looking to have it work?

Green Grasso Holm
  • 468
  • 1
  • 4
  • 18

1 Answers1

2

Is this correct?

No.

Kustomize does not require to specify the entire resource in order to change a single value; the entire point of Kustomize is its ability to transform manifests through patches and other mechanisms to produce the desired output.

For example, assume the following layout:

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

In base/deployment.yaml we have:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: web
          image: docker.io/traefik/whoami:latest

And in base/kustomization.yaml we have:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
  app: kustomize-demo

resources:
- deployment.yaml

If in my dev environment I want to keep replicas: 1, I would create overlays/dev/kustomization.yaml like this:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

This simply includes the resources from base verbatim.

On the other hand, if in my production environment I want to run with three replicas, I would patch the Deployment resource in overlays/prod/kustomization.yaml like this:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

patches:
  - patch: |
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: demo
      spec:
        replicas: 3

This type of patch is called a "strategic merge patch"; you can also apply changes using "JSONPatch" patches. That might look like:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

patches:
  - target:
      kind: Deployment
      name: demo
    patch: |
      - op: replace
        path: /spec/replicas
        value: 3

The kustomize documentation has a variety of examples of patching and other transformations. For example, the commonLabels directive I show in base/kustomization.yaml uses the labels transformer to produce this output:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: kustomize-demo
  name: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kustomize-demo
  template:
    metadata:
      labels:
        app: kustomize-demo
    spec:
      containers:
      - image: docker.io/traefik/whoami:latest
        name: web

Notice how the labels defined in commonLabels have been applied both to:

  1. The top-level /metadata/labels element
  2. The /spec/selector/matchLabels element
  3. The /spec/template/metdata/labels element
larsks
  • 277,717
  • 41
  • 399
  • 399