Docker und Kubernetes Workflows mit Bash automatisieren
AI generated
Bash · Docker · Kubernetes · DevOps · kubectl
Docker und Kubernetes Workflows mit Bash automatisieren
Health-Checks, Rollout-Skripte und Container-Monitoring in der Shell

Container-Tooling wie Docker und Kubernetes bietet leistungsfähige CLIs – aber erst Bash-Automatisierung verknüpft Health-Checks, Rollout-Kontrolle und Alerting zu einem vollständigen Workflow. Wer Docker und Kubernetes Workflows mit Bash automatisiert, reduziert manuelle Eingriffe und macht Deployments nachvollziehbar, wiederholbar und sicher.

15 Min. Lesezeit docker · kubectl · Health-Checks · Rollouts · Monitoring Bash 4.x · 5.x · Linux · macOS · CI/CD

1. Warum Docker und Kubernetes mit Bash automatisieren?

Wer Docker und Kubernetes Workflows mit Bash automatisieren möchte, hat einen pragmatischen Grund: Beide Tools bieten mächtige CLIs, aber ohne Skript-Wrapper fehlt die Orchestrierung. Ein docker run in einer CI-Pipeline ohne Health-Check, ohne Rollback-Logik und ohne Timeout ist kein Deployment-Prozess – es ist ein manuell auslösbarer Befehl. Erst ein Bash-Skript, das Health-Checks wartet, Status überwacht, bei Fehlern automatisch zurückrollt und alle Schritte protokolliert, macht daraus einen reproduzierbaren Workflow.

Der zweite Grund ist die Kontrolle über CLI-Outputs. docker inspect, kubectl get pods -o json und kubectl rollout status liefern maschinenlesbare Ausgaben, die Bash-Skripte mit jq parsen, auswerten und in Entscheidungslogik übersetzen können. Docker und Kubernetes Workflows mit Bash automatisieren bedeutet, diese Outputs in Bedingungen umzuwandeln: Warte auf Container-Status healthy, prüfe ob alle Pods Running sind, vergleiche Image-Tags vor und nach dem Rollout. Diese Entscheidungslogik fehlt in den CLIs selbst – sie gehört in Bash.

Drittens sind Bash-Skripte portabel und unabhängig von CI-Plattform-spezifischen Features. Dasselbe Rollout-Skript läuft in GitHub Actions, GitLab CI, Jenkins und manuell auf dem Server. Wer Docker und Kubernetes Workflows mit Bash automatisieren implementiert, schafft eine Automatisierungsschicht, die nicht an eine bestimmte CI/CD-Plattform gebunden ist.

2. Docker-CLI in Bash-Skripten zuverlässig nutzen

Die wichtigste Grundlage beim Docker und Kubernetes Workflows mit Bash automatisieren ist das korrekte Auswerten von Exit-Codes. Docker-CLI-Befehle geben bei Fehler Exit-Code 1 zurück – mit set -euo pipefail im Skript wird jeder Docker-Fehler automatisch zum Skript-Abbruch. Das Parsen von Docker-Outputs erfordert entweder --format mit Go-Template-Syntax oder docker inspect --format für strukturierte Feldabfragen. Beide Ansätze sind zuverlässiger als das Zeilenweise-Parsen von Klartextausgaben mit grep und awk, weil sie unabhängig von der Ausgabeformatierung einer Docker-Version sind.

Ein häufiges Problem beim Docker und Kubernetes Workflows mit Bash automatisieren: Race Conditions beim Container-Start. Ein docker run gibt den Container-Namen zurück, sobald der Container gestartet ist – nicht sobald die Anwendung darin bereit ist. Wer direkt nach docker run Anfragen an den Container sendet, trifft oft auf einen Container, der läuft, aber dessen Dienst noch initialisiert. Die Lösung ist eine aktive Warte-Schleife, die den Health-Check-Status des Containers abfragt und erst dann fortsetzt, wenn der Status healthy ist.


#!/usr/bin/env bash
# docker-deploy.sh — Deploy Docker container with health-check validation
set -euo pipefail
IFS=$'\n\t'

readonly IMAGE="${1:?Usage: $0 <image:tag> <container-name>}"
readonly CONTAINER_NAME="${2:?Usage: $0 <image:tag> <container-name>}"
readonly MAX_WAIT=120  # seconds to wait for health check
readonly HEALTH_INTERVAL=3

