— Cloud und DevOps

Multi-Cloud, Container, Auslieferung

Die Cloud ist eine Commodity-Schicht, die ich zusammensetze — kein Anbieter, an den ich gebunden bin.

Ich deploye über GCP, Azure und AWS, mit Edge-Runtimes und verwalteten Backends, wähle den stärksten Dienst für jede Rolle und orchestriere über Anbieter hinweg. Container, CI/CD und Infrastructure as Code stehen im Zentrum; Linux läuft darunter auf Administratorebene.

Die Haltung

Ich wähle nicht eine Cloud und biege jedes Problem darauf zu. Ich wähle den stärksten Dienst für jede Rolle und orchestriere über Anbieter hinweg.

Multi-Cloud ist für mich kein Schlagwort — es ist eine bewusste Weigerung, einen Anbieter die Architektur besitzen zu lassen. GCP, Azure und AWS können jeweils einige Dinge besser als die anderen, und Edge-Runtimes und verwaltete Backends füllen Rollen, die keiner der drei Großen sauber abdeckt. Die Aufgabe ist, pro Rolle gut zu wählen und das Ganze portabel zu halten.

Was das möglich macht, ist die Schicht darunter: Container und Infrastructure as Code im Zentrum, sodass ein einmal definierter Workload jeden Anbieter ansteuern kann, auf dem ein Projekt bereits lebt. Die Cloud wird zu einer Commodity, die ich austauschen kann, statt zu einer Abhängigkeit, um die herum ich planen muss.

Und unter dem Orchestrator gibt es immer noch einen Host. Ich betreibe Linux auf Administratorebene — Kernel-Tuning, sysctl-Härtung, systemd, Container-Runtimes und das Netzwerk unter den Diensten — weil die Teile, die die meisten als Standardwerte erben, die Teile sind, die ich lieber bewusst betreibe.

0

Haupt-Clouds, in die ich deploye — GCP, Azure und AWS — gewählt nach Rolle, nicht nach Gewohnheit

0

Anbieter, von denen ich die Architektur abhängen lasse; die Cloud ist eine Commodity-Schicht, die ich austauschen kann

0

Edge-Runtimes, die ich an der Netzwerkgrenze betreibe — Cloudflare Workers und Vercel Edge

0

verwaltete Datenbank-Backends, die ich bereithalte — Supabase, Firebase, PlanetScale, Neon

Multi-Cloud-Topologie

Eine Anwendung, drei Clouds, kein Lock-in.

Ein Workload, den ich portabel halte: Container und Infrastructure as Code im Zentrum, deploybar zu dem Anbieter, auf dem ein Projekt bereits läuft. Jeder Anbieter ist für die Rolle eingebunden, die er am besten erfüllt, und der Edge sitzt vor ihnen allen.

App-Kern Docker · K8s · IaC GCP Vertex AI · Cloud Run · GKE · Pub/Sub Azure AKS · Functions · Container Apps AWS Lambda · EKS · S3 · RDS · SQS BaaS Supabase · Firebase · Neon · PlanetScale Edge — CF Workers · Vercel Edge

Service-Auswahl — das stärkste Werkzeug pro Rolle

Modelltraining und Serving
Vertex AI (GCP)
Analytische Abfragen im großen Maßstab
BigQuery (GCP)
Ereignisbus / Verteilung
Pub/Sub (GCP) · SQS/SNS (AWS)
Auf null skalierende Container
Cloud Run (GCP) · Container Apps (Azure)
Vollständiges Kubernetes
GKE · AKS · EKS
Ereignisgesteuerte Funktionen
Cloud Functions · Azure Functions · Lambda
Objektspeicher
Cloud Storage (GCP) · S3 (AWS)
Relationale Datenbank
RDS (AWS) · Neon · PlanetScale
Edge-Compute
Cloudflare Workers · Vercel Edge
CDN
CloudFront (AWS)

Für jede Rolle wähle ich den Anbieter, der es am besten kann, und orchestriere dann darüber — die Cloud sollte eine Commodity sein, die ich austauschen kann, nie eine Abhängigkeit, die das Produkt besitzt.

Anbieter für Anbieter

Wofür jede Cloud tatsächlich da ist.

