The machine-learning platform for Kubernetes — turn ad-hoc notebooks into reproducible, scalable ML pipelines with experiment tracking, hyperparameter tuning, and model serving. You'll understand the components, build a pipeline, run distributed training and tuning, and serve a model. Concepts-and-hands-on. Work top to bottom, or jump to a part.
The journey:
| You need | Why |
|---|---|
| A Kubernetes cluster (real resources) | Kubeflow is heavy — many controllers, needs CPU/RAM/GPU |
kubectl + basic ML familiarity |
You'll deploy CRDs and reason about training/serving |
| Python | Pipelines and components are defined in Python (KFP SDK) |
Kubeflow is a platform, not a single tool — expect a bigger footprint than most tutorials here. Confirm your cluster: kubectl get nodes.
Machine learning in notebooks doesn't reproduce, doesn't scale, and doesn't ship: "works on my laptop" data science, manual retraining, no experiment history, and a painful gap from a trained model to a running endpoint.
Kubeflow makes the ML lifecycle Kubernetes-native and reproducible: every step (data prep, training, tuning, serving) runs as containers on the cluster, defined as code, tracked, and scalable — using the same primitives (pods, CRDs, autoscaling) you already know. It's the MLOps toolkit for teams that outgrew notebooks and want the ML workflow to be as engineered as the rest of their infrastructure.
Kubeflow is a suite; you adopt the pieces you need:
| Component | Does |
|---|---|
| Notebooks | Managed Jupyter servers on the cluster (with GPUs) |
| Pipelines (KFP) | Reproducible, containerized ML workflows (DAGs) |
| Katib | Automated hyperparameter tuning / AutoML |
| Training Operators | Distributed training (PyTorch, TensorFlow, XGBoost jobs) |
| KServe | Scalable model serving (often a separate project now) |
| Central Dashboard | The UI tying it together, with multi-tenant profiles |
The through-line: each turns an ML task into a Kubernetes resource. You'll rarely use all of them at once — most teams start with Notebooks + Pipelines and add Katib/serving as they mature.
Kubeflow Notebooks give each user a managed Jupyter server as a pod — with the CPU/GPU/memory they request, shared storage, and access to cluster services. It's where experimentation starts, but with cluster resources instead of a laptop.
The key discipline: a notebook is for exploration, not production. As soon as a step works, factor it into a pipeline component (Part 4) so it's reproducible, versioned, and runnable without a human clicking "Run All." Notebooks that quietly become production jobs are the anti-pattern Kubeflow exists to fix.
Kubeflow Pipelines (KFP) is the core. You define an ML workflow as a DAG of containerized steps in Python; each step's inputs/outputs are tracked, so runs are reproducible and comparable.
from kfp import dsl
@dsl.component(base_image="python:3.11")
def preprocess(data_path: str) -> str:
# ... read, clean, write features ...
return "/data/features.parquet"
@dsl.component(base_image="python:3.11")
def train(features: str) -> str:
# ... train, save model ...
return "/models/model.pkl"
@dsl.pipeline(name="train-pipeline")
def pipeline(data_path: str = "/data/raw.csv"):
feats = preprocess(data_path=data_path)
train(features=feats.output) # output wiring defines the DAG edge
Each @dsl.component becomes a container that runs as a pod; wiring one step's .output into the next defines the dependency graph. The KFP UI then shows every run, its parameters, artifacts, and metrics — so "which data + hyperparameters produced this model?" is always answerable. That lineage is the whole point.
When a model won't train on one machine, the Training Operators run distributed jobs as CRDs — e.g. a PyTorchJob coordinates a master and workers:
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata: { name: train-resnet }
spec:
pytorchReplicaSpecs:
Master:
replicas: 1
template: { spec: { containers: [{ name: pytorch, image: my-train:1.0, resources: { limits: { nvidia.com/gpu: 1 } } }] } }
Worker:
replicas: 3
template: { spec: { containers: [{ name: pytorch, image: my-train:1.0, resources: { limits: { nvidia.com/gpu: 1 } } }] } }
The operator sets up the master/worker topology, environment variables, and networking that the distributed framework expects — you just declare replicas and GPUs. The same pattern exists for TensorFlow (TFJob), XGBoost, and MPI. It turns "configure a distributed training cluster" into a YAML manifest.
Katib automates the search for good hyperparameters (learning rate, layers, batch size) — running many trials and steering toward the best result:
apiVersion: kubeflow.org/v1beta1
kind: Experiment
metadata: { name: tune-lr }
spec:
objective: { type: maximize, objectiveMetricName: accuracy }
algorithm: { algorithmName: bayesianoptimization }
parameters:
- name: lr
parameterType: double
feasibleSpace: { min: "0.001", max: "0.1" }
trialTemplate: { ... } # how to run one trial
Katib launches trials (each a training run) with different parameter values, reads back the objective metric, and uses a search algorithm (grid, random, Bayesian, Hyperband) to explore efficiently — instead of hand-tuning one run at a time. It's AutoML/HPO as a Kubernetes CRD.
Training produces a model; KServe serves it as a scalable, production endpoint with one manifest:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata: { name: sklearn-iris }
spec:
predictor:
model:
modelFormat: { name: sklearn }
storageUri: "s3://models/iris/"
KServe handles the hard serving parts: autoscaling (including scale-to-zero), canary rollouts between model versions, batching, and a standard inference protocol — across frameworks (sklearn, PyTorch, TensorFlow, ONNX, LLMs). Point it at a stored model and you get an autoscaling HTTP/gRPC endpoint, closing the gap from "trained" to "in production."
Kubeflow is the compute/orchestration layer of MLOps, not the whole thing. A mature stack pairs it with:
The goal is the ML equivalent of a software delivery pipeline: data → automated training/tuning → tracked model → gated deploy → monitored serving → retrain. Kubeflow provides the Kubernetes-native engine for the training-through-serving middle.
PyTorchJob with 1 master + 2 workers and watch the pods coordinate.Experiment over one hyperparameter and compare trial results.InferenceService and curl the endpoint; scale it to zero and back.Self-check:
You now have the map: notebooks → pipelines → distributed training → tuning → serving → MLOps loop. That's ML engineered on Kubernetes.