Qingular

Helm and Kustomize

·CKAk8sPractice

Helm and Kustomize are the most commonly used application package management and configuration customization tools in the Kubernetes ecosystem, used to simplify application deployment and environment-specific configuration management.

← Back to CKA Practice Index

Overview

Helm and Kustomize are the two main tools for managing application deployment in Kubernetes. Helm uses Charts as its package format, supporting templated deployments and version management; Kustomize achieves configuration customization through an overlay mechanism without templates. While neither is a major focus in the CKA exam, they are very important in real-world work.


Part 1: Helm

1. Helm Basic Concepts

1.1 Helm Core Terminology

TermDescription
ChartA Helm package containing the YAML templates and configuration needed to deploy an application
ReleaseA deployed instance of a Chart in a cluster
RepositoryA Chart storage repository
ValuesConfiguration values passed to templates
TemplatesGo template files that generate Kubernetes manifests

1.2 Chart Directory Structure

mychart/
├── Chart.yaml          # Chart metadata (name, version, description)
├── values.yaml         # Default configuration values
├── values.schema.json  # JSON Schema validation for values
├── charts/             # Sub-chart dependencies
├── crds/               # CRD definitions
├── templates/          # Kubernetes manifest templates
│   ├── NOTES.txt       # Usage instructions after installation
│   ├── _helpers.tpl    # Template helper functions
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── hpa.yaml
└── README.md

2. Helm Installation and Repository Management

# Install Helm
# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# macOS
brew install helm

# Windows (choco)
choco install kubernetes-helm

# Verify installation
helm version

# Add Helm repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jetstack https://charts.jetstack.io

# Update repositories
helm repo update

# List repositories
helm repo list

# Search for Charts
helm search hub nginx                 # Artifact Hub search
helm search repo nginx                # Local repository search
helm search repo bitnami/nginx --versions  # List all versions

# View Chart information
helm show chart bitnami/nginx
helm show values bitnami/nginx
helm show readme bitnami/nginx
helm show all bitnami/nginx

3. Basic Helm Operations

3.1 Install and Uninstall

# Install a Chart (create a Release)
helm install my-nginx bitnami/nginx

# Install in a specific namespace
helm install my-nginx bitnami/nginx --namespace my-namespace --create-namespace

# Install with custom values file
helm install my-nginx bitnami/nginx -f custom-values.yaml

# Set values directly
helm install my-nginx bitnami/nginx --set replicaCount=3 --set service.type=NodePort

# Install from a local Chart
helm install my-app ./mychart/

# Dry-run before installation
helm install my-nginx bitnami/nginx --dry-run --debug

# Uninstall a Release
helm uninstall my-nginx
helm uninstall my-nginx --namespace my-namespace

# View installed Releases
helm list
helm list --all-namespaces
helm list -n my-namespace

3.2 Upgrade and Rollback

# Upgrade a Release
helm upgrade my-nginx bitnami/nginx

# Upgrade with new values
helm upgrade my-nginx bitnami/nginx --set replicaCount=5
helm upgrade my-nginx bitnami/nginx -f new-values.yaml

# Dry-run before upgrade
helm upgrade my-nginx bitnami/nginx --dry-run --debug

# Check upgrade status
helm status my-nginx

# View Release history
helm history my-nginx

# Rollback to the previous version
helm rollback my-nginx

# Rollback to a specific version
helm rollback my-nginx 1

# View differences between Release versions
helm get manifest my-nginx --revision 1 > v1.yaml
helm get manifest my-nginx --revision 2 > v2.yaml
diff v1.yaml v2.yaml

3.3 Viewing Release Information

# Get Release status
helm status my-nginx

# Get rendered manifests
helm get manifest my-nginx

# Get values
helm get values my-nginx

# Get all information
helm get all my-nginx

# Get NOTES.txt content
helm get notes my-nginx

# Get manifest for a specific revision
helm get manifest my-nginx --revision 2

4. values.yaml Customization

4.1 Values Override Priority

--set specified values > --set-file/--set-string > -f values file > values.yaml defaults

4.2 Values File Example

# my-values.yaml
replicaCount: 3

image:
  repository: nginx
  tag: "1.25"
  pullPolicy: IfNotPresent

service:
  type: NodePort
  port: 80

ingress:
  enabled: true
  hostname: example.com

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

persistence:
  enabled: true
  size: 8Gi
# Install using a values file
helm install my-nginx bitnami/nginx -f my-values.yaml

# Merge multiple values files
helm install my-nginx bitnami/nginx -f base.yaml -f production.yaml

# Set complex values
helm install my-nginx bitnami/nginx \
    --set replicaCount=3 \
    --set image.tag="1.25" \
    --set service.type=ClusterIP \
    --set ingress.enabled=true \
    --set ingress.hostname=myapp.example.com

5. Chart Creation and Management

# Create a Chart
helm create mychart