Die vier Reiter unten sind keine Rangliste. Jeder ist eine Reihe von Rollen, die ein bestimmter Anbieter gut erfüllt, und die Disziplin besteht darin, einen Workload dem passenden zuzuordnen, statt alles auf ein einziges Konto zu zwingen. GCP für Daten und Modelle, Azure innerhalb des Microsoft-Umfelds, AWS als breiter Standard und der Edge und die verwalteten Backends für den schnellen Weg.

Google Cloud — wo Daten- und Modellarbeit meist angesiedelt ist

GCP ist der Ort, an dem ich Workloads platziere, die Daten und Modelle berühren. Vertex AI für Training und Serving, BigQuery für analytische Abfragen über große Tabellen und Pub/Sub als Nachrichtenbus, wenn Dienste Ereignisse verteilen müssen, ohne voneinander zu wissen.

Für Compute greife ich zu Cloud Run, wenn ein Container zwischen Anfragen auf null skalieren soll, zu Cloud Functions für kleine ereignisgesteuerte Handler und zu GKE, wenn ein Workload die volle Kubernetes-Oberfläche braucht. Firestore und Cloud Storage decken Dokumentzustand und Objekte ab.

  • Vertex AI für Modelltraining und Serving
  • Cloud Run · Cloud Functions · GKE für Compute über das gesamte Skalierungsspektrum
  • Pub/Sub · BigQuery · Firestore · Cloud Storage für Messaging, Analytik, Zustand und Objekte
Container und Kubernetes

Die Deploy-Einheit ist überall dieselbe, wo sie landet.

ingress DienstLastverteilung Cluster — GKE · AKS · EKS pod · img@sha pod · img@sha pod · img@sha

Docker · Kubernetes · Container-Sicherheit

Ein unveränderliches Image, von Kubernetes geplant, identisch über alle Anbieter.

Alles wird als Container ausgeliefert. Ein Workload wird als unveränderliches Docker-Image verpackt, einmal gebaut, und genau dieses Image läuft in jeder Umgebung — es gibt keinen Neubau, der zwischen Staging und Produktion still abweichen könnte.

Kubernetes plant es auf dieselbe Weise, ob der Cluster GKE, AKS oder EKS ist, sodass der Workload schon durch seine Konstruktion portabel ist. Sicherheit ist in das Image eingebaut, statt nachträglich hinzugefügt: minimale Basis-Images, Nicht-Root-Benutzer, schreibgeschützte Dateisysteme, entzogene Linux-Capabilities und ein Scan, bevor irgendetwas gepusht wird.

  • Ein unveränderliches Image, einmal gebaut, überall ausgeführt
  • Identisch auf GKE, AKS oder EKS geplant
  • Minimale Basis-Images, Nicht-Root, schreibgeschützt, entzogene Capabilities
  • Gescannt, bevor es eine Registry erreicht
DockerKubernetesContainer-Sicherheit

Kubernetes-Workload — Betriebsform

Orchestrator
Kubernetes — GKE, AKS oder EKS
Deploy-Einheit
Unveränderliches Container-Image, einmaliger Build
Skalierung
Horizontales Pod-Autoscaling anhand von Metriken
Config und Secrets
ConfigMaps und Secrets, zur Laufzeit eingebunden
Ingress
Verwalteter Load Balancer · CDN davor
Rollout
Rolling, Canary oder Blue-Green
Image-Quelle
Registry mit unveränderlichen, signierten Tags
CI/CD

Das Image wird einmal gebaut und unverändert promotet.

Eine Pipeline, die ich als nicht verhandelbare Infrastruktur behandle. Aus einem Commit wird das Image einmal gebaut und getestet, gescannt, mit einem unveränderlichen Tag gepusht und durch jedes Tor promotet — sodass das, was in der Produktion läuft, Byte für Byte das ist, was die Tests bestanden hat.

commit build+ test scan push anwendenIaC promotencanary

Vom Commit zur Produktion — GitHub Actions / GitLab CI

  1. 01 Commit Ein Push ins Repository ist der einzige Auslöser; nichts wird von Hand gebaut.
  2. 02 Build + Test GitHub Actions oder GitLab CI baut das Container-Image einmal und führt die Testsuite dagegen aus.
  3. 03 Scan Das Image wird auf bekannte Schwachstellen gescannt und der Abhängigkeitsbaum geprüft, bevor es weitergehen darf.
  4. 04 Push Das signierte Image wird mit einem unveränderlichen Tag in eine Registry gepusht — nie überschrieben.
  5. 05 IaC anwenden Infrastructure as Code plant die Änderung, zeigt das Diff und wendet es dann an, damit die Umgebung dem Repository entspricht.
  6. 06 Promotion Dasselbe Image wird hinter einem Canary- oder Blue-Green-Schalter ausgerollt, mit der Vorgängerversion einen Befehl entfernt.
