19 - Helm & Package Management
What Is Helm?
Helm is the package manager for Kubernetes (like apt for Ubuntu or brew for macOS). It lets you:
- Package multiple K8s resources into a single "chart"
- Template manifests with configurable values
- Manage releases (install, upgrade, rollback)
- Share charts via repositories
Key Concepts
| Concept | Description |
|---|---|
| Chart | A package of K8s manifests (templates + values) |
| Release | An installed instance of a chart |
| Repository | Where charts are stored and shared |
| Values | Configuration that customizes a chart |
Chart Structure
my-app/
├── Chart.yaml # Chart metadata (name, version, dependencies)
├── values.yaml # Default configuration values
├── charts/ # Dependencies (sub-charts)
├── templates/ # Kubernetes manifest templates
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── _helpers.tpl # Template helpers
│ ├── NOTES.txt # Post-install instructions
│ └── tests/
│ └── test-connection.yaml
├── .helmignore # Files to exclude
└── README.md
Chart.yaml
yamlapiVersion: v2 name: my-app description: My web application type: application # or "library" version: 1.2.0 # Chart version (SemVer) appVersion: "3.1.0" # App version dependencies: - name: postgresql version: "13.x.x" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled
values.yaml
yaml# Default values that users can override replicaCount: 3 image: repository: myapp tag: "v3.1.0" pullPolicy: IfNotPresent service: type: ClusterIP port: 80 ingress: enabled: true className: nginx hosts: - host: app.example.com paths: - path: / pathType: Prefix tls: - secretName: app-tls hosts: - app.example.com resources: requests: cpu: 250m memory: 256Mi limits: cpu: 500m memory: 512Mi postgresql: enabled: true auth: database: myapp
Template Example
yaml# templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "my-app.fullname" . }} labels: {{- include "my-app.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "my-app.selectorLabels" . | nindent 6 }} template: metadata: labels: {{- include "my-app.selectorLabels" . | nindent 8 }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: 8080 {{- with .Values.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }}
Helm Commands
Repository Management
bash# Add a chart repository helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx # Update repos helm repo update # Search for charts helm search repo nginx helm search hub wordpress # Search Artifact Hub
Installing Charts
bash# Install a chart helm install my-release bitnami/nginx # Install with custom values helm install my-release bitnami/nginx -f custom-values.yaml # Install with inline overrides helm install my-release bitnami/nginx \ --set replicaCount=3 \ --set service.type=LoadBalancer # Install in specific namespace helm install my-release bitnami/nginx -n production --create-namespace # Dry run (see what would be created) helm install my-release bitnami/nginx --dry-run --debug # Template only (render manifests without installing) helm template my-release bitnami/nginx -f values.yaml
Managing Releases
bash# List installed releases helm list helm list -n production helm list --all-namespaces # Get release info helm status my-release helm get values my-release # Deployed values helm get manifest my-release # Deployed manifests helm history my-release # Revision history # Upgrade a release helm upgrade my-release bitnami/nginx -f new-values.yaml helm upgrade --install my-release bitnami/nginx # Install if doesn't exist # Rollback helm rollback my-release 1 # Rollback to revision 1 helm rollback my-release # Rollback to previous # Uninstall helm uninstall my-release helm uninstall my-release --keep-history # Keep history for rollback
Creating Charts
bash# Create a new chart scaffold helm create my-app # Lint (check for errors) helm lint my-app/ # Package for distribution helm package my-app/ # Creates my-app-1.2.0.tgz # Push to OCI registry helm push my-app-1.2.0.tgz oci://ghcr.io/myorg/charts
Helm Template Syntax (Go Templates)
yaml# Variables {{ .Values.image.tag }} {{ .Release.Name }} {{ .Chart.AppVersion }} # Conditionals {{- if .Values.ingress.enabled }} apiVersion: networking.k8s.io/v1 kind: Ingress ... {{- end }} # Loops {{- range .Values.ingress.hosts }} - host: {{ .host }} {{- end }} # Default values {{ .Values.image.tag | default "latest" }} # Pipelines {{ .Values.name | upper | quote }} # Include template helpers {{ include "my-app.fullname" . }} # toYaml (convert values to YAML) {{- toYaml .Values.resources | nindent 12 }} # With (set context) {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }}
Alternatives to Helm
| Tool | Approach | Best For |
|---|---|---|
| Helm | Templating + packaging | Standard charts, community packages |
| Kustomize | Patching (no templates) | Overlay-based customization |
| Jsonnet | Data templating language | Complex generation |
| cdk8s | Generate K8s manifests with code | Developers who prefer code |
| Timoni | CUE-based package manager | Type-safe configs |
Kustomize (Built into kubectl)
bash# Base base/ ├── kustomization.yaml ├── deployment.yaml └── service.yaml # Overlay (per environment) overlays/ ├── dev/ │ └── kustomization.yaml # patches for dev ├── staging/ │ └── kustomization.yaml └── production/ └── kustomization.yaml
yaml# overlays/production/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base namePrefix: prod- patches: - patch: |- - op: replace path: /spec/replicas value: 5 target: kind: Deployment name: web-app
bashkubectl apply -k overlays/production/
FAANG Interview Angle
Common questions:
- "What is Helm and why would you use it?"
- "How do you manage different environments with Helm?"
- "Compare Helm vs Kustomize"
- "How do you handle secrets in Helm charts?"
- "How do you rollback a Helm release?"
Key answers:
- Helm packages K8s manifests into reusable charts with templating and versioning
- Multiple values files (values-dev.yaml, values-prod.yaml) or --set overrides
- Helm: templates with Go syntax, good for distributing apps. Kustomize: patches, good for env overlays
- helm-secrets plugin, SOPS encryption, or reference external secrets by name
helm rollback <release> <revision>-- Helm keeps history of all releases
Official Links
- Helm Documentation
- Artifact Hub (chart registry)
- Chart Best Practices
- Helm Template Guide
- Kustomize