# Package a Chart
helm package mychart/

# Validate Chart syntax
helm lint mychart/

# View Chart dependencies
helm dependency list mychart/

# Update Chart dependencies
helm dependency update mychart/

# Push Chart to repository
helm push mychart-0.1.0.tgz my-repo

Part 2: Kustomize

6. Kustomize Basics

Kustomize has been built into kubectl since Kubernetes 1.14 and can be used directly via kubectl apply -k.

6.1 Kustomize Core Concepts

ConceptDescription
kustomization.yamlKustomize configuration file (required)
baseBase configuration directory
overlayEnvironment overlay configuration (dev/staging/prod)
patchPartial modifications to resources
transformerGlobal modifications (labels/annotations/names, etc.)
generatorDynamically generated resources (ConfigMap/Secret)

6.2 Typical Directory Structure

project/
├── base/
│   ├── kustomization.yaml
│   ├── deployment.yaml
│   ├── service.yaml
│   └── hpa.yaml
├── overlays/
│   ├── dev/
│   │   ├── kustomization.yaml
│   │   ├── patch-replicas.yaml
│   │   └── configmap-dev.yaml
│   ├── staging/
│   │   ├── kustomization.yaml
│   │   └── patch-resources.yaml
│   └── production/
│       ├── kustomization.yaml
│       ├── patch-ingress.yaml
│       └── secret-generator.yaml

7. Typical Kustomize Usage

7.1 base/kustomization.yaml

# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Referenced resource files
resources:
- deployment.yaml
- service.yaml
- hpa.yaml

# Add common labels to all resources
commonLabels:
  app: my-app
  managed-by: kustomize

# Add common annotations to all resources
commonAnnotations:
  environment: base
  project: my-project

# Namespace
namespace: my-namespace

# Name prefix
namePrefix: myapp-

7.2 overlays/dev/kustomization.yaml

# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Inherit from base
resources:
- ../../base

# Name suffix
nameSuffix: -dev

# Environment labels
commonLabels:
  env: dev

# Patches
patches:
# Strategic merge patch
- path: patch-replicas.yaml
  target:
    kind: Deployment
    name: my-app

# JSON patch (6902 format)
- patch: |-
    - op: replace
      path: /spec/replicas
      value: 1
  target:
    kind: Deployment
    name: my-app

# Replace images
images:
- name: nginx
  newName: myregistry.io/myapp
  newTag: dev-latest

# Generate ConfigMap
configMapGenerator:
- name: app-config
  literals:
  - ENV=dev
  - LOG_LEVEL=debug
  files:
  - configs/app.properties

# Generate Secret
secretGenerator:
- name: app-secret
  literals:
  - DB_PASSWORD=dev-password
  type: Opaque

7.3 Patch Examples

# overlays/dev/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: app
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 200m
            memory: 256Mi
# overlays/production/patch-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-service
            port:
              number: 80

8. Kustomize Commands

# Build and output YAML
kubectl kustomize base/
kubectl kustomize overlays/dev/
kustomize build overlays/production/

# Apply configuration
kubectl apply -k base/
kubectl apply -k overlays/dev/

# Delete configuration
kubectl delete -k overlays/dev/

# View diff
kubectl diff -k overlays/dev/

# Build and save to file
kubectl kustomize overlays/production/ > production-manifest.yaml
kubectl apply -f production-manifest.yaml

9. Helm vs Kustomize Comparison

FeatureHelmKustomize
ConceptPackage manager (Chart)Configuration customization (Overlay)
TemplatingGo templates (template)No templates (native YAML)
Version managementBuilt-in (Release versions)Requires Git
Rollbackhelm rollbackRollback via Git
Parameterizationvalues.yaml + --setpatches + generators
Learning curveSteeper (template syntax)Gentler (pure YAML)
Dependency managementSupports sub-chartsNot supported (requires Helm)
SharingHelm Hub / ArtifactHubRequires Git repository
Built-in kubectlNo (requires helm command)Yes (kubectl apply -k)
Best scenarioThird-party application deploymentInternal application environment management

Selection Advice

# Scenarios suitable for Helm:
# - Deploying third-party/community applications (nginx-ingress, prometheus, cert-manager)
# - Applications requiring version management and rollback
# - Complex applications requiring parameterized deployment

# Scenarios suitable for Kustomize:
# - Managing configuration differences across multiple environments (dev/staging/prod)
# - Teams preferring pure YAML over templates
# - Already have a large number of native Kubernetes YAML files
# - Need integration with CI/CD pipelines

10. Daily Operations Quick Reference

# --- Helm Quick Reference ---
helm repo add <name> <url>
helm repo update
helm search repo <keyword>
helm install <release> <chart> -f values.yaml --set key=value
helm upgrade <release> <chart> -f new-values.yaml
helm rollback <release> <revision>
helm uninstall <release>
helm list
helm history <release>