Ein kleines Stück des Echten

Die Pipeline, als Datei.

Ein gekürzter GitHub-Actions-Workflow — das Image einmal bauen, testen, scannen, dann mit einem unveränderlichen Tag pushen. Dasselbe Image wird später in jede Umgebung promotet; nichts wird stromabwärts neu gebaut.

name: build-and-deploy
on:
  push:
    branches: [ main ]

jobs:
  ship:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    env:
      IMAGE: ghcr.io/${{ github.repository }}:${{ github.sha }}
    steps:
      - uses: actions/checkout@v4

      - name: Build image (once)
        run: docker build -t "$IMAGE" .

      - name: Test
        run: docker run --rm "$IMAGE" go test ./...

      - name: Scan for vulnerabilities
        run: trivy image --exit-code 1 --severity HIGH,CRITICAL "$IMAGE"

      - name: Push immutable tag
        run: |
          echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
          docker push "$IMAGE"
Ein Container, als Datei

Das Image, so definiert, wie es ausgeliefert wird.

Ein mehrstufiges Dockerfile — in einem vollständigen Build-Image kompilieren, dann nur das Binary in eine minimale Runtime kopieren, die als Nicht-Root-Benutzer läuft. Kleine Oberfläche, nichts im Image, das das Programm nicht braucht.

# --- build stage: full toolchain, thrown away after compile ---
FROM golang:1.22 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /out/app ./cmd/app

# --- runtime stage: minimal, non-root, only the binary ---
FROM gcr.io/distroless/static:nonroot
COPY --from=build /out/app /app
USER nonroot:nonroot
EXPOSE 8080
ENTRYPOINT ["/app"]
Infrastructure as Code

Deklariert, geplant, geprüft, angewendet.

Codedeklariert PlanDiff prüfenfreigeben anwendenlive = Repo Drift-Prüfung führt zurück zum Code

Die Umgebung lebt im Repository

Niemand klickt die Produktion ins Dasein.

Jedes Stück Infrastruktur — Netzwerke, Cluster, Queues, Datenbanken — wird als Code deklariert und lebt in der Versionskontrolle neben der Anwendung. Eine Änderung wird als Diff vorgeschlagen, als Probelauf geplant, wie jeder andere Code geprüft und dann angewendet.

Der Punkt ist, dass das Repository die einzige Quelle der Wahrheit ist. Eine periodische Neuplanung fängt jede manuelle Drift ab, sodass die Live-Umgebung stets mit dem abgeglichen wird, was der Code sagt, dass sie sein soll. Eine Umgebung wird reproduzierbar statt das Produkt erinnerter Konsolenklicks.

  • Netzwerke, Cluster, Queues und Datenbanken als Code
  • Der Plan zeigt das Diff, bevor sich etwas ändert
  • Wie Code geprüft, nicht in einer Konsole geklickt
  • Drift-Prüfungen halten das Repository maßgeblich
IaCReproduzierbarVersionskontrolliert

Infrastructure as Code — von deklarieren bis abgleichen

  1. 01 Schreiben Infrastruktur wird als Code deklariert — Netzwerke, Cluster, Queues, Datenbanken — in der Versionskontrolle neben der Anwendung.
  2. 02 Planen Ein Probelauf berechnet das Diff zwischen deklariertem und Live-Zustand, sodass jede Änderung sichtbar ist, bevor sie geschieht.
  3. 03 Prüfen Der Plan wird wie jede andere Codeänderung geprüft; niemand klickt in einer Konsole, um die Produktion zu verändern.
  4. 04 Anwenden Der Plan wird angewendet; die Live-Umgebung entspricht nun exakt dem Repository.
  5. 05 Drift prüfen Periodische Neuplanungen fangen manuelle Änderungen ab, sodass der deklarierte Zustand die einzige Quelle der Wahrheit bleibt.
Der Host darunter

Linux auf Administratorebene.

Über dem Orchestrator gibt es Kubernetes; darunter gibt es immer noch einen Linux-Host, und das ist eine Schicht, die ich bewusst betreibe, statt sie zu erben.

