Veröffentlicht am

Helm Charts für Anfänger: Eigenes Chart erstellen

Teilen:
Authors

Helm Charts für Anfänger: Kubernetes-Pakete verstehen und erstellen

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

ThemaEmpfehlung
VersionierungSemantic Versioning nutzen (MAJOR.MINOR.PATCH)
SecurityImmer runAsNonRoot: true und Resource Limits setzen
WerteSensible Defaults in values.yaml, alles Wichtige dokumentieren
Testenhelm lint und helm template vor jedem Commit
NamespacesCharts in dedizierte Namespaces deployen (--namespace)
SecretsKeine 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

Diese Themen behandeln wir im Detail im Artikel Helm in der Praxis: Repositories, Dependencies und CI/CD.

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.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen