Run a Migration Cutover¶
To carry out a cutover through Confluent Gateway, run kcp migration cutover execute with your migration manifest. This page explains how execute and lag-check use the manifest, how kcp resumes an interrupted migration or conversion, and what to check before you run a cutover.
Execution model¶
The migration manifest drives a resumable migration workflow:
executevalidates the manifest and live infrastructure. It reads the live initial Gateway custom resource (CR) to check that the route's mode matches the declared migration type (see Declare the migration type) and, on a static route, to derive the bootstrap server ID from the target domain. It then carries the migration forward through fence → promote → switch (a conversion: fence → verify → sync offsets → switch). Every run reconciles live from the manifest and the current cluster state, so you can safely continue an interrupted run by re-running the same command: it resumes from whatever the live world already reflects. It re-reads the manifest (topology and policy) on every invocation.--dry-runruns only the reconcile step, against the live Gateway CR, the source and destination Apache Kafka® clusters, and the cluster link, and prints the plan: each precondition (the route exists and has the expected mode, the Gateway CR is set up the way that mode needs, the cluster link mirrors from the source cluster, andspec.target.clusterIdmatches the destination) and a verdict for every selected topic. Nothing is changed and no migration steps run. It exits non-zero if the plan is refused. Flag overrides are applied and validated first, so a dry run rejects an invalid override exactly as a real run would. Use it to iterate on the manifest and your infrastructure before you schedule a live cutover.
lag-checkis an interactive terminal view of replication lag for every mirror topic on the cluster link, independent ofexecute. It uses only the destination REST leg (spec.clusterLink.linkCredentials), so it works beforeexecutehas ever run.
Every execute reconciles the current manifest live against the cluster. A completed migration re-reconciles to nothing to do: execute then runs no migration steps and reports that. An interrupted one continues from the live state. To migrate a different topology, edit the manifest and run execute again. metadata.name is only a label (it appears in logs and the completion message). Changing it does not change what is reconciled.
Resume an interrupted migration with the same topic set (dynamic routes).
On a dynamic route, kcp recognizes the fence it added by its exact shape: a
rules.fencing entry with only topics (the migration's exact topic set) and
blocked: true. Any other entry, including one over the same topics that also
sets trafficType or topicPatterns, is an operator's, and kcp leaves it in
place. If a run is interrupted after fencing, resume it with a manifest that
resolves to the same topics. Resuming with a different set (a topic added or
removed, or a topicPatterns entry that now also matches a topic created on
the source since the interrupted run) is a different migration: kcp fences
the new set, treats the earlier fence as operator-authored, and leaves it on
the route, so those topics stay blocked after switchover. Finish the
interrupted migration first, then migrate the changed set. If this has already
happened, remove the leftover blocked entry from the route's rules.fencing
by hand.
Resume an interrupted conversion. A route conversion keeps no state
between runs either. kcp recognizes its conversion fence by its exact shape:
a rules.fencing entry with only topicPatterns: ['.*'] and blocked: true.
If a conversion is interrupted, re-run the same manifest: kcp finds its fence
on the route, re-checks everything, and carries on. See
Interruptions.
A static route must not carry someone else's fence. A static route has a
single route-level fence. kcp recognizes its own by its exact value,
{scope: ALL, errorCode: BROKER_NOT_AVAILABLE}, and refuses a route that
already carries any other fence, because the switchover and a rollback would
remove it: remove that fence before migrating. scope: NONE counts as no
fence. An operator's plain scope: ALL fence reads back with the same
defaulted errorCode, so kcp cannot tell it from its own and would remove it
too. Remove it before migrating.
Each field under the declared section's policies is a default that a matching
CLI flag can override for a single run, without editing the file.
Before you run it¶
- Connections. Every
executerun, including--dry-run, connects to the source Kafka cluster, the destination Kafka cluster, the cluster-link REST API, and the Kubernetes API, using the credentials and kubeconfig named in the manifest. A--dry-runonly reads: on Kubernetes it reads the Gateway CR (and, for a static migration, checks that the staged Secrets exist). Every run, including a dry run, also checks that the Gateway pods serve the Gateway CR before deciding anything: it reads the CR's status, the Gateway Deployment and its pods, and, on a Gateway with hot reload on, each pod's/configendpoint. kcp refuses the run when the pods may not match the CR, and shows what it observed. The permissions to patch the Gateway and write cluster-link configurations are first used after the fence, so a real run is the first to find one missing. See Permissions. - Producers must use the Gateway. The fence blocks traffic that goes
through the Gateway. Producers writing to the source directly are not
blocked, and the check that catches them (
detectUnroutedProducersDuration) is off by default. A route conversion does not usedetectUnroutedProducersDurationat all. It uses its owndetectUnroutedCommitsDurationcheck instead (see Conversion steps), which watches for consumers committing to the source directly and, like the producer check, is off by default. - What is fenced. A static route is fenced and switched as a whole: the topic selection only decides which mirrors are promoted and lag-checked. A dynamic route fences and switches only the selected topics.
- Promote is the point of no return. If a step fails after the fence is up
but before the promote step starts, kcp removes the fence and restores offset
sync so traffic returns to the source. After promote starts, kcp never removes
the fence, even if no topic was promoted yet, because doing so would split those
clients from the target. The same applies from the start of a re-run that
finds a topic already promoted or promoting. Fix the cause and re-run
executeto roll forward. A conversion promotes nothing. Its point of no return is the switch (see Conversion steps). - Interrupting kcp leaves the fence up. kcp doesn't clean up when it is
stopped (Ctrl+C,
SIGTERM, or a crash), so the fence stays. The Gateway stays fenced until you re-runexecute. - No deadline by default.
rolloutTimeoutdefaults to no deadline, so a rollout that never converges waits indefinitely, with traffic already fenced. - A refused plan changes nothing. If reconcile refuses the plan (for
example, a selected topic is not a mirror topic on the link), the whole run is
refused before anything is fenced or changed.
--dry-runshows the plan and the reasons.