Container entfernen das Betriebssystem nicht — sie sitzen darauf. Ich betreibe Linux auf Administratorebene: Kernel-Tuning für den Workload, sysctl-Härtung, um die Laufzeit-Kerneloberfläche zu verengen, systemd, um Dienste mit Neustart-Richtlinien und Ressourcenlimits zu definieren, die Container-Runtimes selbst und das Netzwerk, das jedes Paket vom Edge bis zu einem Pod trägt.

Das ist derselbe Instinkt, der sich durch den Rest meiner Arbeit zieht. Die Teile, die die meisten als Standardwerte hinnehmen — die Kernel-Parameter, die Firewall-Regeln, das Basis-Image, aus dem ein Container gebaut wird — sind die Teile, die ich lieber verstehe und bewusst setze, denn von dort kommen still Zuverlässigkeit und Sicherheit.

01

Kernel-Tuning

Anpassung der Kernel-Parameter an den Workload — Dateideskriptor-Limits, Netzwerkpuffer, Scheduler-Verhalten — statt die Standardwerte der Distribution hinzunehmen.

02

sysctl-Härtung

Verengung der Laufzeit-Kerneloberfläche über sysctl: Einstellungen des Netzwerkstapels, Schutzmechanismen des Adressraums und Abschalten dessen, was ein Server keinen Grund hat offenzulegen.

03

systemd

Dienste als systemd-Units definiert mit Neustart-Richtlinien, Ressourcenlimits und Abhängigkeitsreihenfolge, damit sich der Host über Neustarts hinweg vorhersagbar verhält.

04

Container-Runtimes

Arbeit auf Runtime-Ebene — Docker und die darunterliegende OCI-Schicht — einschließlich Namespaces, cgroups und der Image-Interna, nicht nur die High-Level-Befehle.

05

Netzwerk

Das Netzwerk unter den Diensten: Routing, Firewall-Regeln, DNS, TLS-Terminierung und der Weg, den ein Paket vom Edge bis zu einem Pod nimmt.

06

Container-Sicherheit

Minimale Basis-Images, Nicht-Root-Benutzer, schreibgeschützte Dateisysteme, entzogene Capabilities und Image-Scanning — was ein kompromittierter Container erreichen kann, wird reduziert.

Beobachtbarkeit

Ein System, in das man nicht hineinsehen kann, ist eines, das man nicht betreiben kann.

Sobald ein Workload über Funktionen, Container und Queues bei mehr als einem Anbieter verteilt ist, kann man ihn nicht aus dem Bauch heraus betreiben. Beobachtbarkeit ist der Teil, der ein verteiltes System wieder in etwas verwandelt, über das man nachdenken kann — Metriken für Trends, Logs für das Detail, Traces für den Weg, den eine Anfrage genommen hat, und Alarme, die bei Symptomen benachrichtigen, die ein Nutzer tatsächlich spüren würde.

Ich behandle den Beobachtbarkeits-Stack als Teil des Builds, nicht als etwas, das nach dem ersten Vorfall angeschraubt wird. Die vier Reiter unten sind die Schichten, die ich instrumentiere, und die Reihenfolge zählt: eine Metrik zeigt auf das Problem, ein Trace grenzt es auf einen Sprung ein, und die Logs erklären, was bei genau dieser Anfrage geschah.

Zahlen über die Zeit, damit Trends sichtbar werden, bevor sie zu Vorfällen werden

Metriken sind das günstige, stets aktive Signal: Anfrageraten, Fehlerraten, Latenz-Perzentile, Ressourcensättigung. Sie sind das, was ein Autoscaler liest und worauf eine Warnung auslöst, weil sie numerisch und kontinuierlich sind.

Ich instrumentiere die Dinge, die einer Nutzererfahrung entsprechen — die Latenz, die eine Anfrage tatsächlich erlebt, die Fehlerrate, die ein Client tatsächlich trifft — statt nur Zähler auf Host-Ebene, die gesund aussehen, während das Produkt versagt.

  • Anfragerate, Fehlerrate, Latenz-Perzentile
  • Ressourcensättigung, die das Autoscaling antreibt
  • Signale, die an die Nutzererfahrung gebunden sind, nicht nur Host-Zähler
MetrikenRate · Latenz Logsstrukturiert Tracespro Anfrage sammelnzentralisieren DashboardsTrends über die Zeit Alarmierungbenachrichtigt bei Symptomen
Die Schichten, von unten nach oben

Vom Kernel bis zur Cloud, ein Stack.