# --- Kustomize Quick Reference ---
kustomize build overlays/prod/ > output.yaml
kubectl apply -k overlays/dev/
kubectl diff -k overlays/prod/
kubectl delete -k overlays/staging/

CKA Exam Key Points

  1. Helm and Kustomize are a very small portion of the CKA exam -- but basic knowledge is still required
  2. Know the three Helm concepts: Chart, Release, Repository
  3. Know the two Kustomize concepts: Base, Overlay
  4. Be able to use helm install/upgrade/rollback/uninstall
  5. Be able to use kubectl apply -k and kustomize build
  6. Be able to read a basic kustomization.yaml

🧪 Complete Hands-on Example: Install Nginx with Helm, Customize Configuration with Kustomize

Scenario Description

Use Helm to install the bitnami/nginx Chart, then use Kustomize to create an overlay that customizes the Deployment configuration (changing replica count and resource limits).

Prerequisites

  • Helm v3 installed
  • Cluster running normally
  • kubectl configured and able to access the cluster

Steps

Step 1: Add Helm repository and install nginx

# Add the bitnami repository
helm repo add bitnami https://charts.bitnami.com/bitnami
# "bitnami" has been added to your repositories

# Update repositories
helm repo update
# Hang tight while we grab the latest from your chart repositories...
# ...Successfully got an update from the "bitnami" chart repository

# Install nginx
helm install my-nginx bitnami/nginx -n default
# NAME: my-nginx
# LAST DEPLOYED: Tue May 27 10:00:00 2026
# NAMESPACE: default
# STATUS: deployed
# REVISION: 1

Step 2: View Helm Release

# View installed Releases
helm list
# NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART
# my-nginx        default         1               2026-05-27 10:00:00                      deployed        nginx-xx.x.x

# View rendered YAML
helm get manifest my-nginx

# View Release status
helm status my-nginx

Step 3: Create Kustomize directory structure

# Create kustomize working directory
mkdir -p ~/kustomize-nginx/base
mkdir -p ~/kustomize-nginx/overlays/production

Step 4: Create base kustomization.yaml

cat <<'EOF' > ~/kustomize-nginx/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
  app: my-nginx
  managed-by: kustomize
namespace: default
EOF

Step 5: Export Helm Deployment and Service as base

# Export YAML from Helm Release as base
helm get manifest my-nginx > ~/kustomize-nginx/base/deployment.yaml
# Or use kubectl to export
kubectl get deployment my-nginx -n default -o yaml --export > ~/kustomize-nginx/base/deployment.yaml 2>/dev/null
kubectl get service my-nginx -n default -o yaml --export > ~/kustomize-nginx/base/service.yaml 2>/dev/null

Step 6: Create production overlay

# Create replica count patch
cat <<'EOF' > ~/kustomize-nginx/overlays/production/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 5
  template:
    spec:
      containers:
      - name: nginx
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 1
            memory: 1Gi
EOF

# Create overlay kustomization.yaml
cat <<'EOF' > ~/kustomize-nginx/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: patch-replicas.yaml
  target:
    kind: Deployment
    name: my-nginx
nameSuffix: -prod
commonLabels:
  environment: production
EOF

Step 7: Apply Kustomize overlay

# Preview Kustomize build output
kubectl kustomize ~/kustomize-nginx/overlays/production/
# ... View generated YAML (replica count is 5, resource limits added)

# Apply Kustomize configuration
kubectl apply -k ~/kustomize-nginx/overlays/production/
# deployment.apps/my-nginx-prod created
# service/my-nginx-prod created

Verification

# Verify Deployment
kubectl get deployment
# NAME              READY   UP-TO-DATE   AVAILABLE   AGE
# my-nginx          1/1     1            1           5m
# my-nginx-prod     5/5     5            5           30s

# Verify replica count
kubectl get deployment my-nginx-prod -o jsonpath='{.spec.replicas}'
# 5

# Verify resource limits
kubectl get deployment my-nginx-prod -o json | jq '.spec.template.spec.containers[0].resources'
# {
#   "limits": { "cpu": "1", "memory": "1Gi" },
#   "requests": { "cpu": "500m", "memory": "512Mi" }
# }

# Verify labels
kubectl get deployment my-nginx-prod --show-labels
# NAME              ...   LABELS
# my-nginx-prod     ...   app=my-nginx,environment=production,managed-by=kustomize

Exam Tips

  • Helm and Kustomize are a very small portion of the CKA exam, but know the basic usage
  • For Helm installation, mainly remember helm repo add, helm install, helm list, helm uninstall
  • Kustomize is built into kubectl; use kubectl apply -k and kubectl kustomize
  • Learn helm get manifest to export Helm Releases as YAML, then customize with Kustomize
  • kubectl kustomize <dir> only outputs YAML to stdout, it does not actually apply to the cluster

Official Documentation