- Authors

- Name
- Phillip Pham
- @ddppham
MLOps auf Kubernetes: ML-Pipelines fuer den Produktionsbetrieb
TL;DR
- MLOps auf Kubernetes loest das zentrale Problem: ML-Modelle kommen nicht in Produktion, weil Infrastruktur, Reproducibility und Monitoring fehlen.
- Kubeflow orchestriert ML-Workflows als Kubernetes-native Pipelines. MLflow trackt Experimente und verwaltet die Model Registry.
- GPU-Scheduling, Resource Quotas und Namespace-Isolation machen Kubernetes zur natuerlichen Plattform fuer Multi-Team ML-Workloads.
- Model Serving mit KServe oder Seldon skaliert Inference-Endpoints automatisch basierend auf Traffic.
- Data Drift Detection und Model Performance Monitoring sind keine Nice-to-haves -- ohne sie degradiert jedes Modell unbemerkt.
Warum Kubernetes fuer ML-Workloads
Die meisten ML-Teams starten mit Jupyter Notebooks auf einem einzelnen Server. Das funktioniert fuer Experimente, aber nicht fuer Produktion. Wenn du ein Modell trainieren, versionieren, deployen und ueberwachen willst, brauchst du Infrastruktur, die das alles verbindet.
Kubernetes loest dabei mehrere Probleme gleichzeitig:
Resource Scheduling: Training-Jobs brauchen GPUs fuer Stunden, dann nichts mehr. Kubernetes alloziert GPUs on-demand und gibt sie danach frei. Ohne Kubernetes blockiert ein Training-Job eine teure GPU-Maschine dauerhaft.
Reproducibility: Jeder Pipeline-Schritt laeuft in einem Container mit fixem Image-Tag. Das garantiert, dass ein Training-Run von vor 3 Monaten identisch reproduzierbar ist -- gleiche Abhaengigkeiten, gleiche Python-Version, gleiche CUDA-Version.
Isolation: Verschiedene Teams arbeiten in getrennten Namespaces mit eigenen Resource Quotas. Team A kann nicht versehentlich die GPU-Ressourcen aufbrauchen, die Team B fuer einen Deadline-kritischen Training-Run braucht.
Scaling: Inference-Endpoints skalieren automatisch mit dem Traffic. Ein Modell, das nachts kaum Requests bekommt, verbraucht nachts kaum Ressourcen.
Die MLOps-Architektur auf Kubernetes
Ein produktionsreifer MLOps-Stack auf Kubernetes besteht aus vier Schichten:
| Schicht | Komponente | Aufgabe |
|---|---|---|
| Pipeline Orchestration | Kubeflow Pipelines / Argo Workflows | ML-Workflows als DAGs definieren und ausfuehren |
| Experiment Tracking | MLflow | Metriken, Parameter und Artifacts aller Training-Runs speichern |
| Model Serving | KServe / Seldon Core | Modelle als skalierbare REST/gRPC Endpoints bereitstellen |
| Monitoring | Prometheus + Grafana + Evidently | Modell-Performance und Data Drift ueberwachen |
Dazu kommen Infrastruktur-Komponenten: MinIO oder S3 fuer Artifact Storage, PostgreSQL fuer Metadaten, und ein GPU Operator fuer NVIDIA GPU Support.
Kubeflow Pipeline: Vom Training zum Deployment
Eine Kubeflow Pipeline definiert ML-Workflows als gerichtete azyklische Graphen (DAGs). Jeder Schritt ist ein Container. Die Abhaengigkeiten zwischen den Schritten werden deklarativ definiert.
Hier ein realistisches Beispiel fuer eine Pipeline, die Daten laedt, ein Modell trainiert, evaluiert und bei ausreichender Qualitaet deployt:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: ml-training-pipeline
namespace: mlops
spec:
entrypoint: ml-pipeline
templates:
- name: ml-pipeline
dag:
tasks:
- name: fetch-data
template: fetch-data
- name: preprocess
template: preprocess
dependencies: [fetch-data]
arguments:
artifacts:
- name: raw-data
from: "{{tasks.fetch-data.outputs.artifacts.dataset}}"
- name: train-model
template: train
dependencies: [preprocess]
arguments:
artifacts:
- name: processed-data
from: "{{tasks.preprocess.outputs.artifacts.processed}}"
- name: evaluate
template: evaluate
dependencies: [train-model]
arguments:
artifacts:
- name: model
from: "{{tasks.train-model.outputs.artifacts.model}}"
- name: fetch-data
container:
image: registry.example.com/ml/data-loader:1.2.0
command: [python, fetch_data.py]
args: ["--output", "/data/raw"]
outputs:
artifacts:
- name: dataset
path: /data/raw
- name: preprocess
container:
image: registry.example.com/ml/preprocessor:1.1.0
command: [python, preprocess.py]
resources:
requests:
memory: "4Gi"
cpu: "2"
inputs:
artifacts:
- name: raw-data
path: /data/raw
outputs:
artifacts:
- name: processed
path: /data/processed
- name: train
container:
image: registry.example.com/ml/trainer:2.0.0
command: [python, train.py]
args: ["--epochs", "50", "--lr", "0.001"]
resources:
requests:
memory: "8Gi"
cpu: "4"
nvidia.com/gpu: "1"
limits:
nvidia.com/gpu: "1"
env:
- name: MLFLOW_TRACKING_URI
value: "http://mlflow.mlops.svc:5000"
inputs:
artifacts:
- name: processed-data
path: /data/processed
outputs:
artifacts:
- name: model
path: /models/output
- name: evaluate
container:
image: registry.example.com/ml/evaluator:1.0.0
command: [python, evaluate.py]
args: ["--threshold", "0.85"]
inputs:
artifacts:
- name: model
path: /models/input
Wichtige Details: Der train-Step fordert eine GPU an (nvidia.com/gpu: 1). Kubernetes Scheduler platziert diesen Pod nur auf einem Node, der eine GPU hat. Nach dem Training wird die GPU freigegeben.
MLflow fuer Experiment Tracking und Model Registry
MLflow laeuft als Deployment im Cluster und speichert Metriken, Parameter und Artifacts jedes Training-Runs.
Das MLflow-Deployment selbst:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mlflow
namespace: mlops
spec:
replicas: 1
selector:
matchLabels:
app: mlflow
template:
metadata:
labels:
app: mlflow
spec:
containers:
- name: mlflow
image: ghcr.io/mlflow/mlflow:2.11.0
command:
- mlflow
- server
---backend-store-uri=postgresql://mlflow:$(DB_PASSWORD)@postgres.mlops.svc:5432/mlflow
---default-artifact-root=s3://mlflow-artifacts/
---host=0.0.0.0
---port=5000
ports:
- containerPort: 5000
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: mlflow-db-credentials
key: password
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: minio-credentials
key: access-key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: minio-credentials
key: secret-key
- name: MLFLOW_S3_ENDPOINT_URL
value: "http://minio.mlops.svc:9000"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: mlflow
namespace: mlops
spec:
selector:
app: mlflow
ports:
- port: 5000
targetPort: 5000
Im Training-Code loggt jeder Run seine Metriken:
# Beispiel: Training-Run starten und Ergebnisse in MLflow loggen
export MLFLOW_TRACKING_URI=http://mlflow.mlops.svc:5000
python train.py \
--experiment-name "fraud-detection-v3" \
--learning-rate 0.001 \
--epochs 50 \
--batch-size 256
Die Model Registry in MLflow verwaltet Modell-Versionen mit Staging-Stufen (Staging, Production, Archived). Das ist der zentrale Ort, an dem ML Engineers und Data Scientists Modelle fuer die Produktion freigeben.
Fuer die GPU-Infrastruktur hinter dem Training siehe Kubernetes GPU Cluster und GPU Monitoring.
Resource Management fuer ML-Teams
ML-Workloads sind ressourcenintensiv und unvorhersehbar. Ohne Quotas kann ein einzelner Training-Job den gesamten Cluster blockieren. ResourceQuotas und LimitRanges verhindern das:
apiVersion: v1
kind: ResourceQuota
metadata:
name: ml-team-alpha-quota
namespace: ml-team-alpha
spec:
hard:
requests.cpu: "32"
requests.memory: "64Gi"
limits.cpu: "64"
limits.memory: "128Gi"
requests.nvidia.com/gpu: "4"
pods: "50"
persistentvolumeclaims: "20"
---
apiVersion: v1
kind: LimitRange
metadata:
name: ml-default-limits
namespace: ml-team-alpha
spec:
limits:
- default:
cpu: "2"
memory: "4Gi"
defaultRequest:
cpu: "500m"
memory: "1Gi"
type: Container
- default:
nvidia.com/gpu: "1"
type: Container
Das Team ml-team-alpha kann maximal 4 GPUs gleichzeitig nutzen und 64Gi RAM anfordern. Wenn sie mehr brauchen, muessen sie bestehende Jobs beenden oder das Quota anpassen lassen.
Fuer eine detaillierte Betrachtung von Resource Management siehe Kubernetes Resource Management.
Model Serving: Vom Artifact zum Endpoint
Ein trainiertes Modell, das in MLflow liegt, muss als skalierbarer Endpoint verfuegbar sein. KServe (frueher KFServing) ist der Kubernetes-native Standard dafuer:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: fraud-detector
namespace: ml-serving
spec:
predictor:
model:
modelFormat:
name: mlflow
storageUri: "s3://mlflow-artifacts/models/fraud-detector/v3"
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
minReplicas: 1
maxReplicas: 10
scaleTarget: 5
scaleMetric: concurrency
KServe skaliert den Inference-Endpoint automatisch zwischen 1 und 10 Replicas basierend auf der Anzahl gleichzeitiger Requests. Bei Null-Traffic kann es auf 0 Replicas skalieren (Knative Scale-to-Zero), um Ressourcen zu sparen.
Model Monitoring: Data Drift und Performance
Ein deployed Modell ist kein abgeschlossenes Projekt. Die Eingabedaten aendern sich ueber die Zeit (Data Drift), und die Modell-Performance degradiert. Ohne Monitoring merkst du das erst, wenn Nutzer sich beschweren.
Die wichtigsten Metriken fuer Model Monitoring:
| Metrik | Beschreibung | Alert-Schwelle |
|---|---|---|
| Prediction Latency (p95) | Antwortzeit des Inference-Endpoints | > 200ms |
| Error Rate | Anteil fehlgeschlagener Predictions | > 1% |
| Data Drift Score | Statistische Abweichung der Eingabedaten vom Trainingsdatensatz | KS-Test p-value < 0.05 |
| Prediction Distribution | Verteilung der Modell-Outputs | Signifikante Verschiebung |
| Feature Coverage | Anteil der Features mit fehlenden Werten | > 5% |
Fuer die Umsetzung: Prometheus sammelt die Metriken, Grafana visualisiert sie, und Alertmanager benachrichtigt bei Schwellenwert-Ueberschreitungen. Details zum Monitoring-Stack unter Kubernetes Observability Stack.
CI/CD fuer ML-Pipelines
ML-Pipelines brauchen eine eigene CI/CD-Strategie. Im Gegensatz zu regulaerer Software gibt es zwei Trigger: Code-Aenderungen und Daten-Aenderungen.
Der typische Flow:
- Data Scientist pusht Code-Aenderung (neues Feature Engineering, anderes Modell).
- CI-Pipeline laeuft: Linting, Unit Tests, Integration Tests.
- Pipeline triggert Training-Run auf dem Kubernetes-Cluster.
- MLflow loggt Metriken des Training-Runs.
- Bei ausreichender Modell-Qualitaet: Modell wird in MLflow Registry als "Staging" registriert.
- Manueller Approval-Step: ML Engineer prueft Metriken und promoted zu "Production".
- KServe InferenceService wird automatisch aktualisiert.
Daten-getriggerte Retraining-Pipelines funktionieren aehnlich, werden aber durch einen Scheduler oder ein Event (z.B. neue Daten im Data Lake) ausgeloest statt durch einen Git-Push.
Fuer die GitOps-Integration der ML-Pipelines siehe ArgoCD Tutorial.
DSGVO-Anforderungen an ML-Systeme
ML-Systeme, die personenbezogene Daten verarbeiten, muessen DSGVO-konform sein. Kubernetes bietet die Infrastruktur dafuer, aber du musst sie korrekt nutzen:
- Data Residency: Trainings- und Inference-Daten duerfen den Cluster nicht verlassen. MinIO als In-Cluster Object Storage statt externe Cloud-Services.
- Audit Trail: MLflow-Experiment-Logs dokumentieren, welche Daten fuer welches Training verwendet wurden. Das ist relevant fuer DSGVO Art. 22 (automatisierte Entscheidungsfindung).
- Right to Erasure: Wenn ein Nutzer Loeschung fordert, muessen seine Daten aus Trainingsdaten und ggf. dem Modell entfernt werden. Das erfordert Data Lineage Tracking.
- Namespace Isolation: RBAC und NetworkPolicies trennen ML-Workloads, die personenbezogene Daten verarbeiten, von anderen Workloads im Cluster.
Fuer eine umfassende Betrachtung von Compliance in Kubernetes siehe DSGVO und Kubernetes Compliance.
Haeufige Fragen
Brauche ich Kubeflow, oder reichen Argo Workflows?
Kubeflow ist ein umfangreicheres Framework, das neben Pipelines auch Notebook-Server, Katib (Hyperparameter-Tuning) und KServe umfasst. Wenn du nur Pipeline-Orchestrierung brauchst, sind Argo Workflows leichtgewichtiger und flexibler. Kubeflow lohnt sich, wenn du den gesamten ML-Lifecycle auf einer Plattform abbilden willst.
Wie viele GPUs brauche ich fuer den Anfang?
Starte mit 1-2 GPUs fuer ein Team. Die meisten ML-Modelle (nicht LLMs) lassen sich auf einer einzelnen NVIDIA A10 oder T4 in akzeptabler Zeit trainieren. Kubernetes erlaubt dir, spaeter problemlos zu skalieren, ohne die Architektur zu aendern.
Kann ich MLflow durch Weights and Biases ersetzen?
Ja. W&B ist ein Cloud-hosted Experiment Tracker mit besserer UI und Collaboration-Features. Der Trade-off: Daten verlassen deinen Cluster und gehen an einen externen Service. Fuer DSGVO-sensible Workloads ist self-hosted MLflow oft die sicherere Wahl.
Was ist der Unterschied zwischen KServe und Seldon Core?
Beide ermöglichen Model Serving auf Kubernetes. KServe ist CNCF-nah und basiert auf Knative. Seldon Core hat eine eigene Architektur und bietet erweiterte Features wie A/B Testing und Explainability. KServe ist der neuere Standard und wird breiter adopted.
MLOps auf Kubernetes ist kein Wochenend-Projekt, aber die Investition lohnt sich. Wenn du Unterstuetzung beim Aufbau deiner ML-Plattform brauchst -- vom initialen Cluster-Setup bis zur Kubeflow-Integration -- melde dich unter /kontakt.
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
Kubeflow auf Kubernetes: MLOps-Pipelines einrichten
Kubeflow auf Kubernetes deckt den gesamten ML-Lifecycle ab: von Jupyter Notebooks über Pipelines bis Model Serving mit KServe und Katib.
Kubernetes als Machine Learning Plattform einrichten
Kubernetes als ML-Plattform aufbauen: GPU-Cluster mit NVIDIA Device Plugin, MLOps-Pipelines mit Kubeflow und Model Serving mit TensorFlow und PyTorch.
KI auf Kubernetes im Healthcare: ML-Pipelines produktiv betreiben
Wie ein deutsches Healthcare-Unternehmen 50+ ML-Modelle DSGVO-konform auf Kubernetes betreibt und die Diagnose-Genauigkeit um 35% verbesserte.
KI-Qualitätskontrolle auf Kubernetes mit YOLO
KI-gestützte Qualitätskontrolle auf Kubernetes: Kamera-zu-Inference-Pipeline mit YOLO und Triton Inference Server für automatisierte Defekterkennung.
YOLO Inference auf Kubernetes: GPU-Scheduling und Autoscaling
YOLO-Modelle als skalierbare Inference-Services auf Kubernetes deployen: NVIDIA Device Plugin, GPU-Scheduling, HPA mit Custom Metrics und Triton Serving.