KUSTOMIZE

Install

curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash

Usage

build and apply

kustomize build . | k apply -f -

or via kubectl

k apply -k . 

Create kustomization.yaml using files in current directory

kustomize create --autodetect

Check for all configurable options inside kustomization.yaml on https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# list of local files
# other options can be some other base folder like ../../base 
# or external resources url as `github.com/lordofthejars/mysql`
resources:
- deployment.yaml
- namespace.yaml
- service.yaml
# updating image on the deployment
# another option can be to use `kustomize edit set image 'IMAGE_NAME:TAG'`
images:
- name: lordofthejars/pacman-kikd
  newTag: 1.0.1
# updating any field(.spec.replicas in Deployment and .spec.type in Service) in the objects listed inside `resources` objects
patches:
  - target:
      version: v1
      group: ""
      kind: Service
      name: pacman-kikd
      namespace: pacman
    patch: |-
      - op: replace
        path: /spec/type
        value: NodePort
  - target:
      version: v1
      group: apps
      kind: Deployment
      name: pacman-kikd
      namespace: pacman
    # define file which will be used for patching via `path: FILENAME`
    # path: external_patch.yaml
    # define patch as yaml 
    patch: |-
      # replace .spec.replicas
      - op: replace
        path: /spec/replicas
        value: 3
      # add .metadata.labels.testkey
      - op: add
        path: /metadata/labels/testkey
        value: testvalue

Patching

Patching can be specified in additional file as well.

external_patch.yaml

# replace .spec.replicas
- op: replace
  path: /spec/replicas
  value: 3
# add .metadata.labels.testkey
- op: add
  path: /metadata/labels/testkey
  value: testvalue

Patching can be done via Stategic Merge Patch(SMP) which is an incomplete YAML that is merged against a completed YAML file.

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./deployment.yaml
patches:
- target:
    labelSelector: "app.kubernetes.io/name=pacman-kikd"
  patch: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pacman-kikd
    spec:
      template:
        spec:
          containers:
          - name: pacman-kikd
            image: lordofthejars/pacman-kikd:1.2.0

Updating

Updating a kustomization.yaml

  • directly
  • via kustomize edit add|remove|set
kustomize edit set annotation 'test:mile voli disko'

will add to the kustomization.yaml

commonAnnotations:
  test: mile voli disko

Overlay

Here we will have one base folder which will serve as a default manifest location.Staging and production will have their changes in related folders and use base folder as a template for their environments.

./
├── base/
│   ├── deployment.yaml
│   └── kustomization.yaml
├── production/
│   └── kustomization.yaml
└── staging/
    └── kustomization.yaml

and

==> base/kustomization.yaml <==
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml

==> production/kustomization.yaml <==
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
namespace: production
namePrefix: production-
nameSuffix: -v1-2-0
images:
- name: nginx
  newTag: 1.17.1

==> staging/kustomization.yaml <==
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
namespace: staging
namePrefix: staging-
nameSuffix: -v1-2-0
images:
- name: nginx
  newTag: 1.17.2

ConfigMap

ConfigMap defined in kustomization.yaml will create a ConfigMap manifest for deployment resource automatically.Name of the configMap will be generated as hash with every new update.Thus, as configMap’s name is always updated and referenced in deployment manifest which will trigger rollout restart of the related deployment.

kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
configMapGenerator:
- name: pacman-configmap
  literals:
  - db-timeout=1000
  - db-username=Ada

when one trigger kustomoize build

$ kustomize build
apiVersion: v1
data:
  db-timeout: "1000"
  db-username: Ada
kind: ConfigMap
metadata:
  name: pacman-configmap-dbd7g9bff5             # hash is used 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
...
        volumes:
        - mountPath: /config
          name: config
      volumes:
      - configMap:
          name: pacman-configmap-dbd7g9bff5     # hash is used
        name: config
status: {}

Overlay for ConfigMap

ConfigMap values from bases may be overridden by adding another generator for the ConfigMap in the overlay and specifying the behavior field(merge,replace).

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
configMapGenerator:
- name: pacman-configmap
  files:
  - connection.properties

# base/connection.properties
db-url=prod:4321/db
db-username=ada

# staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
namespace: staging
namePrefix: staging-
nameSuffix: -v1-2-0
images:
- name: nginx
  newTag: 1.17.2
configMapGenerator:
- name: pacman-configmap
  behavior: merge
  literals:
  - db-username=Mile
  - db-host=localhost

when one trigger kustomize build from staging folder

~/test/staging $ kustomize build
apiVersion: v1
data:
  connection.properties: |
    db-url=prod:4321/db
    db-username=ada
  db-host: localhost
  db-username: Mile
kind: ConfigMap
metadata:
  name: staging-pacman-configmap-v1-2-0-bfb64g2g26
  namespace: staging
---
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
    mile: kitic
  name: staging-nginx-v1-2-0
  namespace: staging
...
      volumes:
      - configMap:
          name: staging-pacman-configmap-v1-2-0-bfb64g2g26
        name: config
status: {}

LINKS