Helm and Kustomize
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.
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
| Term | Description |
|---|---|
| Chart | A Helm package containing the YAML templates and configuration needed to deploy an application |
| Release | A deployed instance of a Chart in a cluster |
| Repository | A Chart storage repository |
| Values | Configuration values passed to templates |
| Templates | Go 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
| Concept | Description |
|---|---|
| kustomization.yaml | Kustomize configuration file (required) |
| base | Base configuration directory |
| overlay | Environment overlay configuration (dev/staging/prod) |
| patch | Partial modifications to resources |
| transformer | Global modifications (labels/annotations/names, etc.) |
| generator | Dynamically 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
| Feature | Helm | Kustomize |
|---|---|---|
| Concept | Package manager (Chart) | Configuration customization (Overlay) |
| Templating | Go templates (template) | No templates (native YAML) |
| Version management | Built-in (Release versions) | Requires Git |
| Rollback | helm rollback | Rollback via Git |
| Parameterization | values.yaml + --set | patches + generators |
| Learning curve | Steeper (template syntax) | Gentler (pure YAML) |
| Dependency management | Supports sub-charts | Not supported (requires Helm) |
| Sharing | Helm Hub / ArtifactHub | Requires Git repository |
| Built-in kubectl | No (requires helm command) | Yes (kubectl apply -k) |
| Best scenario | Third-party application deployment | Internal 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
- Helm and Kustomize are a very small portion of the CKA exam -- but basic knowledge is still required
- Know the three Helm concepts: Chart, Release, Repository
- Know the two Kustomize concepts: Base, Overlay
- Be able to use
helm install/upgrade/rollback/uninstall - Be able to use
kubectl apply -kandkustomize build - 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 -kandkubectl kustomize - Learn
helm get manifestto 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