Fatskills
Practice. Master. Repeat.
Study Guide: TECH **Helm Charts: The Kubernetes Package Manager – Zero-Fluff Study Guide**
Source: https://www.fatskills.com/kubernetes/chapter/tech-helm-charts-the-kubernetes-package-manager-zero-fluff-study-guide

TECH **Helm Charts: The Kubernetes Package Manager – Zero-Fluff Study Guide**

By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.

⏱️ ~8 min read

Helm Charts: The Kubernetes Package Manager – Zero-Fluff Study Guide

(For Engineers Who Need to Deploy, Debug, and Scale Kubernetes Apps Fast)


1. What This Is & Why It Matters

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.

Why This Matters in Production

  • Without Helm: You’re manually editing YAML files, copying/pasting configs, and praying nothing breaks during upgrades. One typo in a kubectl apply -f command, and your app is down.
  • With Helm:
  • Reusability: Deploy the same app (e.g., PostgreSQL, Redis, your custom microservice) across dev, staging, and prod with different configurations (e.g., resource limits, secrets, replicas).
  • Versioning: Helm tracks releases (like Git for your K8s deployments). Roll back to a previous version if an upgrade fails.
  • Templating: Replace hardcoded values (e.g., image: myapp:v1.2.3) with variables (image: {{ .Values.image.tag }}), so you can deploy v1.2.3 in staging and v2.0.0 in prod without editing YAML.
  • Dependency Management: Need Redis + PostgreSQL for your app? Helm can install them as subcharts (like package.json dependencies).

Real-World Scenario

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.


2. Core Concepts & Components

Concept Definition Production Insight
Chart A Helm package containing all K8s manifests (YAML) + templates + values. Treat charts like immutable artifacts—version them (e.g., myapp-1.0.0.tgz) and store in a registry (like Docker Hub for images).
Values User-configurable parameters (e.g., replicaCount: 3, image.tag: v1.2.3). Never hardcode secrets in values.yaml—use --set or --values with a separate secrets.yaml (and encrypt it with helm-secrets or sops).
Templates Go-templated YAML files (e.g., deployment.yaml) that render into final K8s manifests. Use {{- if .Values.enabled }} to conditionally include resources (e.g., only deploy a ServiceMonitor if Prometheus is enabled).
Release A specific instance of a chart deployed to a cluster (e.g., myapp-prod-v1). Helm tracks releases in secrets—if your cluster crashes, you can recover releases with helm list --all-namespaces.
Repository A collection of charts (like Docker Hub for Helm). Host your own repo (e.g., with helm repo index) for internal charts—don’t rely on public repos for production.
Hooks K8s jobs that run at specific lifecycle points (e.g., pre-install, post-upgrade). Use hooks for database migrations—run a Job before upgrading your app to avoid breaking changes.
Dependencies Subcharts (e.g., Redis, PostgreSQL) declared in Chart.yaml. Pin dependency versions (e.g., redis: 14.8.0) to avoid breaking changes from upstream updates.
Helm 3 vs. Helm 2 Helm 3 removed Tiller (security risk) and uses a client-only model. Always use Helm 3—Helm 2 is deprecated and insecure (Tiller had cluster-admin by default).


3. Step-by-Step: Create, Deploy, and Upgrade a Helm Chart


Prerequisites

  • A running Kubernetes cluster (Minikube, Kind, or cloud-based).
  • kubectl configured to talk to your cluster.
  • helm installed (brew install helm or official docs).

Task: Deploy a Web App with PostgreSQL as a Dependency

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.


Step 1: Create a Chart

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


Step 2: Add PostgreSQL as a Dependency

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.


Step 3: Customize the Template

Edit templates/deployment.yaml to use PostgreSQL:


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.


Step 4: Override Values for Dev vs. Prod

Create dev-values.yaml:


replicaCount: 1
resources:
  requests:
cpu: 100m
memory: 128Mi postgresql: auth:
username: devuser
password: devpass
database: devdb

Create prod-values.yaml:


replicaCount: 3
resources:
  requests:
cpu: 500m
memory: 512Mi postgresql: auth:
username: produser
password: prodpass
database: proddb persistence:
enabled: true
size: 10Gi


Step 5: Install the Chart

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


Step 6: Upgrade and Roll Back

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


4. ? Production-Ready Best Practices


Security

  • Never commit values.yaml with secrets—use --set or a separate secrets.yaml (and encrypt it with sops or helm-secrets).
  • Use --atomic for upgrades: If the upgrade fails, Helm rolls back automatically.
    bash helm upgrade --atomic --timeout 5m myapp .
  • Restrict Helm access: Use RBAC to limit who can install/upgrade charts.

