Kubernetes für Trading-Bots.
Kubernetes hat in der Trading-Community einen zwiespältigen Ruf — die einen halten es für übertriebene Komplexität, die anderen führen alles auf K8s aus, auch was nicht hingehört. Wahrheit liegt wie immer dazwischen. Dieser Artikel zeigt, wann Kubernetes für Trading-Bots wirklich Sinn ergibt, welche Patterns sich bewähren — und welche Fehler ich bei Mandanten regelmäßig sehe.
Wann Kubernetes Sinn ergibt — und wann nicht.
Eine einzelne Strategie, die auf einem Symbol läuft und einmal pro Tag entscheidet?
Kein Kubernetes. Ein systemd-Service auf einem VPS ist die richtige Antwort.
Zwei Strategien, jeweils mit eigenem Python-Env, auf demselben Broker? Auch noch
systemd oder docker-compose.
Kubernetes lohnt sich, wenn drei oder mehr der folgenden Punkte zutreffen: mehrere unabhängige Strategien mit unterschiedlichen Dependencies, regelmäßige Backtests die parallel laufen sollen, mehrere Datenanbieter mit eigenen Worker-Pools, Mandanten- Workloads die isoliert laufen müssen, oder Compliance-Anforderungen die einen auditierbaren Deployment-Prozess verlangen. Wenn nichts davon zutrifft, sparen Sie sich die Komplexität. Kubernetes ist nicht kostenlos — auch wenn die Compute-Kosten gleich bleiben, kostet der Betrieb in Stunden und Stress mehr als ein VPS.
Cluster-Setup: Managed oder selbst betrieben?
Für Trading-Workloads gibt es genau eine richtige Antwort: Managed Kubernetes beim Cloud-Provider (EKS, GKE, AKS). Selbst betriebenen K8s-Cluster für Trading aufzusetzen ist ein Fehler — Sie bezahlen mit Ausfallzeit, was Sie an Lizenzkosten sparen.
Konkret nutze ich für die meisten Setups GKE Autopilot oder EKS Fargate. Beide abstrahieren die Node-Verwaltung vollständig weg, Sie zahlen nur für die CPU- und Memory-Requests Ihrer Pods. Für eine moderate Workload (zehn bis zwanzig Pods) liegen die Kosten bei rund 200 bis 400 Euro pro Monat — vergleichbar mit drei bis vier dedizierten VPS-Instanzen, aber mit Selbstheilung, Rolling Updates und ordentlicher Observability.
Das Strategie-Pod-Pattern.
Eine Trading-Strategie besteht aus mehreren Komponenten, die unterschiedliche Lebens-
zyklen haben: ein Datenanbieter-Connector, eine Signal-Engine, ein Order-Manager, ein
State-Reporter. In Kubernetes bilde ich das als Deployment pro
stateless-Komponente und ein StatefulSet für den Order-Manager ab, der
Idempotenz braucht.
# k8s/strategy-momentum-v3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: momentum-v3-signal
namespace: trading-prod
labels:
strategy: momentum-v3
role: signal-engine
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
strategy: momentum-v3
role: signal-engine
template:
metadata:
labels:
strategy: momentum-v3
role: signal-engine
spec:
serviceAccountName: momentum-v3
containers:
- name: signal
image: ghcr.io/mg-quant/momentum-v3:1.4.2
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "1000m"
memory: "2Gi"
env:
- name: BROKER
value: "ibkr"
- name: STRATEGY_ID
value: "momentum-v3"
- name: LOG_LEVEL
value: "INFO"
envFrom:
- secretRef:
name: momentum-v3-secrets
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /readyz
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
ports:
- containerPort: 8080
name: http
- containerPort: 9090
name: metrics
Drei Details, die ich bei Reviews oft korrigieren muss. Erstens strategy: Recreate
statt RollingUpdate — bei Trading-Bots wollen Sie nie zwei Instanzen gleichzeitig haben,
sonst riskieren Sie doppelte Orders. Zweitens explizite Resource-Limits — ohne Limits
kann ein Memory-Leak in einer Strategie den ganzen Node lahmlegen. Drittens getrennte
Liveness- und Readiness-Probes: Liveness terminiert den Pod bei einem Hänger, Readiness
entfernt ihn nur aus dem Service.
StatefulSets für Order-Manager.
Ein Order-Manager hat eine besondere Anforderung: er muss zustandsbehaftet laufen, weil er aktive Orders mit dem Broker reconciled. Wenn der Pod stirbt und neu startet, muss er erkennen, welche Orders bereits unterwegs sind und welche neu rausmüssen.
# k8s/order-manager-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: order-manager
namespace: trading-prod
spec:
serviceName: order-manager
replicas: 1
podManagementPolicy: OrderedReady
selector:
matchLabels:
app: order-manager
template:
metadata:
labels:
app: order-manager
spec:
terminationGracePeriodSeconds: 60
containers:
- name: manager
image: ghcr.io/mg-quant/order-manager:2.1.0
resources:
requests:
cpu: "1000m"
memory: "2Gi"
limits:
cpu: "2000m"
memory: "4Gi"
volumeMounts:
- name: state
mountPath: /var/lib/order-state
lifecycle:
preStop:
exec:
command: ["/app/graceful-shutdown.sh"]
volumeClaimTemplates:
- metadata:
name: state
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: ssd-encrypted
resources:
requests:
storage: 10Gi
Die terminationGracePeriodSeconds: 60 und das preStop-Hook
sind kritisch — bei einem Pod-Restart oder Node-Drain bekommt der Order-Manager 60
Sekunden, um offene Operationen sauber abzuschließen, statt mit halb gesendeten Orders
zu sterben.
Secrets, RBAC und Network-Policies.
Trading-Workloads enthalten extrem sensitive Daten — API-Keys mit Trade-Berechtigung, Account-Stände, Strategie-Logik. Der Cluster muss entsprechend hart konfiguriert sein. Drei Pflichten:
- Secrets nicht im Klartext im Repo: nutzen Sie External Secrets Operator mit AWS Secrets Manager oder GCP Secret Manager als Backend. Im Repo liegt nur eine Referenz auf den Secret, nicht der Wert.
- RBAC pro Strategie: jeder Strategie-ServiceAccount darf nur seine eigenen Secrets und ConfigMaps lesen. Keine Cluster-Admin-Rechte für Pods, niemals.
- NetworkPolicies: per Default ist im K8s-Cluster jeder Pod mit jedem anderen reachable. Eine Default-Deny-Policy plus explizite Allow-Regeln für Broker-Endpoints, Datenbanken und Monitoring schließt eine ganze Klasse von Lateral-Movement-Angriffen.
Observability: Prometheus, Loki, Tempo.
Ohne ordentliches Monitoring ist Kubernetes ein Blackbox-Cluster. Für Trading-Bots installiere ich standardmäßig den kube-prometheus-stack via Helm, dazu Loki für Logs und Grafana Tempo für Traces. Jede Strategie exponiert eigene Metriken auf Port 9090: P&L, offene Positionen, Order-Latenz, Anzahl-Errors, Heartbeat.
Die wichtigste Metrik ist der Heartbeat. Jede Strategie pingt alle 30 Sekunden eine
Metrik strategy_last_heartbeat_timestamp. Ein Alert feuert, wenn dieser
Timestamp älter als 90 Sekunden ist. Das fängt nicht nur Crashes ab, sondern auch
Deadlocks, hängende API-Calls und Netzwerk-Issues — Dinge, die ein klassischer
Liveness-Probe nicht zwingend bemerkt.
Backtest-Workloads als Jobs.
Backtests sind ein Paradebeispiel für Workloads, die Kubernetes elegant löst: viele kurze Tasks, parallelisierbar, mit definiertem Ende. Statt einer manuell gestarteten EC2-Instanz nutze ich Kubernetes Jobs mit Parallelism, getriggert per Argo Workflows oder einem einfachen CronJob.
# k8s/backtest-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: backtest-momentum-v3-2025-w20
namespace: backtest
spec:
parallelism: 8
completions: 50
backoffLimit: 2
ttlSecondsAfterFinished: 86400
template:
spec:
restartPolicy: OnFailure
containers:
- name: backtest
image: ghcr.io/mg-quant/momentum-v3-backtest:1.4.2
resources:
requests:
cpu: "2000m"
memory: "4Gi"
env:
- name: SYMBOLS_SHARD
valueFrom:
fieldRef:
fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']
50 Backtest-Shards laufen mit 8er-Parallelität, fertige Pods werden nach einem Tag aufgeräumt. Die Resultate landen in BigQuery oder S3, der Cluster kümmert sich um Retry und Scheduling. Das ist die Art von Workload, für die Kubernetes wirklich glänzt.
Was Sie nicht tun sollten.
- HPA für Trading-Pods: Auto-Scaling auf CPU oder Memory ist für Strategie-Pods falsch. Eine Strategie ist nicht ein Web-Service — Sie wollen genau eine Instanz, nicht drei.
- Cluster-weite ClusterRoles: bequem, aber ein Sicherheitsrisiko. Jeder Pod, der über einen kompromittierten Container ausbricht, hat dann das ganze Cluster im Zugriff.
- Spot-Instanzen für Live-Strategien: für Backtests okay, für Live fatal. Eine Strategie, die mitten in einem Trade evicted wird, ist ein Risiko, das Sie nicht für 30 % Kostenersparnis eingehen sollten.
Sie überlegen, Ihren Trading-Stack auf Kubernetes zu migrieren oder ein bestehendes Setup zu härten? Erstgespräch buchen — wir gehen Architektur, Deployment-Pipeline und Security gemeinsam an.