# Get current running container ID (if any)
get_running_id() {
  docker ps --filter "name=^/${CONTAINER_NAME}$" --format "{ {.ID} }" 2>/dev/null || true
}

# Wait until container reaches healthy state
wait_for_healthy() {
  local container_id="$1"
  local elapsed=0
  echo "[INFO] Waiting for container $container_id to become healthy..."
  while (( elapsed < MAX_WAIT )); do
    local status
    status="$(docker inspect --format='{ {.State.Health.Status} }' "$container_id" 2>/dev/null || echo "none")"
    case "$status" in
      healthy) echo "[OK] Container is healthy after ${elapsed}s"; return 0 ;;
      unhealthy) echo "[FAIL] Container is unhealthy" >&2; return 1 ;;
      none) echo "[INFO] No health check defined — checking if running..."
        local running
        running="$(docker inspect --format='{ {.State.Running} }' "$container_id")"
        [[ "$running" == "true" ]] && return 0
        ;;
    esac
    sleep "$HEALTH_INTERVAL"
    (( elapsed += HEALTH_INTERVAL )) || true
  done
  echo "[FAIL] Timeout: container did not become healthy within ${MAX_WAIT}s" >&2
  return 1
}

old_id="$(get_running_id)"
echo "[INFO] Pulling image $IMAGE..."
docker pull "$IMAGE"

echo "[INFO] Starting new container $CONTAINER_NAME..."
docker run -d --name "${CONTAINER_NAME}_new" \
  --health-cmd="curl -sf http://localhost:80/health || exit 1" \
  --health-interval=5s \
  --health-timeout=3s \
  --health-retries=3 \
  "$IMAGE"

new_id="$(docker ps -q --filter "name=^/${CONTAINER_NAME}_new$")"
if wait_for_healthy "$new_id"; then
  [[ -n "$old_id" ]] && docker stop "$old_id" && docker rm "$old_id"
  docker rename "${CONTAINER_NAME}_new" "$CONTAINER_NAME"
  echo "[OK] Deployment successful"
else
  docker stop "$new_id" && docker rm "$new_id"
  echo "[FAIL] Deployment rolled back" >&2
  exit 1
fi

3. Container Health-Checks mit Bash überwachen

Health-Checks sind das Herzstück jeder Container-Automatisierung. Wenn man Docker und Kubernetes Workflows mit Bash automatisieren will, muss das Skript wissen, wann ein Container wirklich bereit ist – nicht nur, wann er gestartet wurde. Docker bietet eingebaute Health-Checks, die per HEALTHCHECK-Direktive im Dockerfile oder per --health-cmd beim docker run definiert werden. Der Status ist über docker inspect --format='{ {.State.Health.Status} }' abfragbar und nimmt die Werte starting, healthy, unhealthy oder none an.

Kubernetes bietet drei Health-Check-Typen: livenessProbe prüft, ob ein Container noch lebt und soll ihn bei Fehlern neu starten. readinessProbe prüft, ob ein Container bereit ist, Traffic zu empfangen – Pods ohne positive Readiness-Probe erhalten keinen Traffic vom Service. startupProbe gibt langsam startenden Anwendungen mehr Zeit. Beim Docker und Kubernetes Workflows mit Bash automatisieren ist die Readiness-Probe die relevanteste für Rollout-Skripte: kubectl rollout status deployment/app wartet implizit auf alle Pods mit positiver Readiness-Probe.

4. Image-Builds, Tags und Registry-Workflows

Image-Management ist ein weiterer Bereich, bei dem das Docker und Kubernetes Workflows mit Bash automatisieren erheblichen Mehrwert bringt. Das konsistente Taggen von Images – mit Git-Commit-Hash, Semantic-Versionsnummer und latest-Alias – lässt sich als Bash-Funktion implementieren, die in alle CI-Pipelines eingebunden wird. Der Git-Commit-Hash als Image-Tag ist besonders wertvoll, weil er jedes Image eindeutig und unveränderbar einem Code-Stand zuordnet. docker buildx build --platform linux/amd64,linux/arm64 für Multi-Arch-Builds lässt sich ebenfalls in Bash-Workflows einbetten.

