Kustomize GitOps

pbates | May 4, 2022, 1:19 a.m.

Kustomize GitOps with Flux

What is Kustomize? Simply Kustomize handles the configuration management of manifest states.
These manifests or Kubernetes objects are manged and customized by the CLI configuration manager.
The great news is if you have Kubectl >= 1.14 you already have Kustomize CLI. If you don’t have
Kubectl installed see this article or these Install docs.

Flux Bootstrap

Once Flux is bootstrapped in a kubernetes cluster communication is established
with the single source of truth. Flux components are created during the bootstrap process, those
manifests are pushed back to the newly created repo. A common description of this repo is called the
Flux Fleet repo.

Flux-Fleet-Repo
│   README.md
│ 
└───flux-system
│   │   gotk-components.yaml
│   │   gotk-sync.yaml
│   │   kustomization.yaml

Kustomization Repositories and Sources

Adding repositories and kustomizations via the CLI or manifests? Following the single source of
truth by declaring the manifests is the GitOps way.

GitRepository API

Using this API will define a Source producing a tarball Artifact for
a Git repository revision. To create a manifest only a few declarations need to be made
such as the following.
- name
- namespace
- a repo url and its branch reference
- and finally an interval for it to check

To be able to reach a private and secure repository a secret will need to be created. This field is
an optional one which references a Secret that must be in the same namespace. The following command
flux create secret git [name] [flags] will help with generating a Kubernetes secret.
The ssh key outputted which will need to be added to you Deploy Keys see docs.
The secret reference can then be added to the final GitRepository source.

Source-Controller documentation here

kustomize-repo-source.yaml

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: repo-source
  namespace: flux-system
spec:
  interval: 30s
  ref:
    branch: master
  secretRef:
    name: secret-auth
  url: ssh://gitlab-repo/your-user/your-repo.git
Flux-Fleet-Repo
│   README.md
│ 
└───flux-system
│   │   gotk-components.yaml
│   │   gotk-sync.yaml
│   │   kustomization.yaml
└───repo-sources
│   │   kustomize-repo-source.yaml

Kustomization API

The kustomize-controller is a Kubernetes operator which has its own continuous delivery
pipeline. Even if a repo is made up entirely of native Kubernetes manifests a Kustomization file
will be automatically created and referenced. The kustomization object will watch the referenced
source object for revision changes. If necessary it can “remove” prune objects from an
updated manifest.

Before any changes are made to the environment a dry run validates the build
output. Any errors from the build will be displayed as a kubernetes event in the flux-system namespace.
Any status changes are also presented in the kubernetes events. The kustomize-controller also
monitors the health of deployed workloads.

Kustomize-Controller documentation here

kustomizations.yaml

apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: production
  namespace: flux-system
spec:
  interval: 30s
  path: ./
  prune: true
  sourceRef:
    kind: GitRepository
    name: production-manifests
Flux-Fleet-Repo
│   README.md
│ 
└───flux-system
│   │   gotk-components.yaml
│   │   gotk-sync.yaml
│   │   kustomization.yaml
└───repo-sources
│   │   kustomize-repo-source.yaml
└───kustomize-sources
│   │   kustomizaitons.yaml

Kustomize

Layering manifests on top of a base configuration is one of the many strengths offered by Kustomize.
The basic concept of Kustomize are bases and overlays. An overlay file can refer to a single or
multiple base configurations. An overlay references a base configuration, a base kustomization
has no knowledge of overlays.

GIT REPOSITORY

/Application
│   README.md
│ 
└───base
    └───kustomization.yaml
    │   deployment.yaml
    │   service.yaml
    │   ingress.yaml
    │   configMap.yaml
└───overlays
    │   production
    │   └───kustomizations.yaml 
    │   │   prod-custom-rds-url.yaml
    │   │   prod-replica-count.yaml
    │   staging
    │   └───kustomizations.yaml
    │   │   staging-custom-rds-url.yaml

The base folder contains the static common manifests for both environments. These are the minimum
resources necessary to deploy the application. Environments restricted to a particular setup such
as staging and production are contained in the overlays’ folder. Within each directory a kustomization.yaml
file is placed.

YAML for breakfast, lunch, and dinner

base/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - ingress.yaml
  - service.yaml
  - configMap.yaml
  - deployment.yaml

Base directory contains the plain resources used to launch the application without environment
specificity. The application may need to have a separate environment that during testing. This could
be a separate database to safeguard the production data.

overlays/staging/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
- ../../base

patchesStrategicMerge:
- staging-custom-rds-url.yaml

overlays/staging/staging-custom-rds-url.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: my-app
          env:
            - name: RDS_URL_ENV
-             value: https://rds_URL.com

Another possibility would be to handle traffic to the application. Increasing replica count to
the production manifests to reduce load on the system.

overlays/production/kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
  - ../../base

patchesStrategicMerge:
  - prod-custom-rds-url.yaml
  - prod-replica-count.yaml

overlays/production/prod-replica-count.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 10
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate