- Authors

- Name
- Phillip Pham
- @ddppham
Helm Charts fuer Anfaenger: Tutorial mit Beispielen
TL;DR: Helm ist der Paketmanager für Kubernetes. Statt dutzende YAML-Dateien manuell zu pflegen, bündelt ein Helm Chart alles in ein versioniertes, konfigurierbares Paket. Dieser Artikel erklärt die Grundlagen: Installation, erste Charts nutzen, eigene Charts erstellen und die wichtigsten CLI-Befehle.
Warum Helm?
Wer schon einmal eine Anwendung auf Kubernetes deployt hat, kennt das Problem: Deployment, Service, ConfigMap, Ingress -- schnell hat man fünf oder mehr YAML-Dateien, die zusammengehören. Helm löst das, indem es diese Ressourcen in ein Chart zusammenfasst und parametrisierbar macht.
Die Vorteile auf einen Blick:
- Wiederverwendbarkeit: Ein Chart kann in Dev, Staging und Prod mit unterschiedlichen Werten deployt werden
- Versionierung: Jedes Release hat eine Version, Rollbacks sind trivial
- Dependency Management: Charts können andere Charts als Abhängigkeit einbinden
- Community: Tausende fertige Charts für gängige Software (PostgreSQL, Redis, nginx, Prometheus)
Helm installieren
# macOS
brew install helm
# Linux (offizielles Installationsskript)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Alternativ: Snap (Ubuntu)
sudo snap install helm --classic
# Version prüfen
helm version
Nach der Installation braucht Helm einen laufenden Kubernetes-Cluster. Der Zugriff läuft über die gleiche ~/.kube/config wie bei kubectl.
Repositories einrichten und Charts finden
Helm Charts werden in Repositories gehostet. Die wichtigsten hinzufügen:
# Bitnami -- grosse Sammlung produktionsreifer Charts
helm repo add bitnami https://charts.bitnami.com/bitnami
# Ingress-Controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
# Prometheus/Grafana Monitoring-Stack
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# Repos aktualisieren
helm repo update
# Charts suchen
helm search repo nginx
helm search repo bitnami/postgresql --versions
Das erste Chart installieren
Ein konkretes Beispiel: nginx als Webserver deployen.
# Chart installieren (Release-Name: my-nginx)
helm install my-nginx bitnami/nginx
# Status prüfen
helm list
helm status my-nginx
# Pods anzeigen
kubectl get pods -l app.kubernetes.io/instance=my-nginx
Werte anpassen mit --set und -f
Jedes Chart hat Standardwerte, die sich überschreiben lassen:
# Einzelne Werte direkt setzen
helm install my-nginx bitnami/nginx \
--set replicaCount=3 \
--set service.type=ClusterIP
# Oder: alle Werte in eine Datei exportieren und anpassen
helm show values bitnami/nginx > my-values.yaml
# Datei bearbeiten, dann:
helm install my-nginx bitnami/nginx -f my-values.yaml
Upgrade, Rollback und Deinstallation
Helm verwaltet den gesamten Lebenszyklus eines Releases:
# Upgrade auf neue Werte oder neue Chart-Version
helm upgrade my-nginx bitnami/nginx \
--set replicaCount=5
# Historie anzeigen
helm history my-nginx
# Rollback auf eine frühere Revision
helm rollback my-nginx 1
# Release komplett entfernen
helm uninstall my-nginx
Der Befehl helm upgrade --install ist besonders praktisch in CI/CD-Pipelines -- er installiert, falls das Release noch nicht existiert, und upgradet andernfalls.
Aufbau eines Helm Charts
Wer eigene Charts erstellen will, muss die Verzeichnisstruktur verstehen:
meine-app/
├── Chart.yaml # Metadaten (Name, Version, Beschreibung)
├── values.yaml # Standardwerte für Templates
├── charts/ # Sub-Charts / Dependencies
├── templates/ # Kubernetes-Manifeste als Go-Templates
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Wiederverwendbare Template-Snippets
│ ├── NOTES.txt # Text, der nach helm install angezeigt wird
│ └── tests/
│ └── test-connection.yaml
└── .helmignore # Dateien, die nicht ins Chart-Paket sollen
Ein eigenes Chart erstellen
Helm generiert ein Grundgerüst:
helm create meine-app
Chart.yaml -- Metadaten definieren
apiVersion: v2
name: meine-app
description: Eine einfache Web-Anwendung
type: application
version: 0.1.0 # Chart-Version (SemVer)
appVersion: '1.0.0' # Version der deployt Software
maintainers:
- name: Platform Team
email: platform@example.de
values.yaml -- Standardkonfiguration
Hier definiert man alle Werte, die Nutzer des Charts anpassen können:
replicaCount: 2
image:
repository: registry.example.de/meine-app
tag: '1.0.0'
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: nginx
host: meine-app.example.de
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
securityContext:
runAsNonRoot: true
runAsUser: 1000
Templates -- Go-Templating in Aktion
Die Template-Dateien unter templates/ sind normale Kubernetes-Manifeste, angereichert mit Go-Template-Syntax. Ein einfaches Deployment:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "meine-app.fullname" . }}
labels:
{{- include "meine-app.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "meine-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "meine-app.selectorLabels" . | nindent 8 }}
spec:
securityContext:
runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }}
runAsUser: {{ .Values.securityContext.runAsUser }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
resources:
{{- toYaml .Values.resources | nindent 12 }}
Und der zugehörige Service:
# templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "meine-app.fullname" . }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
selector:
{{- include "meine-app.selectorLabels" . | nindent 4 }}
Template testen ohne zu deployen
Vor dem echten Deployment kann man die gerenderten Manifeste prüfen:
# Templates rendern und ausgeben (kein Cluster-Zugriff nötig)
helm template meine-app ./meine-app
# Dry-Run gegen den Cluster (validiert auch API-Versionen)
helm install meine-app ./meine-app --dry-run --debug
# Chart auf Fehler prüfen
helm lint ./meine-app
Praxisbeispiel: Monitoring-Stack installieren
Ein typischer erster Use Case: Prometheus und Grafana per Helm in den Cluster bringen.
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword=sicheres-passwort \
--set prometheus.prometheusSpec.retention=14d \
--set alertmanager.enabled=true
Damit hat man in wenigen Minuten einen vollständigen Monitoring-Stack mit Dashboards und Alerting. Details dazu im Artikel Kubernetes Monitoring und Observability.
Best Practices für Einsteiger
| Thema | Empfehlung |
|---|---|
| Versionierung | Semantic Versioning nutzen (MAJOR.MINOR.PATCH) |
| Security | Immer runAsNonRoot: true und Resource Limits setzen |
| Werte | Sensible Defaults in values.yaml, alles Wichtige dokumentieren |
| Testen | helm lint und helm template vor jedem Commit |
| Namespaces | Charts in dedizierte Namespaces deployen (--namespace) |
| Secrets | Keine Passwörter in values.yaml einchecken -- helm-secrets oder External Secrets nutzen |
Häufige Fehler und Troubleshooting
# "Release already exists" -- Name ist schon vergeben
helm list -a # zeigt auch fehlgeschlagene Releases
helm uninstall meine-app # erst aufräumen, dann neu installieren
# Template-Fehler finden
helm template ./meine-app --debug 2>&1 | head -50
# Aktuelle Werte eines Releases anzeigen
helm get values meine-app
# Alle Manifeste eines Releases anzeigen
helm get manifest meine-app
Wie geht es weiter?
Wer die Grundlagen beherrscht, kann sich mit fortgeschrittenen Themen befassen:
- Chart Dependencies: Datenbanken und andere Services als Sub-Charts einbinden
- Helmfile: Mehrere Charts deklarativ verwalten
- OCI-Registries: Charts in Container-Registries statt klassischen Repos hosten
- CI/CD-Integration: Charts automatisch in Pipelines deployen
Weitere relevante Artikel:
Sie möchten Helm in Ihrem Unternehmen einführen oder Ihre bestehenden Deployments auf Charts umstellen? Wir unterstützen Sie bei der Chart-Entwicklung, Schulung Ihres Teams und der Integration in Ihre CI/CD-Pipeline -- Kontaktieren Sie uns für ein unverbindliches Erstgespräch.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
ArgoCD GitOps: Enterprise Setup mit App-of-Apps
ArgoCD GitOps fuer Enterprise: App-of-Apps, RBAC, SSO und Sync-Strategien – Setup-Guide fuer produktive Kubernetes-Cluster.
CKA Zertifizierung bestehen: Komplett-Guide 2026
CKA Zertifizierung bestehen: Curriculum, Labs und Tipps fuer den Certified Kubernetes Administrator – Guide fuer Deutschland 2026.
CKAD Zertifizierung bestehen: Praxis-Guide 2026
CKAD Zertifizierung bestehen: Themen, Labs und Pruefungsstrategie fuer Kubernetes Application Developer – kompakt fuer 2026.
AKS Tutorial für Einsteiger: Azure Kubernetes Guide (2026)
AKS Einsteiger-Guide 2026: Azure Kubernetes Service Schritt für Schritt einrichten, erste App mit Load Balancer deployen, Kosten & Best Practices.
kubectl connection refused 6443 beheben
kubectl connection refused auf Port 6443: der API-Server antwortet nicht. kubeconfig, Kontext, Firewall, API-Prozess. Der Pod-Status kommt erst danach.
Error from server Forbidden: RBAC-Recht
kubectl Forbidden: Error from server (Forbidden) nennt User, Verb und Ressource. kubectl auth can-i zeigt das Recht, bevor jemand cluster-admin vergibt.
ContainerCreating hängt: Volume, Sandbox, CNI
ContainerCreating hängt: der Pod hat einen Node, der Container startet nicht. FailedMount, Pod-Sandbox und CNI stehen in den Events, nicht in den Logs.
CreateContainerConfigError: Secret und ConfigMap
CreateContainerConfigError: fehlendes Secret, falscher Key oder Namespace. Der Container startet nicht, logs --previous bleibt leer. Das Event nennt das Objekt.