Veröffentlicht am

Kubernetes Omnichannel-Backend für den Einzelhandel

Teilen:
Authors

TL;DR

  • Omnichannel im Einzelhandel bedeutet: Online-Shop, POS-System, Warenwirtschaft und Click-and-Collect muessen in Echtzeit synchron laufen
  • Horizontal Pod Autoscaling faengt Lastspitzen (Black Friday, Saisonverkauf) automatisch ab -- ohne Ueberprovisionierung an normalen Tagen
  • Bestandssynchronisation ueber Event-Driven Architecture mit Kafka auf Kubernetes eliminiert Phantom-Bestaende und Ueberbuchungen
  • IT-Teams im Einzelhandel sind zu klein fuer den Betrieb einer Container-Plattform -- Managed Kubernetes ab 4.000 EUR/Monat loest das Problem
  • ROI nach 6 Monaten: Weniger IT-Ueberstunden, 99,9% Verfuegbarkeit an Peak-Tagen, 40% schnellere Feature-Releases

Kubernetes fuer Einzelhandel: Omnichannel-Backend ohne IT-Ueberstunden

Kunden erwarten heute, dass der Online-Bestand mit der Filiale uebereinstimmt, dass eine Online-Bestellung in der Filiale abgeholt werden kann und dass die Retoure egal ueber welchen Kanal funktioniert. Fuer die IT-Abteilung eines mittelstaendischen Einzelhaendlers bedeutet das: Systeme, die nie fuer diese Integration gebaut wurden, muessen in Echtzeit zusammenarbeiten.

Kubernetes kann die technische Basis fuer diese Omnichannel-Integration liefern. Aber die eigentliche Frage ist: Wer betreibt das Ganze, wenn das IT-Team schon mit dem Tagesgeschaeft ausgelastet ist?

Die Omnichannel-Herausforderung im Mittelstand

Was Omnichannel wirklich bedeutet

Omnichannel ist mehr als ein Online-Shop neben dem Ladengeschaeft. Es bedeutet, dass alle Kanaele -- stationaer, online, mobil und Marktplatz -- auf den gleichen Datenbestand zugreifen und in Echtzeit synchronisiert sind.

KanalSystemProblem ohne Integration
Filiale (POS)Kassensystem (Vectron, Korona, etc.)Filialbestand weicht vom Online-Bestand ab
Online-ShopShopware, Magento, ShopifyKunden bestellen Artikel, die in der Filiale bereits verkauft wurden
Click-and-CollectLogik zwischen POS und ShopReservierung funktioniert nicht, Ware ist bei Abholung weg
MarktplaetzeAmazon, Otto, ZalandoBestand muss pro Plattform gepflegt werden, Ueberbuchungen
Mobile AppReact Native, FlutterAndere Preise oder Verfuegbarkeiten als im Shop

Das Ergebnis ohne saubere Integration: veraergerte Kunden, Ueberbuchungen, manuelle Korrekturen und ein IT-Team, das staendig Feuer loescht.

Typisches IT-Team im Einzelhandel

Ein Einzelhaendler mit 20 bis 50 Filialen und 500 Mitarbeitern hat typischerweise:

  • 2-4 IT-Mitarbeiter (kein dediziertes Infrastruktur-Team)
  • Einen externen Dienstleister fuer den Online-Shop
  • Einen weiteren Dienstleister fuer das Kassensystem
  • Keine DevOps- oder Kubernetes-Kompetenz im Haus

Wenn dieses Team auch noch eine Container-Plattform betreiben soll, sind Ueberstunden und Wissenslucken vorprogrammiert. Genau hier setzt Managed Kubernetes an.

Referenzarchitektur: Omnichannel auf Kubernetes

Gesamtarchitektur

Eine Omnichannel-Architektur auf Kubernetes besteht aus spezialisierten Microservices, die ueber einen Event-Bus (Kafka) kommunizieren. Jeder Service ist unabhaengig deploybar und skalierbar.

ServiceFunktionSkalierungKritikalitaet
Product-APIArtikelstammdaten, PreiseHPA, 3-8 ReplicasHoch
Inventory-ServiceBestandsfuehrung in EchtzeitHPA, 3-6 ReplicasKritisch
Order-ServiceBestellungen aller KanaeleHPA, 3-10 ReplicasKritisch
POS-GatewayAnbindung KassensystemeFixed 3 ReplicasKritisch
Search-ServiceProduktsuche (Elasticsearch)HPA, 2-6 ReplicasHoch
Price-EngineDynamische PreisberechnungHPA, 2-4 ReplicasMittel
Notification-ServiceE-Mail, Push, SMSHPA, 2-4 ReplicasNiedrig

Inventory-Service: Das Herzstueck

Der Inventory-Service ist der kritischste Baustein. Er fuehrt den Echtzeit-Bestand ueber alle Kanaele und Filialen. Jeder Verkauf an der Kasse, jede Online-Bestellung und jede Retoure aendert den Bestand sofort.

