Nicolas Kovacs

Nicolas Kovacs

kustomize-for-managing-kubernetes-manifests thumbnail image

Kustomize for managing Kubernetes manifests

k8s

With Kustomize we will be able to manage easily multiple K8S YML files for multiple configurations. It will act like a YML files merger which will be easier to manage a real world application or infrastructure.

Prerequisites and objectives

You should have followed the Kubernetes(K8S) Workshop - Part 1 or have basic knowledge of Kubernetes in a declarative way.

Let's do it

Install Kustomize

$ brew install kustomize

We may use a file structure like so :

.
└── k8s
    └── kustomize
        ├── base
        │   ├── kustomization.yml
        │   ├── deployment.yml
        │   └── service.yml
        └── overlays
            ├── dev
            │   ├── kustomization.yml
            │   └── additional.yml
            ├── int
            │   └── kustomization.yml
            ├── qa
            │   └── kustomization.yml
            └── prd
                └── kustomization.yml

Important part here is the concept of base and overlays, we can define default K8S object in base and customize them for our multiple environments. We can eventually add specific object to one environment, for example in dev we may need to handle more thing than on a real environment. Important files are kustomization.yml in each sub folders. It's important to respect the filename but It can be .yml or .yaml

Use kustomize

  • Create folders and file like the schema above (no need to create all env).
mkdir -p k8s/kustomize/base
mkdir -p k8s/kustomize/overlays/dev
mkdir -p k8s/kustomize/overlays/prd
touch k8s/kustomize/base/kustomization.yml
touch k8s/kustomize/base/deployment.yml
touch k8s/kustomize/base/service.yml
touch k8s/kustomize/overlays/dev/kustomization.yml
touch k8s/kustomize/overlays/dev/mongodb.yml
touch k8s/kustomize/overlays/prd/kustomization.yml

Base

# k8s/kustomize/base/kustomization.yml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yml
  - service.yml
# k8s/kustomize/base/deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
# k8s/kustomize/base/service.yml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Dev

# k8s/kustomize/overlays/dev/kustomization.yml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
  - mongodb.yml
# k8s/kustomize/overlays/dev/mongodb.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mongodb
  template:
    metadata:
      labels:
        name: mongodb
    spec:
      containers:
        - name: mongodb
          image: mongo:4.2.8
          ports:
            - containerPort: 27017

Prd

# k8s/kustomize/overlays/prd/kustomization.yml

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

We define all our base ressources and we use kustomization.yml file to include them. For overlays we relatively include the base.

We can now build files with kustomize to see the result

$ kustomize build k8s/kustomize/overlays/dev

It outputs a single YML file with all our resources defined (separated with ---).

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mongodb
  template:
    metadata:
      labels:
        name: mongodb
    spec:
      containers:
        - image: mongo:4.2.8
          name: mongodb
          ports:
            - containerPort: 27017
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:1.7.9
          name: nginx
          ports:
            - containerPort: 80

We can apply them if we want.

$ kustomize build k8s/kustomize/overlays/dev | kubectl apply -f -

Now let's try to override some configurations.

# k8s/kustomize/overlays/prd/kustomization.yml

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

patchesStrategicMerge:
  - deployment-prd.yml
  • Create a new file k8s/kustomize/overlays/prd/deployment-prd.yml and we will override some value of our base deployment.
# k8s/kustomize/overlays/prd/deployment-prd.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1024Mi"
              cpu: "1000m"

We changed for example the the number of replicas and we set some resources allocation and limits.

  • Build It again
kustomize build k8s/kustomize/overlays/prd
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:1.7.9
          name: nginx
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: 1000m
              memory: 1024Mi
            requests:
              cpu: 250m
              memory: 512Mi

We can also change the docker image version nginx:1.7.8 instead of nginx:1.7.9

# k8s/kustomize/overlays/prd/kustomization.yml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patchesStrategicMerge:
  - deployment-prd.yml
images:
  - name: nginx
    newTag: 1.7.8

This can be also done with command line (inside the overlay folder) kustomize edit set image nginx:1.7.8

$ kustomize build k8s/kustomize/overlays/prd
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - image: nginx:1.7.8
          name: nginx
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: 1000m
              memory: 1024Mi
            requests:
              cpu: 250m
              memory: 512Mi

Thanks to kustomize we can now handle and merge YML files easily, It offers other features that you may want like :

Another useful option is generatorOptions, like so, you can disable the suffix generation when applying files (eg: my-secret-34bfD will be my-secret)

kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1
# It's a good practice to add the namespace to kustomization files
# It can prevent you to apply accidentally namespaced object to the wrong one, in case of wrong context
# I usually do It once, in base/kustomization.yml
namespace: my-namespace
resources:
  - my-deployment.yaml

generatorOptions:
  disableNameSuffixHash: true
← Back to home