Registry-Aufräumskripte sind ein klassischer Anwendungsfall. Ohne automatisierte Bereinigung wächst eine Docker-Registry unkontrolliert. Ein Bash-Skript, das alle Tags eines Repositories listet, Tags nach Alter oder Commit-Status filtert und veraltete Tags löscht, verhindert dieses Problem. Die Docker-Registry-API ist über curl erreichbar, und jq parst die JSON-Antworten. Beim Docker und Kubernetes Workflows mit Bash automatisieren ist dieses Cleanup-Skript typischerweise ein nächtlicher Cron-Job, der sicherstellt, dass nur produktionsrelevante Images in der Registry verbleiben.


#!/usr/bin/env bash
# image-build-push.sh — Build, tag and push Docker image with consistent naming
set -euo pipefail

readonly REGISTRY="${REGISTRY:-registry.mironsoft.de}"
readonly APP_NAME="${APP_NAME:?APP_NAME must be set}"
readonly GIT_SHA="$(git rev-parse --short HEAD)"
readonly GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD | tr '/' '-')"
readonly BUILD_DATE="$(date -u +%Y%m%d)"

# Determine version tag
if git describe --exact-match HEAD 2>/dev/null; then
  VERSION_TAG="$(git describe --exact-match HEAD)"
else
  VERSION_TAG="${GIT_BRANCH}-${GIT_SHA}"
fi

readonly FULL_IMAGE="${REGISTRY}/${APP_NAME}"
readonly TAGS=(
  "${FULL_IMAGE}:${VERSION_TAG}"
  "${FULL_IMAGE}:${GIT_SHA}"
  "${FULL_IMAGE}:${GIT_BRANCH}-latest"
)

# Build once, tag multiple times
echo "[INFO] Building ${FULL_IMAGE}:${VERSION_TAG}..."
docker build \
  --build-arg BUILD_DATE="$BUILD_DATE" \
  --build-arg GIT_SHA="$GIT_SHA" \
  --build-arg VERSION="$VERSION_TAG" \
  --label "org.opencontainers.image.revision=$GIT_SHA" \
  --label "org.opencontainers.image.created=$BUILD_DATE" \
  -t "${TAGS[0]}" .

# Tag all variants from the same build
for tag in "${TAGS[@]:1}"; do
  docker tag "${TAGS[0]}" "$tag"
  echo "[INFO] Tagged: $tag"
done

# Push all tags
for tag in "${TAGS[@]}"; do
  docker push "$tag"
  echo "[OK] Pushed: $tag"
done

echo "[OK] Build complete: $VERSION_TAG ($GIT_SHA)"

5. kubectl in Bash-Rollout-Skripten

Das Docker und Kubernetes Workflows mit Bash automatisieren mit kubectl beginnt mit den richtigen Ausgabeformaten. kubectl get pods -o jsonpath='{.items[*].status.phase}' gibt die Status aller Pods im aktuellen Namespace aus – deutlich zuverlässiger zu parsen als die Klartextausgabe von kubectl get pods. Für komplexere Abfragen ist kubectl get deployment app -o json | jq '.status.availableReplicas' das Mittel der Wahl. jq ist in nahezu allen CI-Umgebungen verfügbar und verarbeitet die JSON-Ausgaben von kubectl präzise.

Beim Docker und Kubernetes Workflows mit Bash automatisieren ist die Verwaltung von kubeconfig-Kontexten eine häufige Herausforderung in Multi-Cluster-Umgebungen. Ein Bash-Skript, das vor dem Deployment den aktiven Kontext prüft, in einen temporären Kontext wechselt und ihn nach dem Deployment wieder zurücksetzt, verhindert versehentliche Deployments in falschen Clustern. Die Variable KUBECONFIG kann auf eine temporäre Konfigurationsdatei zeigen, die nur für die Dauer des Skripts gültig ist.


#!/usr/bin/env bash
# k8s-rollout.sh — Kubernetes rolling deployment with validation
set -euo pipefail

readonly NAMESPACE="${K8S_NAMESPACE:?K8S_NAMESPACE must be set}"
readonly DEPLOYMENT="${K8S_DEPLOYMENT:?K8S_DEPLOYMENT must be set}"
readonly IMAGE="${NEW_IMAGE:?NEW_IMAGE must be set}"
readonly ROLLOUT_TIMEOUT="${ROLLOUT_TIMEOUT:-300s}"
readonly CONTAINER_NAME="${CONTAINER_NAME:-app}"

