Rackspace Spot from zero: a spot-priced Kubernetes cluster with a DevPod dev environment

kubernetesrackspace-spotdevpodremote-development

Last verified:

On this page
  1. What you’ll need#
  2. Part 1 — A working Spot cluster#
  3. 1. Sign up and create a cloudspace#
  4. 2. Add a spot node pool — and bid with the percentiles#
  5. 3. Download the kubeconfig — then immediately make a better one#
  6. 4. Two first-boot fixes every new cloudspace needs#
  7. 5. Storage: decide sizes up front#
  8. Part 2 — The dev environment, with DevPod#
  9. 6. Install the CLI#
  10. 7. Configure the Kubernetes provider once#
  11. 8. Launch#
  12. 9. Living with preemption#
  13. Caveats worth knowing#
For terminals & agents: curl -s https://jedarden.com/guides/rackspace-spot-devpod.md

Rackspace Spot sells surplus data-center capacity as managed Kubernetes clusters, priced by open auction. As of a July 2026 pricing change, new bids floor at $0.01 per hour — about $7.30 a month for a node at the floor, which in the less-contested regions you usually get close to. (Bids placed before that change keep running below $0.01/hr, so don’t be surprised if the live pricing table shows a market-clearing price under a cent even though you can no longer place a new bid there.) Either way, it’s the cheapest way I know of to run a real, persistent Kubernetes cluster — and a remote dev environment on top of it.

This guide gets you from no account to a working devcontainer dev environment served by DevPod, including the handful of sharp edges that aren’t in Rackspace’s docs. Everything here comes from running several Spot clusters in production for over a year; the pitfalls are ones I hit for real.

What you’ll need#

  • kubectl installed locally
  • A Docker Hub account (free) — you’ll need a personal access token to dodge a rate-limit trap explained below
  • Optionally, a repo with a devcontainer.json you want to develop in

Part 1 — A working Spot cluster#

1. Sign up and create a cloudspace#

Create an account at spot.rackspace.com, then create a cloudspace — Rackspace’s name for a managed Kubernetes cluster. The control plane is free on the standard tier; you pay only for the nodes you bid on.

Region choice matters more than anything else on your bill. Auction prices vary a lot between regions: the US regions around Ashburn (IAD) and Chicago (ORD) have historically had classes sitting at or near the bid floor for long stretches, while others clear meaningfully higher. Check the live pricing table before you pick — it reads Rackspace’s public pricing feed and shows the current market price plus percentiles for every server class in every region.

2. Add a spot node pool — and bid with the percentiles#

Add a node pool to your cloudspace. Two decisions here:

  • Server class. A general-purpose class (e.g. gp.vs1.medium in your chosen region — 4 vCPU / 8 GB) is plenty for a dev environment.
  • Bid price. Your bid is the maximum you’ll pay; you’re charged the current market price as long as it’s at or below your bid. When the market rises above your bid, your node is preempted. The pricing table shows p20/p50/p80 percentiles for each class: bidding at the p80 level would have kept your node through roughly 80% of the recent window. Bidding exactly the current market price wins now and gets preempted at the next uptick. Since July 2026, new bids also round to fixed steps with a $0.01/hr floor — $0.01 increments up to $0.04/hr, $0.02 up to $0.10/hr, $0.03 up to $0.20/hr, $0.05 above that (changelog). If your target percentile is below $0.01/hr, round up to $0.01/hr or the nearest step above it — you can’t place a new bid lower than that anymore.

Stick to spot pools. On-demand pools exist but cost many times more, which defeats the reason to be here.

3. Download the kubeconfig — then immediately make a better one#

The kubeconfig you download from the console authenticates with an OIDC token that expires after about three days. It’s fine for bootstrap work, but anything unattended (CI, a dev-environment launcher, monitoring) will mysteriously lose access mid-week.

Mint a long-lived ServiceAccount credential right away:

export KUBECONFIG=~/Downloads/your-cloudspace.yaml

kubectl create serviceaccount admin-sa -n kube-system
kubectl create clusterrolebinding admin-sa \
  --clusterrole=cluster-admin \
  --serviceaccount=kube-system:admin-sa
kubectl create token admin-sa -n kube-system --duration=8760h

Build a kubeconfig around that token (same cluster/server block, swap the user for token: <output>), keep it somewhere safe, and use it for everything from here on. Scope it down from cluster-admin later if you keep the cluster around.

4. Two first-boot fixes every new cloudspace needs#

Calico picks the wrong node IP. Spot’s Calico ships with firstFound autodetection, which on these nodes grabs an unreachable interface — symptoms range from flaky pod networking to nodes that never go Ready. Point it at the node’s real InternalIP:

kubectl patch installation default --type=merge \
  -p '{"spec":{"calicoNetwork":{"nodeAddressAutodetectionV4":{"kubernetes":"NodeInternalIP"}}}}'