# inventory-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: inventory-service
  namespace: omnichannel
  labels:
    app: inventory-service
    tier: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: inventory-service
  template:
    metadata:
      labels:
        app: inventory-service
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: inventory-service
      containers:
      - name: inventory
        image: registry.retailer.de/inventory-service:3.2.1
        ports:
        - containerPort: 8080
        env:
        - name: KAFKA_BOOTSTRAP_SERVERS
          value: "kafka-cluster-kafka-bootstrap.kafka:9092"
        - name: REDIS_URL
          value: "redis://inventory-cache:6379"
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: inventory-db-credentials
              key: host
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1000m"
            memory: "1Gi"
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
          initialDelaySeconds: 20
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

Event-Driven Bestandssynchronisation mit Kafka

Statt dass jedes System den Bestand direkt in der Datenbank aendert (was zu Race Conditions und inkonsistenten Daten fuehrt), laeuft die Synchronisation ueber Events:

# kafka-topics fuer Omnichannel
# Kafka-Cluster auf Kubernetes mit Strimzi Operator
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
  name: inventory-events
  namespace: kafka
  labels:
    strimzi.io/cluster: omnichannel-kafka
spec:
  partitions: 12
  replicas: 3
  config:
    retention.ms: "604800000"
    min.insync.replicas: 2
---
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
  name: order-events
  namespace: kafka
  labels:
    strimzi.io/cluster: omnichannel-kafka
spec:
  partitions: 12
  replicas: 3
  config:
    retention.ms: "604800000"
    min.insync.replicas: 2
---
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
  name: pos-transactions
  namespace: kafka
  labels:
    strimzi.io/cluster: omnichannel-kafka
spec:
  partitions: 24
  replicas: 3
  config:
    retention.ms: "604800000"
    min.insync.replicas: 2

Der Ablauf bei einem Verkauf an der Kasse:

  1. Kassensystem sendet Transaktion an POS-Gateway
  2. POS-Gateway publiziert Event auf pos-transactions Topic
  3. Inventory-Service konsumiert Event und reduziert Bestand
  4. Inventory-Service publiziert stock-updated Event
  5. Online-Shop, App und Marktplatz-Connectoren konsumieren das Update
  6. Kunde sieht aktualisierten Bestand innerhalb von 2-5 Sekunden

Autoscaling: Black Friday ohne Nachtschicht

Das Lastprofil im Einzelhandel

Einzelhandel hat eines der extremsten Lastprofile aller Branchen:

Normaler Tag:    ████░░░░░░  100 Requests/Sekunde
Samstag:         ██████░░░░  200 Requests/Sekunde
Saisonstart:     ████████░░  400 Requests/Sekunde
Black Friday:    ██████████  1.000+ Requests/Sekunde

Ohne Autoscaling muesste die Infrastruktur permanent fuer 1.000 Requests/Sekunde ausgelegt sein. Das bedeutet 80% Leerlauf an 360 Tagen im Jahr.

HPA-Konfiguration fuer den Online-Shop

# shop-frontend-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: shop-frontend-hpa
  namespace: omnichannel
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: shop-frontend
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "50"
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
      - type: Pods
        value: 4
        periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Pods
        value: 1
        periodSeconds: 120

Die Konfiguration im Detail:

  • Minimum 3 Replicas: Auch bei niedriger Last immer Hochverfuegbarkeit
  • Maximum 20 Replicas: Deckt Black-Friday-Traffic ab
  • Scale-Up: 4 Pods pro Minute: Schnelle Reaktion auf steigende Last
  • Scale-Down: 1 Pod alle 2 Minuten: Langsames Zurueckfahren verhindert Flapping
  • Stabilisierung: 30 Sekunden beim Hochskalieren, 5 Minuten beim Herunterskalieren

Fuer eine tiefergehende Erklaerung von Autoscaling-Strategien und Kostenoptimierung empfehlen wir den Artikel Kubernetes Autoscaling und Kosten sparen.

POS-Gateway: Stabile Latenz statt Autoscaling

Das POS-Gateway zum Kassensystem laeuft bewusst mit fester Replica-Anzahl. Kassensysteme brauchen vorhersagbare Latenz unter 100ms. Autoscaling wuerde durch Cold-Start-Zeiten neuer Pods kurzzeitige Latenz-Spitzen verursachen.

Die wichtigsten Konfigurationsdetails: replicas: 3 (fest, kein HPA), maxUnavailable: 0 (bei Rolling Updates faellt kein Pod weg, bevor der neue bereit ist), aggressive Liveness-Probes mit failureThreshold: 2 (ein nicht reagierender Pod wird schnell ersetzt). Bei Kassensystemen ist jede Sekunde Ausfall ein Umsatzverlust.

Kostenvergleich: Eigenbetrieb vs. Managed Kubernetes

