Helm-Charts: Paketverwaltung für Kubernetes
Kubernetes-Deployments mit Helm-Paketverwaltung
Helm hat die Bereitstellung von Kubernetes-Anwendungen revolutioniert, indem es Paketverwaltungs Konzepte einführen, die von traditionellen Betriebssystemen bekannt sind.
Mit der wachsenden Adoption von Kubernetes wird die Verwaltung komplexer Anwendungen mit Dutzenden von YAML-Dateien immer schwieriger. Helm-Charts lösen dieses Problem, indem sie alle Ressourcen in versionierte, konfigurierbare Pakete bündeln.
Dieses schöne Bild wurde von dem KI-Modell Flux 1 dev erzeugt.
Helm verstehen: Der Kubernetes-Paketmanager
Helm ist für Kubernetes, was apt für Debian, yum für RedHat oder Homebrew für macOS ist. Es verpackt Kubernetes-Anwendungen in Charts – Sammlungen von Dateien, die verwandte Kubernetes-Ressourcen beschreiben. Ein einzelner Chart könnte ein komplettes Anwendungs-Stack bereitstellen: Webserver, Datenbanken, Caching-Schichten, Ingress-Regeln und Überwachungskomponenten. Für Kubernetes-Neulinge bietet ein Kubernetes Cheatsheet wesentliche Befehle und Konzepte zum Einstieg.
Warum Helm in der modernen DevOps-Welt wichtig ist
Komplexitätsreduktion: Statt 20+ YAML-Dateien zu verwalten, verwalten Sie einen Chart mit anpassbaren Werten.
Wiederholbarkeit: Bereitstellen identischer Konfigurationen in Entwicklung, Staging und Produktion mit umgebungsspezifischen Wert-Überschreibungen. Dies ist besonders wertvoll beim Bereitstellen komplexer Mikroservice-Architekturen, bei denen Konsistenz entscheidend ist.
Versionskontrolle: Charts sind versioniert, was einfache Rollbacks und Upgrade-Verfolgung ermöglicht.
Community-Ökosystem: Tausende vorab erstellte Charts stehen über Artifact Hub (ehemals Helm Hub) für beliebte Anwendungen wie PostgreSQL, Redis, NGINX, Prometheus und mehr zur Verfügung.
Templating-Macht: Go-Templates ermöglichen die dynamische Ressourcenerstellung basierend auf Eingabewerten und reduzieren Duplikate.
Helm-Architektur und Kernkonzepte
Helm 3 Architektur
Helm 3 vereinfachte die Architektur, indem es Tiller, die problematische serverseitige Komponente aus Helm 2, entfernte:
- Helm-Client: CLI-Tool, das direkt mit der Kubernetes-API interagiert
- Chart: Paketformat, das Vorlagen und Metadaten enthält
- Release: Eine Instanz eines Charts, die in einem Kubernetes-Cluster läuft
- Repository: Speicherort für Charts (HTTP-Server oder OCI-Registry)
Wichtige Komponenten eines Helm-Charts
my-app-chart/
├── Chart.yaml # Chart-Metadaten und Version
├── values.yaml # Standardkonfigurationswerte
├── charts/ # Abhängige Charts
├── templates/ # Kubernetes-Ressourcen-Vorlagen
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── _helpers.tpl # Vorlagen-Helper
│ └── NOTES.txt # Nachinstallationshinweise
├── .helmignore # Zu ignorierende Dateien beim Paketieren
├── README.md
└── LICENSE
Erstellen Ihres ersten Helm-Charts
Initialisieren eines neuen Charts
helm create my-application
cd my-application
Dies erzeugt einen Starter-Chart mit Beispielvorlagen für eine Bereitstellung, einen Dienst und einen Ingress.
Chart.yaml: Definieren von Metadaten
apiVersion: v2
name: my-application
description: Ein produktionsbereiter Anwendungs-Chart
type: application
version: 1.0.0 # Chart-Version
appVersion: "2.4.1" # Version der Anwendung
maintainers:
- name: Ihr Team
email: team@company.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Values.yaml: Konfigurationsmanagement
Die values.yaml-Datei definiert Standardkonfigurationen, die Benutzer überschreiben können. Dieser Ansatz trennt Konfiguration von Vorlagen und erleichtert die Verwaltung verschiedener Umgebungen (Entwicklung, Staging, Produktion) und die Anpassung von Bereitstellungen ohne Änderung der Vorlagendateien.
replicaCount: 3
image:
repository: myapp/backend
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 80
Vorlagen: Dynamische Kubernetes-Manifests
Vorlagen verwenden Go-Templating-Syntax, um Kubernetes-Ressourcen dynamisch zu generieren. Diese Vorlagen können jeden Kubernetes-Ressourcentyp generieren, von einfachen Bereitstellungen bis zu komplexen StatefulSets für zustandsbehaftete Anwendungen, die dauerhafte Speicherung benötigen. Für Anwendungen, die stabile Identitäten und dauerhafte Volumes benötigen, sollten Sie StatefulSets anstelle von Bereitstellungen verwenden, wie in unserer Anleitung zu StatefulSets und dauerhafter Speicherung in Kubernetes beschrieben.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-application.fullname" . }}
labels:
{{- include "my-application.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-application.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-application.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 8080
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 10 }}
Vorlagen-Helper (_helpers.tpl)
Erstellen Sie wiederverwendbare Vorlagenfunktionen, um Wiederholungen zu vermeiden:
{{/*
Erweitern Sie den Namen des Charts.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Erstellen Sie einen Standard-vollqualifizierten Anwendungsnamen.
*/}}
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Gemeinsame Labels
*/}}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
{{ include "my-application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Verwaltung von Helm-Charts: Installation und Betrieb
Installation eines Charts
# Installation aus einem Repository
helm install my-release bitnami/postgresql
# Installation aus lokalem Verzeichnis
helm install my-app ./my-application
# Installation mit benutzerdefinierten Werten
helm install my-app ./my-application -f values-production.yaml
# Installation mit inline-Wert-Überschreibungen
helm install my-app ./my-application \
--set replicaCount=5 \
--set image.tag=2.0.0
Aktualisieren von Releases
# Aktualisieren mit neuen Werten
helm upgrade my-app ./my-application -f values-production.yaml
# Aktualisieren mit atomarem Rollback bei Fehlschlag
helm upgrade my-app ./my-application --atomic --timeout 5m
# Erzwingen von Ressourcenaktualisierungen
helm upgrade my-app ./my-application --force
Rollback und Historie
# Anzeigen der Release-Historie
helm history my-app
# Rollback zur vorherigen Version
helm rollback my-app
# Rollback zu einer bestimmten Revision
helm rollback my-app 3
Testen und Debuggen
# Trockenlauf, um generierte Manifests anzuzeigen
helm install my-app ./my-application --dry-run --debug
# Vorlagen-Rendering ohne Installation
helm template my-app ./my-application
# Chart auf Probleme prüfen
helm lint ./my-application
# Testen des Releases mit Test-Hooks
helm test my-app
Fortgeschrittene Helm-Funktionen
Chart-Abhängigkeiten
Helm-Charts können von anderen Charts abhängen, was es ermöglicht, komplexe Anwendungen aus wiederverwendbaren Komponenten zusammenzusetzen. Dies ist besonders nützlich beim Bereitstellen von Mikroservices, die Datenbanken, Nachrichtenwarteschlangen oder andere unterstützende Dienste benötigen. Definieren Sie Abhängigkeiten in Chart.yaml:
dependencies:
- name: redis
version: "17.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Aktualisieren Sie Abhängigkeiten:
helm dependency update ./my-application
Helm-Hooks für Lebenszyklus-Management
Hooks werden zu bestimmten Punkten im Release-Lebenszyklus ausgeführt:
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-application.fullname" . }}-db-migration
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
spec:
containers:
- name: db-migrate
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["python", "manage.py", "migrate"]
restartPolicy: Never
Hook-Typen umfassen:
pre-install: Vor der Ressourceninstallationpost-install: Nach der Installation aller Ressourcenpre-upgrade: Vor dem Upgradepost-upgrade: Nach dem Upgradepre-delete: Vor der Löschungpost-delete: Nach der Löschungpre-rollback: Vor dem Rollbackpost-rollback: Nach dem Rollback
Bedingte Logik und Flusssteuerung
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-application.fullname" . }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "my-application.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
OCI-Registry-Unterstützung: Moderne Chart-Verteilung
Seit Helm 3.8 ist die OCI (Open Container Initiative)-Registry-Unterstützung stabil, was es ermöglicht, Charts zusammen mit Container-Images zu speichern.
Veröffentlichung in OCI-Registry
# Anmeldung beim Registry
helm registry login registry.example.com
# Chart verpacken
helm package ./my-application
# Hochladen in OCI-Registry
helm push my-application-1.0.0.tgz oci://registry.example.com/charts
# Installation aus OCI-Registry
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0
Vorteile von OCI-Registries
- Einheitliche Speicherung: Charts und Images an einem Ort
- Standard-Tools: Nutzung bestehender Registry-Infrastruktur
- Bessere Sicherheit: Nutzung von Registry-Authentifizierung und Scans
- Einfachere Verwaltung: Kein separater Chart-Repository-Server erforderlich
Best Practices für Produktions-Helm-Charts
1. Werte-Struktur und Dokumentation
Dokumentieren Sie alle Werte mit Kommentaren:
# -- Anzahl der Replikate für die Anwendung
replicaCount: 3
# -- Bildkonfiguration
image:
# -- Bild-Repository
repository: myapp/backend
# -- Bild-Ladepolitik
pullPolicy: IfNotPresent
# -- Bild-Tag (standardmäßig Chart appVersion)
tag: ""
2. Ressourcenmanagement
Legen Sie immer Ressourcenanforderungen und -grenzen fest:
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
3. Sicherheitskontexte
Definieren Sie Sicherheitskontexte für Container:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
4. Gesundheitsprüfungen
Integrieren Sie Liveness- und Readiness-Proben:
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
5. ConfigMap- und Secret-Verwaltung
Eine ordnungsgemäße Geheimnisverwaltung ist für Produktionsbereitstellungen entscheidend. Verwenden Sie externe Geheimnismanager (Sealed Secrets, External Secrets Operator oder Vault) anstelle der Speicherung von Geheimnissen in Werte-Dateien. Dadurch wird sichergestellt, dass sensible Daten wie Datenbankpasswörter, API-Schlüssel und Zertifikate sicher gehandhabt werden:
envFrom:
- secretRef:
name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
name: {{ include "my-application.fullname" . }}-config
6. Schema-Validierung
Erstellen Sie values.schema.json, um Benutzereingaben zu validieren:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1
},
"image": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": ["repository"]
}
},
"required": ["image"]
}
7. NOTES.txt für Benutzeranleitung
Bieten Sie Anweisungen nach der Installation:
1. Holen Sie sich die Anwendungs-URL, indem Sie ausführen:
{{- if .Values.ingress.enabled }}
https://{{ (index .Values.ingress.hosts 0).host }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-application.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- end }}
2. Überwachen Sie die Bereitstellung:
kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"
Helm-Chart-Tests und CI/CD-Integration
Chart-Tests mit chart-testing (ct)
# Installieren Sie chart-testing
brew install chart-testing
# Charts überprüfen
ct lint --config ct.yaml
# Installieren und testen Sie Charts
ct install --config ct.yaml
GitHub Actions-Beispiel
name: Helm Chart CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Helm einrichten
uses: azure/setup-helm@v3
with:
version: 3.12.0
- name: chart-testing einrichten
uses: helm/chart-testing-action@v2
- name: Charts überprüfen
run: ct lint --config ct.yaml
- name: Erstellen Sie ein kind-Cluster
uses: helm/kind-action@v1
- name: Installieren Sie Charts
run: ct install --config ct.yaml
GitOps mit Helm: ArgoCD und Flux
GitOps-Tools wie ArgoCD und Flux integrieren sich nahtlos mit Helm-Charts und ermöglichen deklarative, automatisierte Bereitstellungen. Diese Tools überwachen Ihr Git-Repository auf Änderungen und synchronisieren automatisch Helm-Releases, was die kontinuierliche Bereitstellung vereinfacht. Für komplexe Mikroservice-Architekturen sollten Sie prüfen, wie verteilte Transaktionsmuster wie das Saga-Muster helfen können, die Konsistenz über die mit Helm bereitgestellten Dienste zu verwalten.
ArgoCD-Anwendung
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-application
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app-chart
targetRevision: main
path: charts/my-application
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
Flux HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: my-application
namespace: flux-system
spec:
interval: 5m
chart:
spec:
chart: my-application
version: '1.x.x'
sourceRef:
kind: HelmRepository
name: my-charts
values:
replicaCount: 5
image:
tag: "2.0.0"
Fehlerbehebung bei häufigen Helm-Problemen
Problem: Fehlgeschlagenes Upgrade hängt im Status “Pending”
# Überprüfen Sie den Release-Status
helm list --all-namespaces
# Holen Sie sich Release-Details
helm status my-app -n namespace
# Löschen Sie erzwungene Geheimnisse, falls erforderlich (vorsichtig verwenden)
kubectl delete secret -n namespace -l owner=helm,name=my-app
Problem: Template-Rendering-Fehler
# Debuggen Sie das Template-Rendering
helm template my-app ./my-application --debug
# Validieren Sie gegen Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -
Problem: Werte werden nicht angewendet
# Überprüfen Sie die zusammengeführten Werte
helm get values my-app
# Zeigen Sie alle berechneten Werte an
helm get values my-app --all
Helm-Ökosystem und Tools
Das Helm-Ökosystem umfasst zahlreiche Tools, die seine Fähigkeiten erweitern und mit anderen Kubernetes-Technologien integrieren. Bei der Bereitstellung von Anwendungen, die erweiterte Netzwerkfunktionen wie Service-to-Service-Kommunikation, Verkehrsmanagement und Sicherheitsrichtlinien erfordern, sollten Sie die Integration mit einem Service Mesh mit Istio und Linkerd in Betracht ziehen, die über Helm-Charts bereitgestellt und verwaltet werden können.
Wichtige Tools
- Helmfile: Deklarative Spezifikation zum Bereitstellen von Helm-Charts
- Helm Diff: Vorschau von Änderungen vor dem Upgrade
- Helm Secrets: Geheimnisse mit SOPS verwalten
- Nova: Veraltete Helm-Charts finden
- Pluto: Veraltete Kubernetes-APIs erkennen
Beispiel Helmfile
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: postgresql
namespace: database
chart: bitnami/postgresql
version: 12.x.x
values:
- postgresql:
auth:
database: myapp
username: appuser
- name: my-app
namespace: production
chart: ./charts/my-application
values:
- values-production.yaml
needs:
- database/postgresql
Die Zukunft von Helm
Das Helm-Ökosystem entwickelt sich weiter:
- OCI-Nativ: Vollständiger Übergang zu OCI-Registries als Standard
- Verbesserte Sicherheit: Bessere Geheimnisverwaltung und Signaturfähigkeiten
- Leistung: Schnellere Rendering- und Installationszeiten für große Charts
- WASM-Unterstützung: WebAssembly für Chart-Plugins und Erweiterungen
- Bessere Validierung: Erweiterte Schema-Validierung und Richtlinienumsetzung
Fazit
Helm ist zum de facto-Standard für Kubernetes-Paketverwaltung geworden, und die Beherrschung ist für moderne DevOps-Praktiken unerlässlich. Durch das Verständnis der Chart-Struktur, des Templatings, des Werte-Managements und der Best Practices können Sie wartbare, sichere und skalierbare Kubernetes-Bereitstellungen erstellen.
Beginnen Sie mit einfachen Charts, integrieren Sie schrittweise erweiterte Funktionen wie Haken und Abhängigkeiten und integrieren Sie GitOps-Tools für produktionsreife Infrastruktur. Die Helm-Community bietet Tausende von vorgefertigten Charts, aber die wahre Macht liegt in der Erstellung von benutzerdefinierten Charts, die auf die Bedürfnisse Ihrer Organisation zugeschnitten sind. Ob Sie zustandslose Anwendungen oder zustandsbehaftete Workloads mit persistentem Speicher bereitstellen, Helm vereinfacht die Komplexität des Kubernetes-Ressourcenmanagements. Für Teams, die neue Kubernetes-Cluster einrichten, sollten Sie die Installation von Kubernetes mit Kubespray in Betracht ziehen oder Kubernetes-Distributionen wie k3s oder MicroK8s für Entwicklungsumgebungen erkunden. Wenn Sie bewerten, welche Distribution Ihren Anforderungen an ein Homelab oder einen kleinen Cluster entspricht, sehen Sie sich unseren umfassenden Vergleich von Kubernetes-Distributionen für eine detaillierte Analyse an.
Nützliche Links
- Offizielle Helm-Dokumentation
- Artifact Hub - Entdecken Sie Helm-Charts
- Helm GitHub-Repository
- Helm-Best-Practices-Leitfaden
- Chart-Test-Tool
- Helmfile
- ArgoCD
- Flux CD
- Bitnami Charts-Repository
- Kubernetes-Cheatsheet
- Installation von Kubernetes mit Kubespray
- Vergleich von Kubernetes-Distributionen für ein 3-Knoten-Homelab
- Kubernetes-Distributionen - Kurzer Überblick über kubeadm, k3s, MicroK8s, Minikube, Talos Linux und RKE2
- Service Mesh mit Istio und Linkerd
- StatefulSets und Persistente Speicherung in Kubernetes
- Saga-Muster in verteilten Transaktionen