Anonymous Docker Hub pulls get throttled. Spot nodes share NAT egress addresses with other tenants, so Docker Hub’s anonymous rate limit (HTTP 429) is effectively always exhausted. This can break anything pulling from docker.io — I’ve seen it take down CNI and CSI images after a node was recreated, leaving the node NotReady. Create an authenticated pull secret in each namespace you deploy to, using a Docker Hub personal access token:

kubectl create namespace devpod
kubectl create secret docker-registry docker-hub-registry -n devpod \
  --docker-username=<your-dockerhub-user> \
  --docker-password=<your-dockerhub-PAT>

Reference it from your pods’ imagePullSecrets — or, for DevPod below, it gets picked up automatically.

5. Storage: decide sizes up front#

Spot’s storage is OpenStack Cinder. Two rules:

  • Always set storageClassName explicitly on every PVC. The default class varies by cluster, and on Spot the sata class (or sata-large for volumes over ~100 GB) is the one you want.
  • Volumes cannot be expanded. The API returns a 403 on resize — a PVC’s size is a lifetime decision. Size generously; at these prices a too-big volume costs cents.

Part 2 — The dev environment, with DevPod#

DevPod is a client-side, open-source tool that creates dev environments from devcontainer.json on any backend — including a bare Kubernetes cluster. Nothing to install in the cluster ahead of time: each workspace is a pod plus a PVC, created on demand, and DevPod’s dockerless mode builds the devcontainer image inside the cluster, so you don’t need Docker locally or a registry.

6. Install the CLI#

curl -L -o devpod "https://github.com/loft-sh/devpod/releases/latest/download/devpod-linux-amd64" \
  && sudo install -c -m 0755 devpod /usr/local/bin && rm -f devpod

(There’s also a desktop app, and builds for macOS/Windows — see devpod.sh.)

7. Configure the Kubernetes provider once#

This is where every Spot lesson from Part 1 gets encoded as a default:

devpod provider add kubernetes
devpod provider set-options kubernetes \
  -o KUBERNETES_CONFIG=$HOME/.kube/spot.kubeconfig \
  -o KUBERNETES_NAMESPACE=devpod \
  -o STORAGE_CLASS=sata \
  -o DISK_SIZE=30Gi \
  -o PVC_ACCESS_MODE=RWO \
  -o INACTIVITY_TIMEOUT=2h

Why each option matters here:

  • KUBERNETES_CONFIG — the long-lived kubeconfig from step 3, not the 3-day one.
  • STORAGE_CLASS=sata — otherwise DevPod uses the cluster default, which may not be the class you want (step 5).
  • DISK_SIZE=30Gi — this PVC is your workspace’s persistent home and it can never be expanded. Pick a size you won’t outgrow.
  • INACTIVITY_TIMEOUT=2h — auto-stops idle workspace pods. The PVC (your work) stays; the pod (the compute) goes away until the next devpod up.
  • Pull secrets: the provider’s KUBERNETES_PULL_SECRETS_ENABLED defaults to true, so the docker-hub-registry secret from step 4 protects workspace image pulls from the 429 trap automatically.

8. Launch#

devpod up github.com/your-org/your-repo --provider kubernetes --ide vscode

DevPod creates the PVC and workspace pod, builds the devcontainer in-cluster, and opens VS Code connected through a tunnel — no ingress, no load balancer, no public exposure of the cluster. Prefer a terminal?

devpod up github.com/your-org/your-repo --provider kubernetes --ide none
devpod ssh your-repo

9. Living with preemption#

This is spot capacity: when the market price rises above your bid, the node goes away. What that actually means for a DevPod workspace:

  • The pod dies, the PVC survives — your checked-out code, build caches, and home directory are all on the volume.
  • devpod up <workspace> re-provisions onto whatever node your bid wins next, usually within a couple of minutes of capacity returning.
  • Anything running unattended (long builds, servers) dies with the pod. Treat the workspace like a laptop that can run out of battery: commit and push often.
  • Bidding at the p80 percentile (step 2) makes this rare — at the floor-priced classes, preemptions can be weeks apart.

Caveats worth knowing#

  • The 429 trap recurs. Every time Spot recreates a node, that node pulls its system images through the shared NAT. If a fresh node sits NotReady, check for ImagePullBackOff on CNI/CSI pods before suspecting anything else.
  • Prices move. The pricing table is a snapshot of Rackspace’s published feed with the fetch time shown — always confirm in the console before changing a bid.
  • The $0.01/hr minimum bid is new capacity only. Rackspace changed this in July 2026 (see the changelog); bids placed before then keep running below $0.01/hr untouched, so the pricing table can show a market-clearing price under a cent even though you can’t place a new bid there. As of this writing, Rackspace’s own /pricing marketing page still advertises “bid from $0.001/hr” and hasn’t caught up to its own changelog — trust the changelog, not the marketing copy.
  • DevPod’s Kubernetes provider needs write access to one namespace. The ServiceAccount options (SERVICE_ACCOUNT, CLUSTER_ROLE) let you tighten this once you’re past the bootstrap stage.
  • Check your node pool type occasionally. Only spot pools; if an on-demand pool ever appears (e.g. from console experimentation), delete it — it bills at a completely different rate.