Szenario: Einzelhaendler mit 30 Filialen, Online-Shop, 500 Mitarbeiter

Option A: Eigenbetrieb

PositionMonatliche Kosten
2 zusaetzliche IT-Mitarbeiter (Kubernetes-Kompetenz)14.000 EUR
Cloud-Infrastruktur (3 Cluster)4.000 EUR
Tooling (Monitoring, Logging, CI/CD)1.500 EUR
Weiterbildung und Zertifizierungen500 EUR
On-Call-Zulagen800 EUR
Gesamt pro Monat20.800 EUR

Dazu kommen versteckte Kosten: Einarbeitung (3-6 Monate bis zur Produktivitaet), Kuendigungsrisiko (Nachbesetzung dauert 4-8 Monate), Wissensverlust bei Fluktuation.

Option B: Managed Kubernetes

PositionMonatliche Kosten
Managed Kubernetes Service4.000 EUR
Cloud-Infrastruktur3.500 EUR
Tooling (im Managed Service enthalten)0 EUR
Gesamt pro Monat7.500 EUR

Die Differenz: 13.300 EUR pro Monat oder 159.600 EUR pro Jahr. Und das IT-Team kann sich auf das konzentrieren, wofuer es eingestellt wurde: den Einzelhandel digital voranbringen, nicht Kubernetes-Cluster patchen.

Wie Sie den ROI eines Managed Service genau berechnen, zeigt unser Artikel Was 4.000 EUR/Monat Managed Kubernetes beinhaltet.

Click-and-Collect: Ein konkreter Use Case

Click-and-Collect ist der Omnichannel-Use-Case, der am meisten von einer sauberen Kubernetes-Architektur profitiert. Der Ablauf:

  1. Kunde bestellt online und waehlt Filiale zur Abholung
  2. Order-Service prueft Verfuegbarkeit ueber den Inventory-Service
  3. Inventory-Service reserviert Bestand in der gewaehlten Filiale
  4. Notification-Service informiert die Filiale per Push-Nachricht
  5. Filialmitarbeiter kommissioniert und bestaetigt ueber POS-App
  6. Notification-Service informiert den Kunden: Bereit zur Abholung

Ohne Kubernetes laeuft das typischerweise so: Der Online-Shop hat einen Batch-Export, der alle 15 Minuten Bestellungen an das Filialsystem schickt. In diesen 15 Minuten kann der Artikel in der Filiale verkauft worden sein. Ergebnis: Kunde kommt zur Abholung, Ware ist nicht da.

Mit Event-Driven Architecture auf Kubernetes passiert die Reservierung in Echtzeit. Der Bestand wird innerhalb von Sekunden aktualisiert, nicht alle 15 Minuten.

DSGVO-Konformitaet im Einzelhandel

Einzelhaendler verarbeiten personenbezogene Daten: Kundenadressen, Bestellhistorien, Zahlungsdaten. Auf Kubernetes muessen folgende Punkte beachtet werden:

# network-policy-dsgvo.yaml
# Payment-Service darf nur mit dem Payment-Provider kommunizieren
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: payment-isolation
  namespace: omnichannel
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: order-service
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - ipBlock:
        cidr: 203.0.113.0/24
    ports:
    - protocol: TCP
      port: 443
  - to:
    - podSelector:
        matchLabels:
          app: inventory-cache
    ports:
    - protocol: TCP
      port: 6379

Diese Network Policy stellt sicher, dass der Payment-Service nur vom Order-Service angesprochen werden kann und selbst nur mit dem Payment-Provider und dem Cache kommuniziert. Kein anderer Service kommt an Zahlungsdaten. Fuer einen umfassenden DSGVO-Leitfaden lesen Sie Cloud, DSGVO und Kubernetes-Compliance.

Checkliste: Ist Ihr Einzelhandel bereit fuer Kubernetes?

  • Online-Shop und Filialsystem zeigen unterschiedliche Bestaende
  • Black Friday oder Saisonstart fuehrt regelmaessig zu Performance-Problemen
  • Click-and-Collect funktioniert nur mit manuellem Eingriff zuverlaessig
  • Das IT-Team macht regelmaessig Ueberstunden wegen Infrastruktur-Problemen
  • Neue Features im Online-Shop dauern Monate statt Wochen
  • Anbindung neuer Marktplaetze scheitert an der bestehenden Architektur

Drei oder mehr Haken? Dann lohnt sich ein Gespraech ueber eine Omnichannel-Plattform auf Managed Kubernetes.


Verwandte Artikel


Ihr Omnichannel-Backend soll stabil laufen -- ohne dass Ihr IT-Team Nachtschichten schiebt? Wir betreiben Ihre Kubernetes-Plattform, damit Online-Shop, Kasse und Filiale reibungslos zusammenspielen. Jetzt Erstgespraech vereinbaren.

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