# Validate kubectl context before proceeding
validate_context() {
  local current_context
  current_context="$(kubectl config current-context)"
  echo "[INFO] Deploying to Kubernetes context: $current_context"
  echo "[INFO] Namespace: $NAMESPACE, Deployment: $DEPLOYMENT"
  read -r -p "Proceed? [y/N] " confirm
  [[ "${confirm,,}" == "y" ]] || { echo "Aborted."; exit 0; }
}

# Get current image for rollback
get_current_image() {
  kubectl get deployment "$DEPLOYMENT" \
    -n "$NAMESPACE" \
    -o jsonpath="{.spec.template.spec.containers[?(@.name=='${CONTAINER_NAME}')].image}"
}

# Check all pods in deployment are ready
all_pods_ready() {
  local desired available
  desired="$(kubectl get deployment "$DEPLOYMENT" -n "$NAMESPACE" \
    -o jsonpath='{.spec.replicas}')"
  available="$(kubectl get deployment "$DEPLOYMENT" -n "$NAMESPACE" \
    -o jsonpath='{.status.availableReplicas}' 2>/dev/null || echo 0)"
  [[ "$available" == "$desired" ]]
}

[[ -t 0 ]] && validate_context

old_image="$(get_current_image)"
echo "[INFO] Current image: $old_image"
echo "[INFO] New image: $IMAGE"

# Trigger rolling update
kubectl set image deployment/"$DEPLOYMENT" \
  "${CONTAINER_NAME}=${IMAGE}" \
  -n "$NAMESPACE"

echo "[INFO] Waiting for rollout to complete (timeout: $ROLLOUT_TIMEOUT)..."
if ! kubectl rollout status deployment/"$DEPLOYMENT" \
    -n "$NAMESPACE" \
    --timeout="$ROLLOUT_TIMEOUT"; then
  echo "[FAIL] Rollout failed — triggering undo..." >&2
  kubectl rollout undo deployment/"$DEPLOYMENT" -n "$NAMESPACE"
  echo "[INFO] Rolled back to: $old_image"
  exit 1
fi

all_pods_ready && echo "[OK] All pods are ready"
echo "[OK] Deployment successful: $IMAGE"

6. Zero-Downtime-Rollouts mit Wartelogik

Zero-Downtime-Rollouts sind der anspruchsvollste Aspekt beim Docker und Kubernetes Workflows mit Bash automatisieren. Kubernetes implementiert Rolling Updates per Design – neue Pods starten, bevor alte beendet werden. Aber die Wartelogik im Bash-Skript muss sicherstellen, dass der Rollout wirklich vollständig und alle Pods healthy sind, bevor nachgelagerte Schritte ausgeführt werden. kubectl rollout status blockiert bis zum Erfolg oder Timeout und ist die einfachste Implementierung dieser Wartelogik.

Für differenziertere Kontrolle beim Docker und Kubernetes Workflows mit Bash automatisieren lohnt sich eine eigene Warte-Schleife, die nicht nur den Rollout-Status prüft, sondern auch Pods in CrashLoopBackOff oder OOMKilled aktiv erkennt und sofort ein Rollback auslöst – ohne auf den Timeout zu warten. kubectl get events --field-selector reason=BackOff -n $NAMESPACE liefert BackOff-Events in Echtzeit, und eine Bash-Schleife, die diese Events überwacht und gleichzeitig auf Rollout-Completion wartet, reagiert schneller auf fehlerhafte Deployments als das Standard-Timeout-Verhalten.

7. Automatisches Rollback bei fehlgeschlagenem Rollout

Das automatische Rollback ist ein entscheidendes Sicherheitsnetz beim Docker und Kubernetes Workflows mit Bash automatisieren. Kubernetes speichert die letzten Rollout-Revisionen und ermöglicht mit kubectl rollout undo deployment/app einen sofortigen Rollback auf die letzte bekannte gute Version. Ein Bash-Skript kombiniert diesen Befehl mit der Rollout-Überwachung: Schlägt der Rollout innerhalb des Timeouts fehl, wird automatisch kubectl rollout undo ausgeführt, und das Skript gibt Exit-Code 1 zurück – was die CI-Pipeline als fehlgeschlagenes Deployment markiert.