Cost Optimization

  • Set resource requests/limits in values.yaml to avoid over-provisioning.
  • Use horizontalPodAutoscaler for variable workloads (define it in templates/hpa.yaml).
  • Clean up old releases: bash helm uninstall myapp-old helm delete --purge myapp-old # Helm 2 only

Reliability & Maintainability

  • Pin chart versions in Chart.yaml to avoid breaking changes.
  • Use helm lint to catch errors before deploying: bash helm lint .
  • Test upgrades locally with --dry-run: bash helm upgrade --dry-run --debug myapp .
  • Tag releases with --app-version in Chart.yaml to track app versions.

Observability

  • Add Prometheus annotations to your templates: yaml annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"
  • Use helm test to run post-install tests (define tests in templates/tests/).
  • Monitor Helm releases with helm list --all-namespaces and set up alerts for failed upgrades.


5. ⚠️ Common Mistakes & Traps

Mistake Symptom Fix/Prevention
Hardcoding values in templates Can’t override configs per environment. Use {{ .Values.x }} and override with --values or --set.
Not pinning dependency versions Upstream chart updates break your app. Pin versions in Chart.yaml (e.g., postgresql: 12.1.2).
Forgetting --atomic on upgrades Failed upgrades leave your app in a broken state. Always use --atomic --timeout 5m.
Storing secrets in values.yaml Secrets leak into Git or Helm history. Use --set or helm-secrets + sops.
Not testing upgrades locally Breaking changes hit production. Always run helm upgrade --dry-run --debug.


6. ? Exam/Certification Focus (CKA, CKAD, CKS)


Typical Question Patterns

  1. Helm vs. kubectl apply:
  2. Question: "You need to deploy the same app to dev and prod with different configs. What’s the best tool?"
  3. Answer: Helm (templating + values overrides).
  4. Trap: kubectl apply requires manual YAML edits per environment.

  5. Helm 2 vs. Helm 3:

  6. Question: "Which Helm version uses Tiller?"
  7. Answer: Helm 2 (deprecated; Helm 3 is client-only).
  8. Trap: Helm 2 is insecure (Tiller had cluster-admin by default).

  9. Rollbacks:

  10. Question: "Your Helm upgrade fails. How do you revert?"
  11. Answer: helm rollback <release> <revision>.
  12. Trap: helm uninstall deletes the release; rollback keeps history.

  13. Dependencies:

  14. Question: "How do you add Redis as a dependency to your chart?"
  15. Answer: Add it to Chart.yaml and run helm dependency update.
  16. Trap: Manually installing Redis with helm install won’t link it to your app.

  17. Hooks:

  18. Question: "You need to run a database migration before upgrading your app. How?"
  19. Answer: Use a pre-upgrade hook (a Job in templates/ with helm.sh/hook: pre-upgrade).
  20. Trap: Running migrations as part of the app container risks race conditions.

7. ? Hands-On Challenge

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.

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

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).


8. ? Rapid-Reference Crib Sheet

Command Purpose Example
helm create <name> Generate a starter chart. helm create myapp
helm install <release> <chart> Install a chart. helm install myapp .
helm upgrade <release> <chart> Upgrade a release. helm upgrade myapp . --atomic
helm rollback <release> <revision> Roll back to a previous revision. helm rollback myapp 1
helm list --all-namespaces List all releases. helm list -A
helm uninstall <release> Delete a release. helm uninstall myapp
helm dependency update Download chart dependencies. helm dependency update
helm lint . Validate a chart. helm lint .
helm template . Render templates locally. helm template . --values prod.yaml
helm get values <release> Show values for a release. helm get values myapp
helm show values <chart> Show default values for a chart. helm show values bitnami/postgresql
⚠️ Default values.yaml location ./values.yaml (overridden by --values).
⚠️ Helm 3 storage backend Secrets (not ConfigMaps like Helm 2).
⚠️ --atomic flag Roll back if upgrade fails. Always use it!


9. ? Where to Go Next

  1. Helm Official Docs – The best reference.
  2. Bitnami Charts – Study real-world charts (e.g., PostgreSQL, Redis).
  3. Helm Best Practices – Official guide to writing production-ready charts.
  4. Helm Secrets – Encrypt secrets in values.yaml.
  5. Kubernetes Patterns – Book on Helm and other K8s patterns.


ADVERTISEMENT