Host, Container, Pipeline, Cloud — von unten nach oben gelesen, ist die Arbeit ein durchgehender Stack statt vier getrennter Anliegen.

Jede Schicht ruht auf der darunter. Ein gehärteter Linux-Host trägt eine Container-Runtime; ein unveränderliches Image läuft auf Kubernetes; eine CI/CD-Pipeline und Infrastructure as Code machen das Ganze reproduzierbar; und ein Multi-Cloud-Deployment verteilt es, ohne sich auf einen einzigen Anbieter festzulegen.

Auseinandergenommen wirken sie wie getrennte Spezialgebiete. Zusammen betrieben sind sie eine einzige Disziplin: bewusst auf jeder Schicht, portabel über Anbieter hinweg und reproduzierbar aus einem Repository statt aus dem Gedächtnis.

  1. Host Linux auf Administratorebene Kernel-Tuning, sysctl-Härtung, systemd-Units, Container-Runtimes und das Netzwerk darunter — die Schicht, die die meisten erben, bewusst betrieben.
  2. Container Docker und Kubernetes Workloads als unveränderliche Container-Images verpackt und auf Kubernetes — GKE, AKS oder EKS — betrieben, sodass die Deploy-Einheit überall dieselbe ist, wo sie landet.
  3. Pipeline CI/CD und Infrastructure as Code GitHub Actions und GitLab CI bauen und promoten das Image; als Code deklarierte Infrastruktur macht die gesamte Umgebung reproduzierbar statt von Hand gebaut.
  4. Cloud Multi-Cloud, nach Rolle GCP, Azure und AWS — plus Edge-Runtimes und verwaltete Backends — nach Rolle ausgewählt und zusammen orchestriert, ohne dass ein einzelner Anbieter die Architektur besitzt.
Wie ich arbeite

Die Prinzipien unter der Plattform.

Die Anbieter und Werkzeuge ändern sich mit dem Projekt; die Prinzipien nicht. Dies sind die Regeln, die ich anwende, ob das Ziel GCP, Azure, AWS, der Edge oder ein verwaltetes Backend ist — der Teil, der die Plattform reproduzierbar macht statt zufällig.

01

Den stärksten Dienst pro Rolle wählen

Für jede Rolle — Modell-Serving, den Ereignisbus, die Datenbank, den Edge — wähle ich den Anbieter, der es am besten kann, und orchestriere dann darüber. Das Ergebnis ist ein System, das aus den richtigen Teilen zusammengesetzt ist, nicht aus den bequemen.

02

Nie von einer einzigen Cloud abhängen

Container und Infrastructure as Code stehen im Zentrum, damit derselbe Workload GCP, Azure oder AWS ansteuern kann. Die Cloud ist eine Commodity, die ich austauschen kann, keine Abhängigkeit, die das Produkt besitzt.

03

Das Image einmal bauen, unverändert promoten

Ein Image wird ein einziges Mal gebaut und Byte für Byte durch jedes Tor bis zur Produktion bewegt. Was in der Produktion läuft, ist genau das, was die Tests bestanden hat, kein Neubau, der abweichen könnte.

04

Infrastruktur deklarieren, nie klicken

Netzwerke, Cluster, Queues und Datenbanken werden als Code deklariert, geplant, geprüft und angewendet. Niemand verändert die Produktion in einer Konsole, sodass das Repository die einzige Quelle der Wahrheit bleibt.

05

Den Host darunter härten

Linux auf Administratorebene zu betreiben — Kernel-Tuning, sysctl-Härtung, systemd, Container-Runtimes, Netzwerk — bedeutet, dass die Schicht unter dem Orchestrator bewusst gestaltet ist, nicht auf Standardwerten belassen.

06

Das System beobachtbar machen

Metriken, Logs und Traces sind Teil des Builds, nicht nachträglich nach einem Vorfall angeschraubt. Ein System, in das man nicht hineinsehen kann, ist ein System, das man nicht betreiben kann.

Den stärksten Dienst pro Rolle wählen, den Workload mit Containern und Code portabel halten, das Image einmal bauen und den Host darunter härten — alles andere ist Detail.

Open to the right work

Wenn Sie eine Plattform brauchen, die über Clouds hinweg läuft, ohne zu einer einzigen von ihnen zu gehören, dann ist das die Arbeit, die ich mache.

If you are holding a problem that doesn't fit inside one field, that is the conversation I want.

NextCybersecurity