Wichtig beim Docker und Kubernetes Workflows mit Bash automatisieren mit Rollback: Das Rollback selbst muss ebenfalls überwacht werden. Ein fehlgeschlagenes Rollback – weil das vorige Image nicht mehr in der Registry verfügbar ist oder weil auch das alte Deployment CrashLoops hatte – ist ein kritischer Zustand, der sofort eskaliert werden muss. Ein vollständiges Bash-Skript implementiert deshalb einen Rollback-Timeout und sendet im Fehlerfall eine Benachrichtigung, bevor es mit Exit-Code 2 abbricht.

8. Kubernetes-Ressourcen und Pod-Status überwachen

Über einzelne Deployments hinaus gehört beim Docker und Kubernetes Workflows mit Bash automatisieren auch die Cluster-weite Ressourcenüberwachung zum Werkzeugkasten. kubectl top nodes und kubectl top pods liefern CPU- und Memory-Auslastung, die Bash-Skripte gegen definierte Schwellenwerte prüfen können. Ein Cron-Job, der diese Metriken sammelt und bei Überschreitung kritischer Grenzen eine Benachrichtigung sendet, ist eine einfache, aber effektive Ergänzung zu vollständigen Monitoring-Lösungen. Für Umgebungen ohne Prometheus oder Datadog ist dieser Bash-basierte Ansatz oft die pragmatischste Lösung.

Namespace-Snapshots – eine vollständige JSON-Ausgabe aller Kubernetes-Ressourcen eines Namespaces zu einem bestimmten Zeitpunkt – sind ein weiterer nützlicher Workflow beim Docker und Kubernetes Workflows mit Bash automatisieren. Vor jedem Deployment wird ein Snapshot des aktuellen Zustands gespeichert. Nach einem fehlgeschlagenen Rollback kann der Snapshot analysiert werden, um den Zustand vor dem Problem zu rekonstruieren. Diese Snapshots sind auch für Post-Mortem-Analysen wertvoll.

9. Docker vs. Kubernetes Automatisierung im Vergleich

Beim Docker und Kubernetes Workflows mit Bash automatisieren unterscheiden sich die Muster je nach Zielplattform erheblich. Diese Tabelle zeigt die wichtigsten Unterschiede.

Aspekt Docker (Standalone) Kubernetes (kubectl) Bash-Ansatz
Health-Check-Status docker inspect --format kubectl get pod -o jsonpath Warte-Schleife mit Timeout und CrashLoop-Erkennung
Rollback Altes Image neu starten kubectl rollout undo Automatisch bei Exit-Code ≠ 0, Rollback ebenfalls überwachen
Image-Tag-Strategie Registry frei wählbar ImagePullPolicy beachten Git-SHA + Semver-Tag, nie latest in Produktion
Kontext-Verwaltung DOCKER_HOST-Variable KUBECONFIG + Context Temporäre kubeconfig, Kontext vor Deploy validieren
Parallelität Mehrere Container manuell ReplicaSet verwaltet Pods Bash-Parallelisierung für Multi-Service-Deployments

Die Tabelle zeigt: Obwohl Docker und Kubernetes unterschiedliche CLIs haben, folgt die Bash-Automatisierung denselben Grundmustern. Warte-Schleifen mit Timeouts, automatisches Rollback bei Fehlern, Kontext-Validierung vor dem Deployment und strukturiertes Logging sind in beiden Umgebungen gleich wichtig. Wer diese Muster einmal als wiederverwendbare Bash-Funktionen implementiert, kann sie in beide Deployment-Arten einbinden.

Mironsoft

Docker- und Kubernetes-Automatisierung, DevOps-Tooling und Deployment-Infrastruktur

Docker und Kubernetes Workflows zuverlässig automatisieren?

Wir implementieren Health-Check-Überwachung, Zero-Downtime-Rollouts und automatische Rollback-Logik als robuste Bash-Skripte für eure Docker- und Kubernetes-Umgebung – CI/CD-Plattform-unabhängig und vollständig protokolliert.

Rollout-Skripte

Zero-Downtime-Deployments mit Health-Check-Validierung und automatischem Rollback

Image-Management

