By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For Engineers Who Need to Deploy, Debug, and Scale Kubernetes Apps Fast)
Helm is the package manager for Kubernetes—think apt for Ubuntu or npm for Node.js, but for K8s manifests. Instead of manually applying dozens of YAML files (Deployments, Services, ConfigMaps, etc.), you bundle them into a single Helm chart, which you can install, upgrade, or roll back with one command.
apt
npm
kubectl apply -f
image: myapp:v1.2.3
image: {{ .Values.image.tag }}
v1.2.3
v2.0.0
package.json
You’re a DevOps engineer at a startup. Your team just built a new microservice, and you need to: 1. Deploy it to 3 environments (dev, staging, prod) with different resource limits and secrets.2. Ensure zero downtime during upgrades.3. Roll back instantly if a new version breaks.
Without Helm: You’d maintain 3 separate sets of YAML files, manually edit them for each environment, and pray kubectl apply doesn’t fail.With Helm: You write one chart, override values per environment (helm install --values prod.yaml), and roll back with helm rollback.
kubectl apply
helm install --values prod.yaml
helm rollback
myapp-1.0.0.tgz
replicaCount: 3
image.tag: v1.2.3
--set
--values
secrets.yaml
helm-secrets
sops
deployment.yaml
{{- if .Values.enabled }}
myapp-prod-v1
helm list --all-namespaces
helm repo index
pre-install
post-upgrade
Chart.yaml
redis: 14.8.0
kubectl
helm
brew install helm
We’ll: 1. Create a Helm chart for a simple web app.2. Add PostgreSQL as a dependency.3. Deploy to dev (1 replica) and prod (3 replicas) with different configs.
helm create myapp # Generates a starter chart cd myapp tree . # See the structure
Output:
myapp/ ├── Chart.yaml # Metadata (name, version, dependencies) ├── values.yaml # Default values ├── charts/ # Subcharts (dependencies) ├── templates/ # K8s manifests (templated) │ ├── deployment.yaml │ ├── service.yaml │ ├── ingress.yaml │ └── _helpers.tpl # Reusable template snippets └── tests/ # Test hooks
Edit Chart.yaml:
dependencies: - name: postgresql version: 12.1.2 # Pin version to avoid surprises repository: https://charts.bitnami.com/bitnami
Then update dependencies:
helm dependency update
What just happened?- Helm downloaded the PostgreSQL chart into charts/postgresql-12.1.2.tgz.- When you install myapp, Helm will automatically install PostgreSQL as a subchart.
charts/postgresql-12.1.2.tgz
myapp
Edit templates/deployment.yaml to use PostgreSQL:
templates/deployment.yaml
env: - name: DB_HOST value: {{ .Release.Name }}-postgresql # Helm auto-generates this name - name: DB_USER value: {{ .Values.postgresql.auth.username }} - name: DB_PASSWORD valueFrom: secretKeyRef: name: {{ .Release.Name }}-postgresql key: postgres-password
Key points:- {{ .Release.Name }} is the release name (e.g., myapp-dev).- {{ .Values.postgresql.auth.username }} comes from the PostgreSQL subchart’s values.yaml.
{{ .Release.Name }}
myapp-dev
{{ .Values.postgresql.auth.username }}
values.yaml
Create dev-values.yaml:
dev-values.yaml
replicaCount: 1 resources: requests: cpu: 100m memory: 128Mi postgresql: auth: username: devuser password: devpass database: devdb
Create prod-values.yaml:
prod-values.yaml
replicaCount: 3 resources: requests: cpu: 500m memory: 512Mi postgresql: auth: username: produser password: prodpass database: proddb persistence: enabled: true size: 10Gi
Dev environment:
helm install myapp-dev . --values dev-values.yaml
Prod environment:
helm install myapp-prod . --values prod-values.yaml --namespace prod
Verify:
helm list --all-namespaces kubectl get pods -n prod # Should show 3 replicas + PostgreSQL
Upgrade to v2.0.0:
helm upgrade myapp-prod . --values prod-values.yaml --set image.tag=v2.0.0
Roll back if it fails:
helm rollback myapp-prod 1 # Revert to revision 1 helm history myapp-prod # See all revisions
--atomic
bash helm upgrade --atomic --timeout 5m myapp .
horizontalPodAutoscaler
templates/hpa.yaml
bash helm uninstall myapp-old helm delete --purge myapp-old # Helm 2 only
helm lint
bash helm lint .
--dry-run
bash helm upgrade --dry-run --debug myapp .
--app-version
yaml annotations: prometheus.io/scrape: "true" prometheus.io/port: "8080"
helm test
templates/tests/
{{ .Values.x }}
postgresql: 12.1.2
--atomic --timeout 5m
helm upgrade --dry-run --debug
Trap: kubectl apply requires manual YAML edits per environment.
Helm 2 vs. Helm 3:
Trap: Helm 2 is insecure (Tiller had cluster-admin by default).
Rollbacks:
helm rollback <release> <revision>
Trap: helm uninstall deletes the release; rollback keeps history.
helm uninstall
rollback
Dependencies:
Trap: Manually installing Redis with helm install won’t link it to your app.
helm install
Hooks:
pre-upgrade
templates/
helm.sh/hook: pre-upgrade
Challenge: Deploy a Helm chart for a simple web app with: - 2 replicas in dev, 5 in prod.- A ConfigMap with a custom message (e.g., WELCOME_MESSAGE: "Hello Dev" vs. "Hello Prod").- A Service of type LoadBalancer.
ConfigMap
WELCOME_MESSAGE: "Hello Dev"
"Hello Prod"
Service
LoadBalancer
Solution: 1. Create the chart: bash helm create mywebapp cd mywebapp 2. Edit templates/deployment.yaml to use the ConfigMap: yaml env: - name: WELCOME_MESSAGE valueFrom: configMapKeyRef: name: {{ .Release.Name }}-config key: message 3. Add templates/configmap.yaml: yaml apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-config data: message: {{ .Values.welcomeMessage | quote }} 4. Create dev-values.yaml: yaml replicaCount: 2 welcomeMessage: "Hello Dev" 5. Create prod-values.yaml: yaml replicaCount: 5 welcomeMessage: "Hello Prod" 6. Deploy: bash helm install mywebapp-dev . --values dev-values.yaml helm install mywebapp-prod . --values prod-values.yaml 7. Verify: bash kubectl get pods -l app.kubernetes.io/instance=mywebapp-dev kubectl logs <pod-name> # Should show the welcome message
bash helm create mywebapp cd mywebapp
yaml env: - name: WELCOME_MESSAGE valueFrom: configMapKeyRef: name: {{ .Release.Name }}-config key: message
templates/configmap.yaml
yaml apiVersion: v1 kind: ConfigMap metadata: name: {{ .Release.Name }}-config data: message: {{ .Values.welcomeMessage | quote }}
yaml replicaCount: 2 welcomeMessage: "Hello Dev"
yaml replicaCount: 5 welcomeMessage: "Hello Prod"
bash helm install mywebapp-dev . --values dev-values.yaml helm install mywebapp-prod . --values prod-values.yaml
bash kubectl get pods -l app.kubernetes.io/instance=mywebapp-dev kubectl logs <pod-name> # Should show the welcome message
Why it works: - Helm renders the ConfigMap with the correct message per environment.- The Service is auto-generated by helm create (type LoadBalancer by default).
helm create
helm create <name>
helm create myapp
helm install <release> <chart>
helm install myapp .
helm upgrade <release> <chart>
helm upgrade myapp . --atomic
helm rollback myapp 1
helm list -A
helm uninstall <release>
helm uninstall myapp
helm lint .
helm template .
helm template . --values prod.yaml
helm get values <release>
helm get values myapp
helm show values <chart>
helm show values bitnami/postgresql
./values.yaml
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.