Skip to main content

Cluster API's Docker Resources Are Deprecated, Not Removed: The Real CAPD→CAPDev Timeline and What to Migrate Before v1.15

8 min readDora NodaDora Noda
Share
On this page

If you searched for when Cluster API deprecated its Docker-backed test resources and landed on "v1.12," that's wrong on both ends. The deprecation PR merged in April 2026 and shipped in v1.13.0; the current release is v1.13.4 (July 15, 2026); and full removal of DockerCluster, DockerMachine, and DockerMachinePool isn't scheduled for v1.13 at all — it's targeted for v1.15, a release that doesn't exist yet, with no committed date. The tracking issue, kubernetes-sigs/cluster-api#13270, was last updated July 20, 2026, and its v1.15 checklist is still unchecked.

That gap between "deprecated" and "removed" matters more than the version-number trivia. DockerCluster/DockerMachine/DockerMachinePool still work today, in the current release, with no functional change. What changed is that the community's own test infrastructure, CI templates, and documentation are actively moving off them — and any team whose manifests, test fixtures, or tooling assume those kinds exist has a real but unpublished migration window to use before they stop working.

The actual timeline, dated

Here's what the public record — the proposal doc, the tracking issue, and the merged PRs — actually says, in order:

DateEvent
Jan 25, 2025Proposal opened: evolve CAPD(docker) into a generic CAPD(dev) supporting docker, in-memory, and eventually kubemark backends
~CAPI v1.10 cyclePhase 1 ships: DevCluster/DevMachine land with docker and in-memory backends; InMemoryCluster/InMemoryMachine (the old CAPIM provider) are removed immediately, not deprecated first
Feb 2026DevMachinePool with a docker backend lands, closing the last kind gap between Docker* and Dev*
Apr 10, 2026PR #13557 merges: DockerCluster, DockerMachine, and DockerMachinePool are formally marked deprecated
Apr 21, 2026v1.13.0 ships — the deprecation is now in a released version, not just main
Through Jul 2026E2E tests, test-extension code, and test/infrastructure/docker/templates all migrate to Dev* resources
Jul 15, 2026v1.13.4 ships — current latest release
Jul 20, 2026Tracking issue #13270 last updated; every task through "migrate E2E to in-memory backend" is checked off, the v1.15 removal checklist is not
Targeted v1.15Actual removal of DockerCluster/DockerMachine/DockerMachinePool, plus a docs/folder-structure cleanup (infrastructure-dockerinfrastructure-dev)

Cluster API ships a new minor roughly every four months and actively supports N, N-1, and N-2 — v1.13, v1.12, and v1.11 are all supported right now, with v1.11 in maintenance-only mode. No v1.14 has shipped yet as of this writing. On that public cadence, v1.14 lands around September–October 2026 and v1.15 — the release that actually deletes the Docker* CRDs — lands somewhere around December 2026 to February 2027. That's an inference from the project's own stated release rhythm, not an announced date; treat it as the outer edge of your planning window, not a deadline to cut it close to.

What actually changes in your manifests

The rename isn't cosmetic — fields move, not just kind names. Here's the shape straight from the proposal doc%20to%20CAPD(dev)%20.md), a DockerMachine next to its DevMachine equivalent:

yaml
# Before — deprecated, still works through v1.13.x and v1.14.x
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DockerMachine
metadata:
  name: controlplane
spec:
  extraMounts:
    - containerPath: "/var/run/docker.sock"
      hostPath: "/var/run/docker.sock"
yaml
# After — the kind changes AND the spec nests under spec.backend.docker
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DevMachine
metadata:
  name: controlplane
spec:
  backend:
    docker:
      extraMounts:
        - containerPath: "/var/run/docker.sock"
          hostPath: "/var/run/docker.sock"

Every DockerMachine field you're currently setting has to move under spec.backend.docker, not just get relabeled — a find-and-replace on the kind: line alone will produce a manifest that doesn't validate. The same spec.backend.<name> nesting applies to DockerClusterDevCluster, and DockerMachinePoolDevMachinePool follows the identical pattern. It's not vaporware either — the February 2026 PR that landed it includes the actual proof-of-work output from a live cluster:

text
$ kubectl get cluster
NAME          CLUSTERCLASS      AVAILABLE   CP DESIRED   CP AVAILABLE   PHASE         AGE
dev-mp-7608   dev-quick-start   True        1            0              Provisioned   9m26s
 
$ kubectl get machinepool
NAME                     CLUSTER       DESIRED   CURRENT   READY   PHASE       AGE
dev-mp-7608-mp-0-pmchk   dev-mp-7608   1         1         0       ScalingUp   9m30s
 
$ kubectl get devmachinepool
NAME                     AGE
dev-mp-7608-mp-0-szq42   9m34s
 