Build, Tag, Push und Registry-Cleanup als konsistenter Bash-Workflow

Cluster-Monitoring

Pod-Status, Ressourcenauslastung und Event-Überwachung als Bash-Cron-Jobs

10. Zusammenfassung

Wer Docker und Kubernetes Workflows mit Bash automatisieren will, braucht keine komplexen CI/CD-Plattform-Features – er braucht klare Muster: Warte-Schleifen für Health-Checks, automatisches Rollback bei Fehlern, strukturiertes Logging mit Exit-Codes und konsistentes Image-Tagging mit Git-SHAs. Diese Muster sind als Bash-Funktionen implementierbar, wiederverwendbar und funktionieren in jeder CI-Umgebung.

Der entscheidende Vorteil: Bash-Rollout-Skripte abstrahieren die Komplexität von Docker-CLI und kubectl hinter einer einheitlichen Schnittstelle. Neue Teammitglieder müssen nicht die Details beider CLIs kennen – sie sehen das Rollout-Skript und verstehen sofort, welche Schritte es ausführt, welche Fehlerbedingungen es abfängt und wie es bei Problemen reagiert. Das ist wartbare, dokumentierte Deployment-Automatisierung.

Docker und Kubernetes mit Bash automatisieren — Das Wichtigste auf einen Blick

Health-Check-Warte-Schleife

Nie direkt nach docker run oder kubectl apply weitermachen. Aktiv auf healthy-Status oder positive Readiness-Probe warten.

Automatisches Rollback

kubectl rollout undo bei Exit-Code ≠ 0. Das Rollback selbst ebenfalls überwachen und mit Timeout absichern.

Image-Tagging

Git-SHA + Semver-Tag. Niemals latest in Produktion – latest ist nicht immutable und macht Rollbacks unzuverlässig.

Kontext-Validierung

Kubernetes-Kontext vor jedem Deployment explizit prüfen und bestätigen lassen. Versehentliche Deployments in falschen Clustern sind häufiger als erwartet.

11. FAQ: Docker und Kubernetes Workflows mit Bash automatisieren

1Warum Bash statt Deployment-Tool für Docker/Kubernetes?
Bash-Skripte sind CI-Plattform-unabhängig, laufen überall und erzeugen keinen Tool-Lock-in. Für kleinere Teams oft wartbarer als Helm oder Ansible.
2Auf gesunden Docker-Container warten?
docker inspect --format='{ {.State.Health.Status} }' in Schleife abfragen. Bei 'healthy' weiter, bei 'unhealthy' sofort Fehler, nach Timeout Exit-Code 1.
3kubectl rollout status Timeout?
--timeout=300s wartet maximal 5 Minuten, dann Exit-Code 1. Mit set -e löst das automatisch Rollback-Logik aus.
4CrashLoopBackOff in Bash erkennen?
kubectl get pods -o jsonpath='{.items[*].status.containerStatuses[*].state.waiting.reason}' und auf CrashLoopBackOff prüfen.
5Warum nie 'latest' in Produktion?
latest ist nicht immutable. kubectl rollout undo funktioniert nicht verlässlich. Git-SHA macht jeden Deploy eindeutig und rollback-fähig.
6Mehrere Kubernetes-Kontexte sicher verwalten?
KUBECONFIG auf temporäre Datei setzen. Kontext vor Deploy explizit ausgeben und bestätigen. In CI aus Secrets injizieren.
7Registry-API mit Bash auf veraltete Images prüfen?
Docker Registry API v2 per curl: GET /v2/name/tags/list. Mit jq filtern, DELETE /v2/name/manifests/digest für alte Tags. Basic Auth per Authorization-Header.
8Multi-Arch-Images mit Bash bauen?
docker buildx build --platform linux/amd64,linux/arm64 --push -t registry/app:tag . — buildx als Builder aktivieren mit docker buildx create --use.
9Kubernetes-Snapshots vor Deployment?
kubectl get all -n $NAMESPACE -o json > snapshot-datum.json. In S3 oder Git versionieren für Post-Mortem-Analysen.
10Rollout-Skripte in GitHub Actions integrieren?
Als Shell-Step direkt ausführen: run: ./scripts/deploy.sh. KUBECONFIG aus Secrets als Umgebungsvariable. Exit-Code beendet den Workflow-Step automatisch.