How to Move a Databricks or SageMaker Training Pipeline to Kubernetes (Without Losing a Month)
A practical 7-step path for moving Databricks jobs or SageMaker training pipelines onto Kubernetes when you need direct GPU access, spot instances, and a cloud bill in your own name. Includes a per-GPU-hour cost table, a component mapping table, a post-migration options table, a cutover validation table, and an honest list of when to stay put.
Moving a Databricks or SageMaker training pipeline to Kubernetes means replacing five layers: job orchestration (Argo Workflows, Kubeflow Pipelines, Flyte or KubeRay), distributed training (Kubeflow Trainer with Kueue or Volcano for gang scheduling), the GPU runtime (NVIDIA GPU Operator plus labeled, tainted node pools), data and artifacts (S3, GCS, Azure Blob or Scaleway Object Storage) and experiment tracking (MLflow or Weights & Biases).
The cost gap is built into the pricing model. Databricks bills DBUs on top of the cloud instance, and SageMaker prices ml.* training instances 15-40% above the same EC2 hardware in us-east-1. On Kubernetes you pay cloud list price, and you keep spot GPUs, GPU sharing, scale-to-zero, Savings Plans and committed-use discounts in your own account.
Direct GPU access is what makes the move stick: you pin the driver, CUDA and container toolkit together, slice an A100 or H100 into up to seven MIG instances, time-slice GPUs for notebooks and tune NCCL over EFA or InfiniBand for multi-node runs.
The safe sequence has seven steps: containerize, externalize data paths, provision GPU node pools, prove one GPU job, move orchestration, move tracking, then parallel-run a full retraining cycle. A big-bang DAG rewrite turns a three-week migration into a quarter.
Do not migrate below the break-even. Under a few hundred GPU-hours a month, with no platform engineer, or with deep Unity Catalog or SageMaker Feature Store coupling, SageMaker Managed Spot Training or Databricks Jobs Compute is still the cheaper total answer. Above it, Qovery runs the cluster layer inside your own AWS, GCP, Azure, Scaleway or existing Kubernetes cluster so the ML team ships training jobs without a dedicated DevOps engineer.
One SageMaker training hour on an ml.g5.xlarge costs $1.408 in us-east-1. The same g5.xlarge, same NVIDIA A10G, costs $1.006 on raw EC2 (both checked November 2026 from the AWS SageMaker price list and EC2 on-demand pricing). That is a 40% premium for identical silicon.
On Azure Databricks, a Jobs cluster on one NC24ads A100 v4 costs $6.67 per hour in East US: $3.67 for the VM plus $3.00 of DBUs (Azure Databricks pricing, checked November 2026). The DBUs nearly double the GPU bill.
Those two numbers are why ML teams call us. This guide is the migration plan we walk them through, including the cases where we tell them to stay put.
Why do teams move training pipelines off Databricks or SageMaker?
Teams move training off Databricks or SageMaker for three reasons: a per-unit markup on GPU compute (DBUs on top of the instance on Databricks, an ml.* premium of 15-40% on SageMaker), no control over the driver and CUDA stack, and proprietary job formats that make every future workload harder to move. Cost usually triggers the project. GPU control is what keeps teams from going back.
Databricks pricing in one sentence: classic Jobs Compute is billed in DBUs "plus underlying compute costs billed by cloud provider" (Databricks Lakeflow Jobs pricing), so every GPU hour carries two line items. Premium Jobs Compute is $0.30/DBU on Azure East US (Azure Retail Prices API, checked November 2026); legacy Standard tier is $0.10/DBU on AWS and GCP.
SageMaker pricing in one sentence: training runs on ml.* instances billed at a separate, higher rate than the matching EC2 instance. In us-east-1 that is +40% on ml.g5.xlarge and +15% on both ml.p4d.24xlarge and ml.p5.48xlarge.
GPU control: pinning driver and CUDA versions, MIG partitioning, time-slicing, NCCL tuning, interconnect choice for multi-node runs, and running a PyTorch build the managed image does not ship yet.
Lock-in comes in two shapes. Databricks: notebooks, Workflows, DBFS paths, Delta Lake, Unity Catalog and TorchDistributor. SageMaker: Estimators, the Pipelines SDK, input channels, /opt/ml entrypoint conventions and the Model Registry.
Quota friction: SageMaker tracks training capacity as its own per-instance-type quotas in Service Quotas, separate from your EC2 quotas. Teams with large runs end up negotiating capacity twice.
When not to migrate: fewer than a few hundred GPU-hours a month, no one on the team who can own a cluster, or a pipeline wired deeply into Unity Catalog or SageMaker Feature Store. The break-even is utilization and headcount.
The honest trade: you swap a vendor markup for operating responsibility, and the swap only pays above a utilization threshold.
What exactly do you have to replace when you move training to Kubernetes?
A managed ML platform bundles five layers (job orchestration, distributed training, the GPU runtime, data and artifacts, experiment tracking), while Kubernetes only schedules containers. Map each layer to a named replacement before you write a line of YAML, because the layer you forget is the one that blocks the cutover.
Job orchestration: SageMaker Pipelines and Databricks Workflows map to Argo Workflows (CNCF graduated, v4.1), Kubeflow Pipelines (Kubeflow is CNCF graduated since July 2026), Flyte (Linux Foundation, backed by Union.ai), Metaflow (Netflix origin, backed by Outerbounds) or KubeRay (Ray project, backed by Anyscale).
Distributed training: the Estimator distribution config or TorchDistributor maps to Kubeflow Trainer v2.4 and its TrainJob API. It replaced the Training Operator's PyTorchJob and TFJob, which Kueue now lists as deprecated. Trainer v2 still calls itself alpha, so pin the version.
Gang scheduling and queues: Kueue (v0.20, a kubernetes-sigs project from the Batch Working Group) or Volcano (CNCF incubating, v1.16).
GPU runtime: the managed AMI or Databricks ML Runtime maps to the NVIDIA GPU Operator (driver, device plugin, container toolkit, DCGM) plus node labels, taints and a MIG or time-slicing profile.
Data and artifacts: DBFS paths, Delta tables, SageMaker default buckets and input channels map to plain object storage URIs on S3, GCS, Azure Blob or Scaleway Object Storage, plus Feast if you used a feature store.
Tracking and registry: self-hosted or managed MLflow, or Weights & Biases, replace the SageMaker Model Registry or Databricks-hosted MLflow.
Default S3 bucket, input channels under /opt/ml/input
S3, GCS, Azure Blob or Scaleway Object Storage URIs; Feast for features
ML engineers
2-5 days
Experiment tracking and registry
Databricks-hosted MLflow, Unity Catalog models
SageMaker Experiments, Model Registry
MLflow (LF AI & Data) or Weights & Biases
ML engineers or platform owner
1-3 days
Identity and secrets
Instance profiles, Unity Catalog credentials
SageMaker execution role
IRSA / EKS Pod Identity, GKE Workload Identity Federation, AKS Entra Workload ID
Whoever operates the cluster
1-2 days
The day ranges are our field estimates for one pipeline and one ML engineer, not a benchmark.
Is GPU training on Kubernetes actually cheaper than SageMaker or Databricks?
Yes, for sustained GPU use: on Kubernetes you pay the raw cloud instance price, while SageMaker charges 15-40% more for the same EC2 hardware in us-east-1 and Databricks adds DBUs that range from +4% on an 8x H100 VM to +82% on a single-A100 VM on Azure. The bigger saving comes from three levers you control on Kubernetes: spot GPUs, GPU sharing and scale-to-zero node pools, all billed to your own account where Savings Plans and committed-use discounts apply.
Spot columns are point-in-time snapshots and move daily. The SageMaker and Azure figures come from each vendor's machine-readable price list.
Two honest readings of that table. SageMaker's premium is a flat tax of 15% or more on every training hour. The Databricks markup depends on the DBU rating of the VM: large 8-GPU nodes carry a small DBU uplift, while small single-GPU nodes can nearly double. Databricks classic compute also runs the VM in your own cloud account, so the instance line already benefits from your discounts. The DBU line does not.
Lever 1, spot GPUs with checkpointing. AWS advertises up to 90% off on Spot Instances, Google up to 91% on Spot VMs including GPUs, and Azure up to 90% on Spot VMs. Real discounts on GPU families are smaller and volatile: our snapshot shows 17% off on p4d and 82% off on the Azure H100 VM.
Lever 2, GPU sharing. MIG gives hard isolation on A100 and H100; time-slicing covers notebooks and dev jobs. Large distributed runs should get whole GPUs.
Lever 3, scale-to-zero and bin-packing.Karpenter deletes empty nodes and consolidates underutilized ones on AWS; Cluster Autoscaler or the managed equivalent does the same on GKE, AKS and Scaleway Kapsule.
The BYOC point:AWS Savings Plans go up to 72% off on-demand, and Google resource-based committed-use discounts cover Cloud GPUs. Those commitments apply to EC2 and Compute Engine spend in your account. SageMaker needs its own separate SageMaker Savings Plan, and DBUs need a Databricks commit.
Be fair to the managed option.SageMaker Managed Spot Training "can optimize the cost of training models up to 90%" with checkpointing to S3 handled for you. If your runs are bursty, single-node and checkpoint well, flip EnableManagedSpotTraining=True and skip the migration. Note that it never falls back to on-demand: if spot capacity is gone, the job waits until MaxWaitTimeInSeconds and stops.
The counterweight: an idle GPU node is the fastest way to erase the saving. One idle p5.48xlarge at $55.04/h costs $1,321 a day and about $40,180 a month (730 hours). One idle Azure ND96isr H100 v5 costs about $71,770 a month. Add the cluster control plane, monitoring, and the engineer time to run all of it.
Rule of thumb: the math flips when GPUs are busy more than about half the month, or when more than one team shares the same node pool.
What does a step-by-step migration plan look like?
Migrate one training step at a time and run it beside the existing pipeline until the metrics match: containerize, externalize data paths, provision GPU node pools, prove exactly one GPU job, move orchestration, move tracking, then parallel-run and cut over. That sequence takes weeks. A big-bang DAG rewrite takes a quarter.
Containerize the training code. Lift it out of notebooks or Estimators into a plain train.py and a Dockerfile on a pinned CUDA base image. It still runs on the old platform (SageMaker accepts custom containers, Databricks accepts container services), which makes it the biggest de-risking step.
Externalize config and data paths. Replace dbfs:/ paths and /opt/ml/input/data/<channel> conventions with environment variables and object storage URIs. Keep a compatibility shim for one cycle.
Provision GPU node pools. Tainted, labeled GPU node groups, the NVIDIA GPU Operator, an autoscaler (Karpenter on AWS, Cluster Autoscaler or the managed equivalent on GKE, AKS and Kapsule), and one spot pool with an on-demand fallback pool.
Run exactly one job. A single TrainJob or Argo step. Validate samples per second, NCCL initialization and the checkpoint write to object storage before touching the DAG.
Move orchestration. Port the DAG to Argo Workflows, Kubeflow Pipelines or Flyte, and make retries and artifact passing explicit.
Move tracking and the registry. Stand up MLflow and dual-log to both systems for the whole parallel run.
Parallel run and cut over. Compare eval metrics, wall-clock and cost per completed run across at least one full retraining cycle, then retire the old pipeline.
Rollback rule: keep the managed pipeline runnable for one full retraining cycle after cutover, and keep old artifacts addressable at their original URIs.
Step
What you build
What breaks if you skip it
Realistic duration, one ML engineer (estimate)
Can it run before cutover?
1. Containerize
train.py + Dockerfile on a pinned CUDA image
Notebook state and Estimator magic leak into the new platform
3-5 days
Yes, on SageMaker or Databricks
2. Externalize paths
Env-based config, object storage URIs, a path shim
Hard-coded dbfs:/ or /opt/ml paths fail on the first Kubernetes run
Jobs land on CPU nodes or wait forever for capacity
3-5 days
Yes, idle until step 4
4. One GPU job
One TrainJob or Argo step writing checkpoints
You debug NCCL and IAM inside a 12-step DAG
2-4 days
Yes, beside the old pipeline
5. Orchestration
Argo, Kubeflow Pipelines or Flyte DAG
Retries and artifact passing stay implicit and break silently
4-7 days
Yes, shadow mode
6. Tracking
MLflow with dual logging
You lose run lineage and cannot compare models
2-3 days
Yes, dual-log
7. Parallel run
Side-by-side retraining cycle, cost and metric report
You cut over on faith
One retraining cycle
This is the cutover gate
These durations are estimates from migrations we have seen, not a benchmark. Add a week if identity and networking belong to another team.
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.
How do you get direct GPU access right on Kubernetes (drivers, sharing, spot, multi-node)?
Direct GPU access on Kubernetes comes down to four decisions: how drivers are managed (NVIDIA GPU Operator or pre-baked node images), how jobs are scheduled (gang scheduling with Kueue or Volcano), how GPUs are shared (MIG or time-slicing), and how interruptions are handled (checkpointing plus an on-demand fallback pool). Get them right and throughput matches the managed platform. Get them wrong and you pay on-demand prices for idle accelerators.
Drivers. Use the GPU Operator (v26.7 at the time of writing) or bake drivers into the node image, but pin driver, CUDA and container toolkit versions together. Roll upgrades to a canary node pool first.
Scheduling. A 16-worker job that gets 12 GPUs and waits for 4 more holds 12 idle GPUs. Kueue's all-or-nothing admission or Volcano's gang scheduling prevents that. Add per-team ClusterQueue quotas and cohorts from day one.
Sharing.NVIDIA's MIG profiles split an H100 80GB into up to seven 1g.10gb instances, or 3x 2g.20gb, 2x 3g.40gb, or one 7g.80gb; the A100 80GB uses the same layout. Time-slicing shares a GPU across more pods but, in NVIDIA's words, offers "no memory or fault-isolation between replicas". Use MIG for small production jobs, time-slicing for notebooks, and neither for multi-GPU training.
Spot. AWS gives a two-minute interruption notice, Azure 30 seconds via scheduled events, and Google lets you set a 120-second notice or none (the default is 0). Checkpoint to object storage every N steps so that a lost node costs minutes, not hours. Karpenter launches a replacement as soon as it sees the warning.
Multi-node. On AWS, EFA supports NCCL with OS bypass on p4d and p5, at no extra cost. On Google Cloud, use GPUDirect networking on A3; on Azure, InfiniBand on ND-series VMs. An NCCL ring falling back to TCP can stretch a large run enough to erase the whole cost saving, so run nccl-tests on every new pool.
Observability.DCGM Exporter feeds Prometheus and Grafana with DCGM_FI_DEV_GPU_UTIL (shipped as DCGM_FI_DEV_GPU_UTIL_RATIO in current default counters) and the more precise DCGM_FI_PROF_GR_ENGINE_ACTIVE. Sustained utilization well under half usually points to a data-loading bottleneck.
The utilization problem is measured. In Microsoft's analysis of its Philly cluster (Jeon et al., USENIX ATC 2019), 8-GPU jobs used GPU cycles 56.9% of the time on average, and 16-GPU jobs only 34.3%. The authors conclude that "GPUs are underutilized in shared clusters." Sharing and bin-packing are how you buy that capacity back.
Who operates the cluster afterwards, and what are the alternatives to Qovery?
Kubernetes fixes GPU access and the vendor markup, but someone still has to upgrade the cluster at 2am, and there are five realistic answers: raw EKS/GKE/AKS with a platform team, a self-managed Kubeflow or Flyte stack, a managed portable runtime such as Anyscale or Union.ai, an internal developer platform such as Qovery inside your own cloud account, or keeping part of the pipeline on SageMaker or Databricks.
The people problem is real. In the CNCF Annual Cloud Native Survey (628 respondents, September 2025), 66% of organizations already host generative AI workloads on Kubernetes, and "lack of training" ranks as the second-biggest challenge at 36%.
Qovery is an internal developer platform that deploys and operates applications inside your own AWS, GCP, Azure or Scaleway account, or on your existing Kubernetes cluster. That is BYOC: the cloud bill, Savings Plans and committed-use discounts stay in your name. What it does: git-push deployments, preview environments per pull request, environment auto-stop for non-production, managed cluster upgrades, per-environment RBAC, and databases backed by managed cloud services.
Be precise about the split. Qovery operates the cluster and the self-service deployment layer; Kubeflow Trainer, Argo Workflows, Ray and MLflow run on top as workloads you control. Qovery is not an MLOps, training-orchestration or experiment-tracking product.
Hybrid is legitimate and common: keep Delta Lake or Unity Catalog as the data layer, move GPU training to Kubernetes, and keep inference wherever it already works.
Option after leaving the managed ML platform
Who operates the cluster
GPU control
Where the cloud bill lands
Time to first training job
DevOps headcount required
Lock-in risk
Raw EKS / GKE / AKS + in-house platform team
Your platform team
Full
Your cloud account
Weeks
High, usually 2+ engineers
Low
Kubeflow or Flyte, self-managed on your cluster
You
Full
Your cloud account
Weeks
Medium to high
Low, open source
Anyscale (Ray) or Union.ai (Flyte), managed
The vendor, on vendor or your cloud
High, within the vendor's runtime
Vendor bill plus cloud bill
Days
Low
Medium, new vendor
Qovery on your own AWS, GCP, Azure, Scaleway or existing cluster
Qovery operates the cluster; you own the ML stack on top
Full, node pools in your account
Your cloud account, plus Qovery subscription
Days
Low, no dedicated DevOps engineer
Low, standard Kubernetes
Stay on SageMaker or Databricks for part of the pipeline
AWS or Databricks
Limited to supported instances and images
Your cloud account plus ml.* premium or DBUs
Already running
None
High, proprietary APIs
Decision rule: pick based on how many engineers you can dedicate to the platform, not on which tool has the nicest docs.
What should you check before and after the cutover?
Validate four axes before deleting the old pipeline: numerical parity of the trained model, wall-clock per run, cost per completed run, and GPU utilization measured with DCGM. If any one regresses, fix it first, and keep the managed pipeline runnable for one more retraining cycle.
Axis
Metric
How you measure it
Pass threshold
What you do if it fails
Model parity
Eval metrics on the same data and seed
Same eval set, both pipelines, logged to MLflow
Within a tolerance written down before the run
Diff data loaders, preprocessing, framework and CUDA versions
Throughput
Samples per second, time to convergence
Training logs vs the SageMaker or Databricks baseline run
Equal or better than the managed baseline
Check NCCL transport, EFA or InfiniBand, data loader workers
Cost
Cost per completed run, including retries, preempted spot runs, data transfer
Cloud bill tags per namespace or queue
Lower than the managed baseline per completed run
Move to spot, add MIG, tighten scale-to-zero
GPU utilization
DCGM_FI_DEV_GPU_UTIL per team or queue over a full week
DCGM Exporter, Prometheus, Grafana
Sustained above the threshold you set, for example 50%
Fix data loading first, then bin-pack or share GPUs
Operations
Paging, driver upgrades, Kubernetes upgrades, per-team quota, empty spot pool
Runbook review and one game day
Every item has a named owner
Assign owners or buy the operating layer
Compliance is often the reason the move clears review. Training inside your own account and region keeps personal data under your control, which matters in finance, healthcare and the EU, where GDPR restricts transfers of personal data outside the EEA.
How do I run this migration from Claude Code or Cursor with Qovery?
Install the Qovery Agent Skills once and your coding agent (Claude Code, Cursor, Codex, OpenCode or Gemini CLI) can scaffold the containerized training job, deploy it to a cluster in your own cloud account, and troubleshoot the first run, asking you to approve each action before it happens.
Add the MCP Server to Claude Code (OAuth, read-only by default) so the agent can inspect what already runs:
BASH
claude mcp add --transport http qovery https://mcp.qovery.com/mcp --callback-port 4242
Enable write access only when you want the agent to change things. You also need to enable write access in the Qovery Console:
BASH
claude mcp add --transport http qovery "https://mcp.qovery.com/mcp?read_write=true" --callback-port 4242
The skills that matter here are qovery-onboard, qovery-deploy, qovery-troubleshoot, qovery-optimize, qovery-speedup, qovery-preview and qovery-terraform. The skills deploy; the MCP Server operates what already exists. Then ask in plain language: "Deploy this training container to my AWS account with Qovery" or "Why did this training job fail?"
How do I migrate a SageMaker training pipeline to Kubernetes?
Move the training code out of the Estimator into a container with a plain train.py, replace /opt/ml/input channels with S3 URIs, and run one Kubeflow Trainer TrainJob on an EKS GPU node pool beside the existing pipeline. Then port SageMaker Pipelines to Argo Workflows or Kubeflow Pipelines, swap the Model Registry for MLflow, and parallel-run one retraining cycle before cutting over. Expect four to six weeks of work for one pipeline and one ML engineer, plus one retraining cycle in parallel.
How do I migrate Databricks jobs and notebooks to Kubernetes without rewriting everything?
Extract the notebook logic into a script and container first, keep Delta Lake as the data source, and replace dbfs:/ paths with object storage URIs. TorchDistributor jobs map to a Kubeflow Trainer TrainJob, and Databricks Workflows map to Argo Workflows or Flyte. Move one job at a time and keep the Databricks job runnable until the Kubernetes run matches its metrics.
Is GPU training on Kubernetes actually cheaper than SageMaker or Databricks?
For sustained use, yes. In us-east-1 (November 2026), SageMaker training costs 15-40% more than the same EC2 instance, and Azure Databricks Premium Jobs adds $0.30 per DBU on top of the VM, from +4% on an 8x H100 VM to +82% on a single A100 VM. Kubernetes adds spot GPUs, MIG sharing and scale-to-zero, but one idle p5.48xlarge costs about $40,180 a month, so below roughly half-month utilization the managed platform often wins.
How do I get direct GPU access and share one A100 or H100 across several training jobs on Kubernetes?
Install the NVIDIA GPU Operator on a tainted GPU node pool and pick a sharing mode per pool. MIG splits one A100 80GB or H100 80GB into up to seven isolated 1g.10gb instances with their own memory; time-slicing shares a GPU across more pods but without memory or fault isolation. Use MIG for small production jobs, time-slicing for notebooks, and whole GPUs for distributed training.
Do I need a dedicated DevOps engineer to run GPU training on Kubernetes?
On raw EKS, GKE or AKS, someone has to own node pools, GPU drivers, autoscaling, upgrades and on-call, which usually means a platform engineer. Managed runtimes like Anyscale or Union.ai remove part of that work with a new vendor bill. Qovery operates the Kubernetes cluster inside your own AWS, GCP, Azure or Scaleway account, so ML engineers can ship training workloads without a dedicated DevOps engineer.
Can I keep Delta Lake or Unity Catalog while moving training to Kubernetes?
Yes. Delta Lake is an open table format that sits on S3, ADLS or GCS, so Kubernetes training jobs can read it directly with the deltalake Python package or Spark. Unity Catalog can stay the governance layer for your data while GPU training moves to Kubernetes. This hybrid is common: data stays on Databricks, training moves to your cluster.
Melanie leads content at Qovery. She covers platform engineering trends, Kubernetes operations, FinOps, and the tools that help engineering teams ship faster.
Next step
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.