$ kubectl get devmachine
NAME                      CLUSTER       FAILURE DOMAIN   PROVISIONED   AGE
dev-mp-7608-zwwdv-vpgtd   dev-mp-7608   fd1              true          9m37s
worker-jysrly             dev-mp-7608                    true          7m18s

That's a real MachinePool backed by a real DevMachinePool/DevMachine pair, not a design sketch — the three-kind migration is fully implemented today, months ahead of the v1.15 removal that will make it mandatory.

DevCluster/DevMachine also carry an inMemory backend option, functionally equivalent to the now-removed InMemoryCluster/InMemoryMachine, plus a reserved slot for a future kubemark backend if CAPK's maintainers ever converge onto CAPDev. None of that is relevant to a fleet that only ever used the docker backend — but it's the reason the kind consolidated in the first place: one set of CRDs, one controller, three interchangeable backends, instead of three separate providers each with its own CI and release burden.

What this actually means for a CAPH-based fleet

It's tempting to assume CAPD sits underneath a CAPH-based fleet's own local-dev loop, given how often the two show up in the same sentence. It doesn't. CAPH's own Tiltfile spins up a kind cluster (kind_cluster_name: "caph") directly — CAPD isn't in that loop at all. Nobody running tilt up against CAPH is touching DockerCluster or DevCluster in the course of normal development.

The real exposure is narrower and easy to miss precisely because it's not in the day-to-day workflow:

  • E2E and integration test fixtures that spin up a workload cluster on the docker backend to exercise a CAPH controller's reconcile logic without hitting the real Hetzner API — any YAML in that suite still declaring kind: DockerCluster or kind: DockerMachine.
  • Reference manifests and quick-start docs copied from an older CAPI example that predates the Dev* migration — CAPI's own upstream templates already moved (test/infrastructure/docker/templates migrated in PR #13741), so a doc that still shows DockerMachine is now visibly stale against the source it was copied from.
  • Any tooling that generates or validates against Docker* CRD schemas — a codegen step, an OPA/Kyverno policy, or a CI lint rule hardcoded to kind: DockerCluster will silently stop matching once a manifest is migrated to DevCluster, and will hard-fail once v1.15 deletes the old CRD entirely.

Concretely, before v1.15 ships, that's a one-line audit:

bash
grep -rn "kind: Docker\(Cluster\|Machine\|MachinePool\)" .

against your test fixtures, CI manifests, and docs — then migrate each hit to the Dev* kind with fields moved under spec.backend.docker, following the shape above.

Why "not just a naming preference" is the right read

It would be easy to treat this as upstream bikeshedding — a kind got renamed, whatever. Two facts argue against that reading. First, the precedent: CAPIM's InMemoryCluster/InMemoryMachine weren't deprecated-then-later-removed at all — they were deleted the same cycle DevCluster/DevMachine landed, because CAPIM's blast radius (CAPI's own scale tests) was small enough to move fast. That's a live demonstration that this project does execute removals on schedule when it decides to, not a hypothetical.

Second — and this is the part worth budgeting time for now rather than at v1.15 — there is currently no official migration guide. Search the Cluster API Book for one and you won't find it; the only written record of the field-level migration shape is the proposal doc%20to%20CAPD(dev)%20.md) and the PR descriptions linked above. A team that waits for a polished migration doc to appear before touching this is waiting for something that, as of today, doesn't exist and isn't promised.

There's also a support-window trap worth naming directly. Cluster API only actively supports N, N-1, and N-2 minors — right now that's v1.13, v1.12, and v1.11, with v1.11 already in maintenance-only mode (emergency patches, no proactive backports). The deprecation warning itself shipped in v1.13.0; it was never backported to v1.12.x or v1.11.x. A fleet still pinned to v1.11 or v1.12 for stability reasons won't see so much as a deprecation notice until the day it upgrades past v1.13 — which means "upgrade to the latest supported minor" is quietly also "the first moment you'll be told this is happening," with less runway left before v1.15 than a team on the current release gets.

Action items, now

  1. Grep test fixtures, CI manifests, and docs for kind: Docker(Cluster|Machine|MachinePool).
  2. Migrate each hit to DevCluster/DevMachine/DevMachinePool, moving every spec field under spec.backend.docker.
  3. Update or delete any policy/lint/codegen rule hardcoded to the old kind: string.
  4. Watch #13270 directly rather than a release-notes summary — it's the single place the v1.15 removal checklist gets checked off first.

None of this is urgent in the sense of "breaks today." It is urgent in the sense that the only source of truth is a GitHub issue and two PR descriptions, and the removal date is an inference from release cadence rather than a commitment — the kind of gap that's cheap to close in July and expensive to discover in whatever month v1.15 actually ships.

Bex.co runs its own fleet on Cluster API and Cluster API Provider Hetzner — the open-source, AI-native Render alternative: push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Sources

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex