Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM’s address.
By the end of this page, VMs that ran in your vCenter run as KubeVirt VMs in a project on a supervisor, and you have checked that they arrived. Celum drives Forklift for the move: Forklift copies each VM’s disks, and virt-v2v converts the guest to run on KVM unless you ask for the disks as they are.Only vSphere is a source in this release, and only through a vCenter. Celum declares every source to Forklift as a vCenter (sdkEndpoint: vcenter), so a standalone ESXi host cannot be a source, and Celum refuses an ESXi host’s address (see Step 3). oVirt, OpenStack, Hyper-V and OVA appear in the form as “Not in this release”.
On the supervisor. Turning migration on installs Forklift (konveyor-forklift/virt-forklift), the NetworkAttachmentDefinition CRD if it is missing, four admission policies, and one Cilium policy (celum-forklift-v2v) that lets Forklift reach its conversion pods inside isolated projects. The admission policies act only in namespaces labelled k8s-gate/migration-target; creating a plan sets that label on the plan’s project namespace. Talos nodes need no change: the conversion does not need user namespaces.In the project. The migrated VMs and their disks, as ordinary Celum VMs of that project.In vCenter. Celum reads the inventory. When a plan runs, each source VM is shut down — a cold plan at its start, a warm plan at cutover — and stays off in vCenter. A warm plan also takes snapshots of the source VM while it copies.
An onboarded supervisor with KubeVirt, CDI, cert-manager and Flux, and a Kubernetes version that serves admissionregistration.k8s.io/v1 MutatingAdmissionPolicy (GA in 1.36). If any of these is missing, turning migration on is refused with 409, and the card links to the onboarding step that installs it.
The Secret Store onboarding step, if you register the vCenter for the platform (step 2). The credential lives in the secret store and reaches the supervisor through External Secrets.
The cluster agent chart 1.30.462 or later on the supervisor. The plan wizard reads the vCenter inventory through it; with an older agent it cannot list VMs.
A registry. Forklift’s images (about 5.6 GB) are copied into the supervisor’s registry when migration is turned on.
A VDDK image, vddk:<version>, in the supervisor’s registry, for warm migration, for copying disks as they are, and for the fastest copy. VDDK is VMware’s Virtual Disk Development Kit, licensed by Broadcom, which you load into the registry yourself. A Celum appliance installed from a 1.314 OVA or later carries OpenVDDK, an independent Apache-2.0 drop-in for it, as vddk:0.7.4, and new sources take it by default. Updating an older appliance in place does not add it. Without a VDDK, a source can still use virt-v2v over HTTPS (step 3).
vCenter reachable over HTTPS (/sdk) from the supervisor. For a warm migration, Changed Block Tracking (CBT) enabled on the VMs. To keep a VM’s address, VMware Tools running in the guest, so vCenter reports the address.
Turn migration on → register the vCenter → add a source → build a plan → run it → verify. The first three are done once per supervisor; a plan is one wave of VMs.
Migrations. While migration is off, the page shows VM migration is off on this supervisor, with what it installs, its prerequisites, and VMs transferred at once (1–200, default 20). Enable VM migration starts at once, without a confirmation; it reads “Copying images…” while Forklift’s images are copied into the supervisor’s registry.
POST /api/supervisors/{name}/migration/enable with {"maxVMInflight": 20}. GET /api/supervisors/{name}/migration/status reports the components.
enable_vm_migration, and get_component_status with component=migration.
Result: the Forklift tile reads 6/6, “components up · destination ready”, and the VM migration on this supervisor card lists every component ready.
Migrations with Forklift running and two sources ready
Register a vCenter once, and every supervisor’s sources (and Cluster API) can use it. Celum pins its certificate, tests the login, and keeps the user and password only in the secret store.
Dashboard
API
MCP
Settings → vCenters → Add vCenter: Name, Address, Load from vCenter (reads its certificate), User, Password, CA certificate, an optional description, then Verify and add. A row’s menu offers Edit or rotate password, Load the certificate again and Remove.
POST /api/vcenters with name, server, username, password, caPem and description. GET /api/vcenters lists them; PUT and DELETE /api/vcenters/{name} change and remove one.
create_vcenter, register_vcenter_from_cluster_api, update_vcenter, probe_vsphere_certificate, list_vcenters and get_vcenter. No tool removes a vCenter.
Settings → vCenters: the certificate is pinned and the credential is in the secret store
Registering a vCenter, or rotating its password, refuses an ESXi host’s address with the same message as a source does (see Step 3).You can skip this step and type a vCenter’s address and credentials straight into a source. Registering it keeps one copy of the credential, which every source then reads.
A source is the vCenter that VMs are migrated from, as Forklift sees it.
Dashboard
API
MCP
Migrations → Sources → Add source. Source type vSphere. For the vCenter, choose A registered vCenter, This supervisor’s vCenter (the one Cluster API uses), or Another vCenter with its address, user, password and CA certificate. Name the source (a DNS label; plans refer to it by name) and pick the VDDK image, or None — virt-v2v copies over HTTPS. Add source saves it.
POST /api/supervisors/{name}/migration/providers with name, type: "vsphere", and one of vcenter (a registered one), useSupervisorVCenter, or url, user, password and caCert. Optional: insecureSkipVerify, and vddkImage ("none" for no VDDK). GET lists the sources, DELETE .../providers/{provider} removes one, PUT .../providers/{provider}/vcenter switches it to a registered vCenter, and POST .../providers/{provider}/register-vcenter registers its vCenter for the platform.
create_migration_source, list_migration_sources, use_vcenter_for_migration_source, register_vcenter_from_migration_source, and get_migration_source_inventory to read its VMs, networks and datastores. No tool removes a source.
Add source, taking the vCenter registered in Settings
Celum tests the login before it saves the source, and it refuses three sources that would only fail later, during a run:
An ESXi host. Celum asks the address what it is before it sends the password, and refuses an ESXi host with “<host> is an ESXi host, not a vCenter — give the address of the vCenter that manages it”. It makes this check also when Skip TLS verification is on.
No CA and no insecureSkipVerify. TLS is verified, so the source needs the CA the vCenter’s certificate chains to.
No VDDK and TLS still verified. Without VDDK, virt-v2v copies the disks with curl, which ignores the CA, and the run would fail at conversion with curl error 60. Use a VDDK image, or accept insecureSkipVerify.
Result: the source’s row shows TLS verified and state ready. New plan stays disabled until at least one source is ready.
Changing a source makes Forklift read its whole vCenter inventory again. A run copying from that source at that moment can fail. Change a source between runs, not during one.
A plan names the VMs to move, the source, the project they land in, and how their networks, addresses and disks map. It holds at most 500 VMs.
Dashboard
API
MCP
Migrations → Plans → New plan, or Workloads → New workload → Import from another platform. The wizard has seven steps: Source & target, VMs, Networks, Addresses, Storage, Migration type, Review.
POST /api/supervisors/{name}/migration/plans with name, source, targetNamespace, vms, networks and storage. Optional: description, type (cold, the default, or warm), conversion (full, the default, raw-virtio or raw-compatibility), convertorNode, targetPowerState (on, off, or empty for the source VM’s state), preserveStaticIPs, identityNetwork, addresses, and start to start it as soon as it is ready. GET /api/supervisors/{name}/migration/landing?namespace= reads what the project offers.
create_migration_plan, with get_migration_source_inventory and get_migration_landing to fill it in.
Source & target. The source, the Target project, a Plan name (a DNS label of at most 55 characters, such as erp-wave-3), and an optional description. The project’s namespace is where the VMs land; they become that project’s VMs.VMs. The source’s VMs, with their power state, OS, size and Concerns. vSphere Cluster Services (vCLS) agent VMs are not listed. The wizard will not go on with a VM whose name or MAC address is already in use on the supervisor, a VM with a critical concern, or a VM with more than one NIC on the pod network; in a warm plan, also a VM without CBT or with shared disks. vSAN needs VDDK.
VMs: pick the ones this wave moves
Networks. Each vCenter network the chosen VMs use goes to the Pod network or is ignored; a NIC on an ignored network is dropped. The pod network is masquerade, as for every Celum VM: the guest takes its address by DHCP. Mapping a network to a VLAN of its own is not offered yet.Addresses. A VM can keep the address VMware Tools reports for it, inside a subnet declared adoptable: it becomes the VM’s identity address, a routed /32 that follows it through live migration. The address is claimed only once that VM’s migration has succeeded. The other VMs get the pod address only, or an address from the project’s pool. Keeping addresses needs cilium:Apply, a NIC on the pod network, and cannot be combined with Preserve static IPs. Hosts still on the source subnet reach a kept address only once that subnet is extended (see Reach moved VMs from the source network), or once its gateway answers ARP for it.
Addresses: keep the address the guest had
Storage. Each datastore maps to a StorageClass. A VM keeps live migration between the supervisor’s nodes only on a class whose volumes are ReadWriteMany.Migration type.
Choice
What it does
Cold
Each VM is shut down, copied, converted and started here. It is down for the whole copy.
Warm
Copied while it runs, then the changed blocks again until cutover. It is down only for the last delta and the conversion. Needs VDDK and CBT.
Convert (default)
virt-v2v installs virtio drivers and the guest agent and removes VMware Tools. Most of a warm cutover’s downtime.
Copy as is · virtio
Disks copied unchanged, with a virtio disk and NIC. Boots only a guest that already has virtio drivers; no guest agent. Needs VDDK.
Copy as is · compatibility
Disks copied unchanged, with a SATA disk and an e1000e NIC, which most guests have drivers for. Slow disk and network; no guest agent. Needs VDDK.
Conversion runs on
The node that copies and converts each disk: the one with the faster path to the ESXi hosts, if one has it. It must run KubeVirt VMs, not be cordoned, and have no NoSchedule or NoExecute taint.
Power state after migration
As before, On, or Off.
Migration type: cold or warm, and whether the guest is converted
Review. The plan as it will be created, and what it does to the source: each VM is shut down in vCenter before its disks are copied and stays off there. Create plan creates it; Create and start also starts it as soon as Forklift has validated it (with VDDK that includes a check job, which can take a minute). Neither asks again.
The plan’s page, from Migrations → Plans. Start (or Retry) runs it. A warm plan adds Cut over now, and Schedule cutover… in the overflow menu. Cancel the run stops it. Each of these asks for confirmation, except scheduling a cutover.
POST /api/supervisors/{name}/migration/plans/{plan}/start, .../cutover with an optional {"at": "<RFC 3339 time>"}, .../cancel with an optional {"vms": [...]}. Cancelling single VMs is API only; the dashboard cancels the whole run. GET .../plans/{plan} reads the plan, its runs and each VM’s progress.
start_migration_plan, cutover_migration_plan, get_migration_plan and list_migration_plans. No tool cancels a run.
The plan’s page follows each VM through Forklift’s steps — Initialize, DiskTransfer, Cutover, ImageConversion, VirtualMachineCreation — with when each started and how long it took. A warm VM lists its precopies; a converted VM lists virt-v2v’s own phases. The page refreshes every 5 seconds while a run is going.
A finished warm migration: every step with its duration, the precopies, and the whole run
Progress counts each disk’s full size. VDDK reads only the blocks a disk has allocated, so the bytes actually moved, and the copy’s rate, are not shown, and the time left on a sparse disk can be well off. For orientation, on Celum’s own test bed: a copy with VDDK ran at about 150 MiB/s, and a warm cutover that kept the VM’s address took the VM away for about 2 minutes for Ubuntu and 6–7 minutes for Windows.
A plan is validating, needs attention, ready, running, succeeded, failed, canceled or archived. Mappings shows where each network and datastore went, and each VM’s identity address with its state.
Mappings: networks, datastores, and the address each VM kept
A VM that kept its address has left its source subnet. Hosts that stay behind in that subnet reach it again only when the subnet is extended: an ARP-proxy appliance, a small VM on the source VLAN, answers for exactly the addresses that moved and hands their traffic to the subnet’s own gateway, which routes each one to the supervisor. Nothing on the fabric changes. It bridges a migration in progress: move the whole subnet as soon as you can, retire the source environment, then remove the hybrid subnet.
Dashboard
API
MCP
Migrations → Network extension. Mapping lists the vCenter networks, the subnets their guests report, and how many hosts are still at the source. ARP-proxy appliances has Declare hybrid subnet and Deploy ARP-proxy appliance.
GET, POST /api/supervisors/{name}/networking/hybrid-subnets, and PUT, DELETE .../hybrid-subnets/{subnet}. PUT .../networking/vm-identity-adoptable declares which subnets’ addresses may be kept.
The plan reads succeeded, and VMs migrated counts every VM of the latest run.
Each VM is in Workloads, in the plan’s project, running (unless you chose Off).
A converted VM shows its guest agent connected. A copied-as-is VM has no guest agent, by design.
A VM that kept its address shows it on Mappings as done, and answers on it. From a host left in the source subnet, it answers only once that subnet is extended.
There is no reverse migration. The source VM is still in vCenter, powered off: power it back on there to return to it.
Cancel the run powers back on the VMs Forklift shut down, removes a warm plan’s snapshot, and removes what the run had built on the supervisor.
Retry runs again only the VMs that did not get across. A plan that succeeded cannot be run again.
Archive cleans up what failed and canceled VMs left behind.
Delete removes the plan. It never touches the VMs that migrated.
Disable on the VM migration on this supervisor card removes Forklift’s sources, their credentials and the plans, and leaves the CRDs. It is refused with 409 while a run is going; Disable anyway… overrides that. It never touches migrated VMs.
Removing a source, cancelling, archiving or deleting a plan, disabling migration and removing a vCenter have no MCP tool: they are left to a person on purpose. Use the dashboard or the API.
A prerequisite is missing on the supervisor; the message names it, and the card links to its onboarding step.
New plan is greyed out
No source is ready yet.
A source is refused with “no CA for …”
Paste the CA the vCenter’s certificate chains to, use a registered vCenter, or accept insecureSkipVerify.
A source without VDDK is refused with curl error 60
Without VDDK the copy ignores the CA. Use a VDDK image, or accept insecureSkipVerify.
The wizard lists no VMs
The cluster agent on the supervisor is older than chart 1.30.462.
The wizard will not let a VM through
Its name or MAC is already used on the supervisor, it has a critical concern, it has more than one NIC on the pod network, or (warm) it has no CBT or has shared disks.
A run stops at ImageConversion with 0%
The conversion pod in an isolated project is unreachable: the celum-forklift-v2v policy is missing. Re-apply on the migration card restores it, and every Start applies it again.
A run failed while a source was being changed
Changing a source re-reads its inventory. Change sources between runs, then Retry.
A Windows guest does not boot after Copy as is
A stock Windows guest has no virtio drivers, and one installed on PVSCSI may not boot from SATA either. Use Convert.
A converted Windows VM takes minutes longer to come up
Services set to Automatic (Delayed Start) add about two minutes to its first boot.
Disable answers 409
A run is going. Let it finish or cancel it, or use Disable anyway….
krn:celum:vcenter:* or krn:celum:vcenter:<vcenter>
Three checks happen inside a request rather than on its route: Create and start also needs migration:StartPlan; keeping addresses needs cilium:Apply; and Load from vCenter needs capi:Install.
Start, stop, resize and live-migrate the VMs you just moved.
VM identity pools
The addresses migrated VMs keep, and how they follow a VM.
VM networking
Publish a migrated VM’s ports through a LoadBalancer or a Gateway.
Create a project
The project a plan’s VMs land in.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Celum","description":"Operator documentation for Celum — the multi-supervisor Kubernetes management platform.","colors":{"primary":"#4F46E5"},"logo":{"light":"https://mintcdn.com/celum-e0119be0/NF4EBzT06mCbloJe/images/icon-64.png?fit=max\u0026auto=format\u0026n=NF4EBzT06mCbloJe\u0026q=85\u0026s=5cc0f1352d4722abcd86fa910254326e","dark":"https://mintcdn.com/celum-e0119be0/NF4EBzT06mCbloJe/images/icon-64.png?fit=max\u0026auto=format\u0026n=NF4EBzT06mCbloJe\u0026q=85\u0026s=5cc0f1352d4722abcd86fa910254326e"},"favicon":{"light":"https://mintcdn.com/celum-e0119be0/ACqXS6nCknlRGpPb/favicon.svg?fit=max\u0026auto=format\u0026n=ACqXS6nCknlRGpPb\u0026q=85\u0026s=4b83e2c8a80a7dfa346ea4703904d309","dark":"https://mintcdn.com/celum-e0119be0/ACqXS6nCknlRGpPb/favicon.svg?fit=max\u0026auto=format\u0026n=ACqXS6nCknlRGpPb\u0026q=85\u0026s=4b83e2c8a80a7dfa346ea4703904d309"},"navbar":{"links":[]},"icons":{"library":"fontawesome"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"celum-e0119be0","hasAudioNarration":false,"actualSubdomain":"celum-e0119be0","customDomains":["docs.celum.io"],"gitSource":{"type":"github","owner":"celum-dev","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6aecba45759a071fd76fb012","clientVersion":"0.0.4111","searchFilterCounts":[{"language":"default","tag":"API Reference","count":678},{"language":"default","tag":"networking","count":112},{"language":"default","tag":"security","count":91},{"language":"default","tag":"capi","count":83},{"language":"default","tag":"Documentation","count":79},{"language":"default","tag":"platform-settings","count":66},{"language":"default","tag":"vms","count":62},{"language":"default","tag":"storage","count":36},{"language":"default","tag":"projects","count":35},{"language":"default","tag":"iam","count":34}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"svg[id^=\"mermaid\"] .node rect,svg[id^=\"mermaid\"] .node polygon,svg[id^=\"mermaid\"] .node path{fill:rgb(var(--background-light))!important;stroke:rgb(var(--gray-200))!important;stroke-width:1px!important;rx:7.2px;ry:7.2px}svg[id^=\"mermaid\"] .cluster rect{fill:rgb(var(--gray-50))!important;stroke:rgb(var(--gray-200))!important;rx:10.08px;ry:10.08px}svg[id^=\"mermaid\"] .nodeLabel,svg[id^=\"mermaid\"] .edgeLabel,svg[id^=\"mermaid\"] span,svg[id^=\"mermaid\"] p{color:rgb(var(--gray-800))!important;font-size:13px!important}svg[id^=\"mermaid\"] .cluster-label,svg[id^=\"mermaid\"] .cluster span{color:rgb(var(--gray-500))!important;font-size:11px!important;letter-spacing:0.04em;text-transform:uppercase}svg[id^=\"mermaid\"] .edgePath path,svg[id^=\"mermaid\"] path.flowchart-link{stroke:rgb(var(--gray-400))!important;stroke-width:1.25px!important}svg[id^=\"mermaid\"] marker path,svg[id^=\"mermaid\"] .marker{fill:rgb(var(--gray-400))!important;stroke:rgb(var(--gray-400))!important}svg[id^=\"mermaid\"] .edgeLabel rect,svg[id^=\"mermaid\"] .edgeLabel foreignObject div{background:rgb(var(--background-light))!important;fill:rgb(var(--background-light))!important}.dark svg[id^=\"mermaid\"] .node rect,.dark svg[id^=\"mermaid\"] .node polygon,.dark svg[id^=\"mermaid\"] .node path{fill:rgb(var(--gray-900))!important;stroke:rgb(var(--gray-700))!important}.dark svg[id^=\"mermaid\"] .cluster rect{fill:rgb(var(--gray-950))!important;stroke:rgb(var(--gray-800))!important}.dark svg[id^=\"mermaid\"] .nodeLabel,.dark svg[id^=\"mermaid\"] .edgeLabel,.dark svg[id^=\"mermaid\"] span,.dark svg[id^=\"mermaid\"] p{color:rgb(var(--gray-100))!important}.dark svg[id^=\"mermaid\"] .cluster-label,.dark svg[id^=\"mermaid\"] .cluster span{color:rgb(var(--gray-400))!important}.dark svg[id^=\"mermaid\"] .edgePath path,.dark svg[id^=\"mermaid\"] path.flowchart-link{stroke:rgb(var(--gray-500))!important}.dark svg[id^=\"mermaid\"] marker path,.dark svg[id^=\"mermaid\"] .marker{fill:rgb(var(--gray-500))!important;stroke:rgb(var(--gray-500))!important}.dark svg[id^=\"mermaid\"] .edgeLabel rect,.dark svg[id^=\"mermaid\"] .edgeLabel foreignObject div{background:rgb(var(--gray-950))!important;fill:rgb(var(--gray-950))!important}"}],"page":{"pagePath":"vms/migrate-from-vsphere","slug":"/vms/migrate-from-vsphere","pageMetadata":{"title":"Migrate VMs from vSphere","sidebarTitle":"Migrate from vSphere","description":"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM's address.","icon":"truck","href":"/vms/migrate-from-vsphere"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM’s address.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Card,CardGroup,Frame,Heading,Note,OptimizedImage,Tab,Table,Tabs,Warning}=_components;if(!Card)_missingMdxReference(`Card`,true);if(!CardGroup)_missingMdxReference(`CardGroup`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`By the end of this page, VMs that ran in your vCenter run as KubeVirt VMs in a project on a supervisor, and you have checked that they arrived. Celum drives `,_jsx(_components.a,{href:`https://github.com/kubev2v/forklift`,children:`Forklift`}),` for the move: Forklift copies each VM’s disks, and virt-v2v converts the guest to run on KVM unless you ask for the disks as they are.`]}),`\n`,_jsxs(_components.p,{children:[`Only vSphere is a source in this release, and only through a vCenter. Celum declares every source to Forklift as a vCenter (`,_jsx(_components.code,{children:`sdkEndpoint: vcenter`}),`), so a standalone ESXi host cannot be a source, and Celum refuses an ESXi host’s address (see `,_jsx(_components.a,{href:`#step-3--add-a-source`,children:`Step 3`}),`). oVirt, OpenStack, Hyper-V and OVA appear in the form as “Not in this release”.`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-this-changes`,children:`What this changes`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`On the supervisor.`}),` Turning migration on installs Forklift (`,_jsx(_components.code,{children:`konveyor-forklift/virt-forklift`}),`), the NetworkAttachmentDefinition CRD if it is missing, four admission policies, and one Cilium policy (`,_jsx(_components.code,{children:`celum-forklift-v2v`}),`) that lets Forklift reach its conversion pods inside isolated projects. The admission policies act only in namespaces labelled `,_jsx(_components.code,{children:`k8s-gate/migration-target`}),`; creating a plan sets that label on the plan’s project namespace. Talos nodes need no change: the conversion does not need user namespaces.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`In the project.`}),` The migrated VMs and their disks, as ordinary Celum VMs of that project.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`In vCenter.`}),` Celum reads the inventory. When a plan runs, each source VM is shut down — a cold plan at its start, a warm plan at cutover — and `,_jsx(_components.strong,{children:`stays off in vCenter`}),`. A warm plan also takes snapshots of the source VM while it copies.`]}),`\n`,_jsx(Heading,{level:`2`,id:`before-you-start`,children:`Before you start`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`An onboarded supervisor`}),` with KubeVirt, CDI, cert-manager and Flux, and a Kubernetes version that serves `,_jsx(_components.code,{children:`admissionregistration.k8s.io/v1`}),` MutatingAdmissionPolicy (GA in 1.36). If any of these is missing, turning migration on is refused with `,_jsx(_components.code,{children:`409`}),`, and the card links to the onboarding step that installs it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The Secret Store onboarding step`}),`, if you register the vCenter for the platform (step 2). The credential lives in the secret store and reaches the supervisor through External Secrets.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`The cluster agent chart 1.30.462 or later`}),` on the supervisor. The plan wizard reads the vCenter inventory through it; with an older agent it cannot list VMs.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A registry.`}),` Forklift’s images (about 5.6 GB) are copied into the supervisor’s registry when migration is turned on.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`A VDDK image`}),`, `,_jsx(_components.code,{children:`vddk:\u003cversion>`}),`, in the supervisor’s registry, for warm migration, for copying disks as they are, and for the fastest copy. VDDK is VMware’s Virtual Disk Development Kit, licensed by Broadcom, which you load into the registry yourself. A Celum appliance installed from a 1.314 OVA or later carries `,_jsx(_components.a,{href:`https://github.com/openvddk/openvddk`,children:`OpenVDDK`}),`, an independent Apache-2.0 drop-in for it, as `,_jsx(_components.code,{children:`vddk:0.7.4`}),`, and new sources take it by default. Updating an older appliance in place does not add it. Without a VDDK, a source can still use virt-v2v over HTTPS (step 3).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`vCenter reachable over HTTPS`}),` (`,_jsx(_components.code,{children:`/sdk`}),`) from the supervisor. For a warm migration, `,_jsx(_components.strong,{children:`Changed Block Tracking (CBT)`}),` enabled on the VMs. To keep a VM’s address, `,_jsx(_components.strong,{children:`VMware Tools`}),` running in the guest, so vCenter reports the address.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Permissions`}),`, listed under `,_jsx(_components.a,{href:`#permissions`,children:`Permissions`}),`.`]}),`\n`]}),`\n`,_jsx(Note,{children:_jsx(_components.p,{children:`This page does not list the privileges the vCenter account needs. Forklift’s own documentation for the vSphere provider is the reference for them.`})}),`\n`,_jsx(Heading,{level:`2`,id:`the-shape-of-it`,children:`The shape of it`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Turn migration on → register the vCenter → add a source → build a plan → run it → verify.`}),` The first three are done once per supervisor; a plan is one wave of VMs.`]}),`\n`,_jsx(Heading,{level:`2`,id:`step-1-—-turn-vm-migration-on-for-the-supervisor`,children:`Step 1 — Turn VM migration on for the supervisor`}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard`,children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Migrations`}),`. While migration is off, the page shows `,_jsx(_components.strong,{children:`VM migration is off on this supervisor`}),`, with what it installs, its prerequisites, and `,_jsx(_components.strong,{children:`VMs transferred at once`}),` (1–200, default 20). `,_jsx(_components.strong,{children:`Enable VM migration`}),` starts at once, without a confirmation; it reads “Copying images…” while Forklift’s images are copied into the supervisor’s registry.`]})}),_jsx(Tab,{title:`API`,id:`api`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /api/supervisors/{name}/migration/enable`}),` with `,_jsx(_components.code,{children:`{\"maxVMInflight\": 20}`}),`. `,_jsx(_components.code,{children:`GET /api/supervisors/{name}/migration/status`}),` reports the components.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`enable_vm_migration`}),`, and `,_jsx(_components.code,{children:`get_component_status`}),` with `,_jsx(_components.code,{children:`component=migration`}),`.`]})})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Result:`}),` the `,_jsx(_components.strong,{children:`Forklift`}),` tile reads 6/6, “components up · destination ready”, and the `,_jsx(_components.strong,{children:`VM migration on this supervisor`}),` card lists every component ready.`]}),`\n`,_jsx(Frame,{caption:`Migrations with Forklift running and two sources ready`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ee66b8ad2c75282cbf62d9c0c6984a8e`,alt:`The Migrations page with tiles for plans, VMs migrated, sources and Forklift 6/6, the Sources tab listing two vSphere sources with verified TLS, a VDDK image and state ready, and the VM migration on this supervisor card with Re-apply and Disable buttons and every Forklift component ready`,\"data-og-width\":`1980`,width:`1980`,\"data-og-height\":`1820`,height:`1820`,\"data-path\":`images/migrations/migrations-sources.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=33218c703e9de3950dbe5bd136f2668e 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=b0c43c3d9127671d65d29f121985dd5a 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=e29c4793e47350fdeaad91fbffebba8c 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=fb8e406f1bf44a8a3024b0991e10eda6 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=83c4d6ace0f58d3d9c728926ebe98630 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/migrations-sources.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=4c3536eda02c0440a9cc5a70aa4504b1 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`step-2-—-register-the-vcenter-for-the-platform`,children:`Step 2 — Register the vCenter for the platform`}),`\n`,_jsx(_components.p,{children:`Register a vCenter once, and every supervisor’s sources (and Cluster API) can use it. Celum pins its certificate, tests the login, and keeps the user and password only in the secret store.`}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard-2`,children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Settings → vCenters → Add vCenter`}),`: Name, Address, `,_jsx(_components.strong,{children:`Load from vCenter`}),` (reads its certificate), User, Password, CA certificate, an optional description, then `,_jsx(_components.strong,{children:`Verify and add`}),`. A row’s menu offers `,_jsx(_components.strong,{children:`Edit or rotate password`}),`, `,_jsx(_components.strong,{children:`Load the certificate again`}),` and `,_jsx(_components.strong,{children:`Remove`}),`.`]})}),_jsx(Tab,{title:`API`,id:`api-2`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /api/vcenters`}),` with `,_jsx(_components.code,{children:`name`}),`, `,_jsx(_components.code,{children:`server`}),`, `,_jsx(_components.code,{children:`username`}),`, `,_jsx(_components.code,{children:`password`}),`, `,_jsx(_components.code,{children:`caPem`}),` and `,_jsx(_components.code,{children:`description`}),`. `,_jsx(_components.code,{children:`GET /api/vcenters`}),` lists them; `,_jsx(_components.code,{children:`PUT`}),` and `,_jsx(_components.code,{children:`DELETE /api/vcenters/{name}`}),` change and remove one.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp-2`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`create_vcenter`}),`, `,_jsx(_components.code,{children:`register_vcenter_from_cluster_api`}),`, `,_jsx(_components.code,{children:`update_vcenter`}),`, `,_jsx(_components.code,{children:`probe_vsphere_certificate`}),`, `,_jsx(_components.code,{children:`list_vcenters`}),` and `,_jsx(_components.code,{children:`get_vcenter`}),`. No tool removes a vCenter.`]})})]}),`\n`,_jsx(Frame,{caption:`Settings → vCenters: the certificate is pinned and the credential is in the secret store`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=93fa746f9b949158ce3cbecb7c8a68af`,alt:`The vCenters tab of Settings with one registered vCenter, its address, user, a pinned certificate with days left and its SHA-1 fingerprint, and the credential shown as in secret store with when the login was last tested`,\"data-og-width\":`2048`,width:`2048`,\"data-og-height\":`1230`,height:`1230`,\"data-path\":`images/migrations/settings-vcenters.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=e20cd6544fb687d9ffe7fd81e805fc90 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=897349414e15d4fe99d3634c1e547341 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=a95437d36a61d4a1a2b1821db6f5e696 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=774734dcd87ac1d742b3feee1fb8b7c1 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=2ca5779fb1b5a9933bd18814944a9561 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/settings-vcenters.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=bcd8ac84ce0d213ff4a75629e49d1de3 2500w`})}),`\n`,_jsxs(_components.p,{children:[`Registering a vCenter, or rotating its password, refuses an ESXi host’s address with the same message as a source does (see `,_jsx(_components.a,{href:`#step-3--add-a-source`,children:`Step 3`}),`).`]}),`\n`,_jsx(_components.p,{children:`You can skip this step and type a vCenter’s address and credentials straight into a source. Registering it keeps one copy of the credential, which every source then reads.`}),`\n`,_jsx(Heading,{level:`2`,id:`step-3-—-add-a-source`,children:`Step 3 — Add a source`}),`\n`,_jsx(_components.p,{children:`A source is the vCenter that VMs are migrated from, as Forklift sees it.`}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard-3`,children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Migrations → Sources → Add source`}),`. Source type `,_jsx(_components.strong,{children:`vSphere`}),`. For the vCenter, choose `,_jsx(_components.strong,{children:`A registered vCenter`}),`, `,_jsx(_components.strong,{children:`This supervisor’s vCenter`}),` (the one Cluster API uses), or `,_jsx(_components.strong,{children:`Another vCenter`}),` with its address, user, password and CA certificate. Name the source (a DNS label; plans refer to it by name) and pick the `,_jsx(_components.strong,{children:`VDDK image`}),`, or `,_jsx(_components.strong,{children:`None — virt-v2v copies over HTTPS`}),`. `,_jsx(_components.strong,{children:`Add source`}),` saves it.`]})}),_jsx(Tab,{title:`API`,id:`api-3`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /api/supervisors/{name}/migration/providers`}),` with `,_jsx(_components.code,{children:`name`}),`, `,_jsx(_components.code,{children:`type: \"vsphere\"`}),`, and one of `,_jsx(_components.code,{children:`vcenter`}),` (a registered one), `,_jsx(_components.code,{children:`useSupervisorVCenter`}),`, or `,_jsx(_components.code,{children:`url`}),`, `,_jsx(_components.code,{children:`user`}),`, `,_jsx(_components.code,{children:`password`}),` and `,_jsx(_components.code,{children:`caCert`}),`. Optional: `,_jsx(_components.code,{children:`insecureSkipVerify`}),`, and `,_jsx(_components.code,{children:`vddkImage`}),` (`,_jsx(_components.code,{children:`\"none\"`}),` for no VDDK). `,_jsx(_components.code,{children:`GET`}),` lists the sources, `,_jsx(_components.code,{children:`DELETE .../providers/{provider}`}),` removes one, `,_jsx(_components.code,{children:`PUT .../providers/{provider}/vcenter`}),` switches it to a registered vCenter, and `,_jsx(_components.code,{children:`POST .../providers/{provider}/register-vcenter`}),` registers its vCenter for the platform.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp-3`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`create_migration_source`}),`, `,_jsx(_components.code,{children:`list_migration_sources`}),`, `,_jsx(_components.code,{children:`use_vcenter_for_migration_source`}),`, `,_jsx(_components.code,{children:`register_vcenter_from_migration_source`}),`, and `,_jsx(_components.code,{children:`get_migration_source_inventory`}),` to read its VMs, networks and datastores. No tool removes a source.`]})})]}),`\n`,_jsx(Frame,{caption:`Add source, taking the vCenter registered in Settings`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=9fa916d4ce59401240bec9511893e9a5`,alt:`The Add source drawer with vSphere selected, the choice between a registered vCenter, this supervisor's vCenter and another vCenter, the source name, the registered vCenter with its pinned certificate, and the VDDK image`,\"data-og-width\":`1088`,width:`1088`,\"data-og-height\":`2200`,height:`2200`,\"data-path\":`images/migrations/add-source.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ade2267e96bc9cd52572672f1c5542bd 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=61d8c95ccbaa843c8afa6ab7e02e0c4d 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=43ac58ebe57b97dd32fd085bc1c0ebd2 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=8f72ce01a70eb6d9a8ad0e88d6ebcd0b 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=59a4ac3f7399f94191a3a08e6fc63fa8 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/add-source.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=f4b20e8c99cd39a678178b3b070b57af 2500w`})}),`\n`,_jsx(_components.p,{children:`Celum tests the login before it saves the source, and it refuses three sources that would only fail later, during a run:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`An ESXi host.`}),` Celum asks the address what it is before it sends the password, and refuses an ESXi host with “`,_jsx(_components.code,{children:`\u003chost>`}),` is an ESXi host, not a vCenter — give the address of the vCenter that manages it”. It makes this check also when `,_jsx(_components.strong,{children:`Skip TLS verification`}),` is on.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`No CA and no `,_jsx(_components.code,{children:`insecureSkipVerify`}),`.`]}),` TLS is verified, so the source needs the CA the vCenter’s certificate chains to.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`No VDDK and TLS still verified.`}),` Without VDDK, virt-v2v copies the disks with curl, which ignores the CA, and the run would fail at conversion with `,_jsx(_components.code,{children:`curl error 60`}),`. Use a VDDK image, or accept `,_jsx(_components.code,{children:`insecureSkipVerify`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Result:`}),` the source’s row shows TLS `,_jsx(_components.strong,{children:`verified`}),` and state `,_jsx(_components.strong,{children:`ready`}),`. `,_jsx(_components.strong,{children:`New plan`}),` stays disabled until at least one source is ready.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Changing a source makes Forklift read its whole vCenter inventory again.`}),` A run copying from that source at that moment can fail. Change a source between runs, not during one.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`step-4-—-build-a-plan`,children:`Step 4 — Build a plan`}),`\n`,_jsx(_components.p,{children:`A plan names the VMs to move, the source, the project they land in, and how their networks, addresses and disks map. It holds at most 500 VMs.`}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard-4`,children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Migrations → Plans → New plan`}),`, or `,_jsx(_components.strong,{children:`Workloads → New workload → Import from another platform`}),`. The wizard has seven steps: `,_jsx(_components.strong,{children:`Source \u0026 target`}),`, `,_jsx(_components.strong,{children:`VMs`}),`, `,_jsx(_components.strong,{children:`Networks`}),`, `,_jsx(_components.strong,{children:`Addresses`}),`, `,_jsx(_components.strong,{children:`Storage`}),`, `,_jsx(_components.strong,{children:`Migration type`}),`, `,_jsx(_components.strong,{children:`Review`}),`.`]})}),_jsx(Tab,{title:`API`,id:`api-4`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /api/supervisors/{name}/migration/plans`}),` with `,_jsx(_components.code,{children:`name`}),`, `,_jsx(_components.code,{children:`source`}),`, `,_jsx(_components.code,{children:`targetNamespace`}),`, `,_jsx(_components.code,{children:`vms`}),`, `,_jsx(_components.code,{children:`networks`}),` and `,_jsx(_components.code,{children:`storage`}),`. Optional: `,_jsx(_components.code,{children:`description`}),`, `,_jsx(_components.code,{children:`type`}),` (`,_jsx(_components.code,{children:`cold`}),`, the default, or `,_jsx(_components.code,{children:`warm`}),`), `,_jsx(_components.code,{children:`conversion`}),` (`,_jsx(_components.code,{children:`full`}),`, the default, `,_jsx(_components.code,{children:`raw-virtio`}),` or `,_jsx(_components.code,{children:`raw-compatibility`}),`), `,_jsx(_components.code,{children:`convertorNode`}),`, `,_jsx(_components.code,{children:`targetPowerState`}),` (`,_jsx(_components.code,{children:`on`}),`, `,_jsx(_components.code,{children:`off`}),`, or empty for the source VM’s state), `,_jsx(_components.code,{children:`preserveStaticIPs`}),`, `,_jsx(_components.code,{children:`identityNetwork`}),`, `,_jsx(_components.code,{children:`addresses`}),`, and `,_jsx(_components.code,{children:`start`}),` to start it as soon as it is ready. `,_jsx(_components.code,{children:`GET /api/supervisors/{name}/migration/landing?namespace=`}),` reads what the project offers.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp-4`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`create_migration_plan`}),`, with `,_jsx(_components.code,{children:`get_migration_source_inventory`}),` and `,_jsx(_components.code,{children:`get_migration_landing`}),` to fill it in.`]})})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Source \u0026 target.`}),` The source, the `,_jsx(_components.strong,{children:`Target project`}),`, a `,_jsx(_components.strong,{children:`Plan name`}),` (a DNS label of at most 55 characters, such as `,_jsx(_components.code,{children:`erp-wave-3`}),`), and an optional description. The project’s namespace is where the VMs land; they become that project’s VMs.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`VMs.`}),` The source’s VMs, with their power state, OS, size and `,_jsx(_components.strong,{children:`Concerns`}),`. vSphere Cluster Services (vCLS) agent VMs are not listed. The wizard will not go on with a VM whose name or MAC address is already in use on the supervisor, a VM with a critical concern, or a VM with more than one NIC on the pod network; in a warm plan, also a VM without CBT or with shared disks. vSAN needs VDDK.`]}),`\n`,_jsx(Frame,{caption:`VMs: pick the ones this wave moves`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ab31e97441dd1f08cbc8eeeaf60ad4a7`,alt:`The VMs step of New migration plan, searching the source's 212 VMs, with one Ubuntu VM chosen, its power state, size and number of concerns`,\"data-og-width\":`1344`,width:`1344`,\"data-og-height\":`1250`,height:`1250`,\"data-path\":`images/migrations/plan-vms.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ff7d300198d0dea7c1e8d62a95f8bddd 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=e54b47209d13119ff6d345cda19a9786 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=f6760f3eda7e39023c153e66ca0a78b3 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=0faf17873156ed688810bf0f7bfefb0a 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=e489ac3f22247c9834ddf9afac412922 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-vms.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=6928ac7b1ce3f8924e7fab2f28a4ff1d 2500w`})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Networks.`}),` Each vCenter network the chosen VMs use goes to the `,_jsx(_components.strong,{children:`Pod network`}),` or is ignored; a NIC on an ignored network is dropped. The pod network is masquerade, as for every Celum VM: the guest takes its address by DHCP. Mapping a network to a VLAN of its own is not offered yet.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Addresses.`}),` A VM can keep the address VMware Tools reports for it, inside a subnet declared adoptable: it becomes the VM’s identity address, a routed /32 that follows it through live migration. The address is claimed only once that VM’s migration has succeeded. The other VMs get the pod address only, or an address from the project’s pool. Keeping addresses needs `,_jsx(_components.code,{children:`cilium:Apply`}),`, a NIC on the pod network, and cannot be combined with `,_jsx(_components.strong,{children:`Preserve static IPs`}),`. Hosts still on the source subnet reach a kept address only once that subnet is extended (see `,_jsx(_components.a,{href:`#reach-moved-vms-from-the-source-network`,children:`Reach moved VMs from the source network`}),`), or once its gateway answers ARP for it.`]}),`\n`,_jsx(Frame,{caption:`Addresses: keep the address the guest had`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ed623a74f6e2bfeb8cc1d2272afee42e`,alt:`The Addresses step with a VM, the address VMware Tools reports, Keep that address chosen as its address here, and the other VMs getting the pod address only`,\"data-og-width\":`1344`,width:`1344`,\"data-og-height\":`1280`,height:`1280`,\"data-path\":`images/migrations/plan-addresses.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=d61eeaff732143f54c1b15ba2f8d484c 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=6012bb8228225cbdda12d5042980c257 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=4bcff0ca7d5f5d21f0bd5d9ffe2e10e5 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=8eddf3370721ab2df808321c4111f0cd 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=5da301703ec537080d8b57e3920d6f2e 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-addresses.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=acbaf545e42b6a1b6a71795e4561afd3 2500w`})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Storage.`}),` Each datastore maps to a StorageClass. A VM keeps live migration between the supervisor’s nodes only on a class whose volumes are ReadWriteMany.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Migration type.`})}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Choice`}),_jsx(_components.th,{children:`What it does`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Cold`})}),_jsx(_components.td,{children:`Each VM is shut down, copied, converted and started here. It is down for the whole copy.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Warm`})}),_jsx(_components.td,{children:`Copied while it runs, then the changed blocks again until cutover. It is down only for the last delta and the conversion. Needs VDDK and CBT.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Convert`}),` (default)`]}),_jsx(_components.td,{children:`virt-v2v installs virtio drivers and the guest agent and removes VMware Tools. Most of a warm cutover’s downtime.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Copy as is · virtio`})}),_jsx(_components.td,{children:`Disks copied unchanged, with a virtio disk and NIC. Boots only a guest that already has virtio drivers; no guest agent. Needs VDDK.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Copy as is · compatibility`})}),_jsx(_components.td,{children:`Disks copied unchanged, with a SATA disk and an e1000e NIC, which most guests have drivers for. Slow disk and network; no guest agent. Needs VDDK.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Conversion runs on`})}),_jsx(_components.td,{children:`The node that copies and converts each disk: the one with the faster path to the ESXi hosts, if one has it. It must run KubeVirt VMs, not be cordoned, and have no NoSchedule or NoExecute taint.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Power state after migration`})}),_jsx(_components.td,{children:`As before, On, or Off.`})]})]})]}),`\n`,_jsx(Frame,{caption:`Migration type: cold or warm, and whether the guest is converted`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=8d269bd8c62c2c028f62434cef505762`,alt:`The Migration type step with Cold and Warm, the guest conversion choices Convert, Copy as is virtio and Copy as is compatibility, the node conversion runs on, and the power state after migration`,\"data-og-width\":`1344`,width:`1344`,\"data-og-height\":`1480`,height:`1480`,\"data-path\":`images/migrations/plan-migration-type.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=27d1bed86f0d21b46099947f4d93f54a 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=d40ae58d7238d7f83fd76eaaad431aad 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=2be90335994e5bf7b2717a4bf74ef666 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=b66051bc76ba3ad6dec8bdbb074225fd 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=80e9983d0330d5c8feff00a4f8b3c6ce 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-migration-type.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=47be1844792096d52afdbe0792658b9b 2500w`})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Review.`}),` The plan as it will be created, and what it does to the source: each VM is shut down in vCenter before its disks are copied and stays off there. `,_jsx(_components.strong,{children:`Create plan`}),` creates it; `,_jsx(_components.strong,{children:`Create and start`}),` also starts it as soon as Forklift has validated it (with VDDK that includes a check job, which can take a minute). Neither asks again.`]}),`\n`,_jsx(Frame,{caption:`Review, with the warning about the source VMs`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=6fb326b31b59492fd0da406bb6d094e2`,alt:`The Review step listing the plan's name, source, project, type, guest conversion, VMs, networks, addresses and datastores, a warning that the source VMs will be shut down, and the buttons Create plan and Create and start`,\"data-og-width\":`1344`,width:`1344`,\"data-og-height\":`1540`,height:`1540`,\"data-path\":`images/migrations/plan-review.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=a593936e9eacd3c6c0653493401cf672 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=9cf7367117eb782e7145ed3b8425330a 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=2e601af6cb6557ca7016a7ba835f6437 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=e23633fa75045514127785269f6aa859 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=49a5dbddae6acb2e865c52c1ec5d3e0f 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-review.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ba73b1320e178b0e7fe0adb0d2a86a73 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`step-5-—-run-it`,children:`Step 5 — Run it`}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard-5`,children:_jsxs(_components.p,{children:[`The plan’s page, from `,_jsx(_components.strong,{children:`Migrations → Plans`}),`. `,_jsx(_components.strong,{children:`Start`}),` (or `,_jsx(_components.strong,{children:`Retry`}),`) runs it. A warm plan adds `,_jsx(_components.strong,{children:`Cut over now`}),`, and `,_jsx(_components.strong,{children:`Schedule cutover…`}),` in the overflow menu. `,_jsx(_components.strong,{children:`Cancel the run`}),` stops it. Each of these asks for confirmation, except scheduling a cutover.`]})}),_jsx(Tab,{title:`API`,id:`api-5`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`POST /api/supervisors/{name}/migration/plans/{plan}/start`}),`, `,_jsx(_components.code,{children:`.../cutover`}),` with an optional `,_jsx(_components.code,{children:`{\"at\": \"\u003cRFC 3339 time>\"}`}),`, `,_jsx(_components.code,{children:`.../cancel`}),` with an optional `,_jsx(_components.code,{children:`{\"vms\": [...]}`}),`. Cancelling single VMs is API only; the dashboard cancels the whole run. `,_jsx(_components.code,{children:`GET .../plans/{plan}`}),` reads the plan, its runs and each VM’s progress.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp-5`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`start_migration_plan`}),`, `,_jsx(_components.code,{children:`cutover_migration_plan`}),`, `,_jsx(_components.code,{children:`get_migration_plan`}),` and `,_jsx(_components.code,{children:`list_migration_plans`}),`. No tool cancels a run.`]})})]}),`\n`,_jsx(_components.p,{children:`The plan’s page follows each VM through Forklift’s steps — Initialize, DiskTransfer, Cutover, ImageConversion, VirtualMachineCreation — with when each started and how long it took. A warm VM lists its precopies; a converted VM lists virt-v2v’s own phases. The page refreshes every 5 seconds while a run is going.`}),`\n`,_jsx(Frame,{caption:`A finished warm migration: every step with its duration, the precopies, and the whole run`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=1d42f84101f8cfaf3f8b03b7bc19a901`,alt:`A plan's page for a succeeded warm migration: VMs migrated 1 of 1, none failed, disks copied 100%, and the VM's steps Initialize, DiskTransfer, Cutover, ImageConversion with virt-v2v and virt-customize phases, VirtualMachineCreation and the final snapshot consolidation, each marked done with its duration, then two precopies and the cutover-to-done and whole-run times`,\"data-og-width\":`2048`,width:`2048`,\"data-og-height\":`2040`,height:`2040`,\"data-path\":`images/migrations/plan-run.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=2044f356e32cb0e20b0486e4bb8207ef 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=1fb3397459ea108f047a85a08585689f 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=79704f03e1c86d111acf8d11883a57cc 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ad4f80c09f15cbeed15c4c77993389c6 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=a52c303c97ee9460309000b5f1fad8b6 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-run.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=9bcb5db8face0186de38f20d837a51ad 2500w`})}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Progress counts each disk’s full size.`}),` VDDK reads only the blocks a disk has allocated, so the bytes actually moved, and the copy’s rate, are not shown, and the time left on a sparse disk can be well off. For orientation, on Celum’s own test bed: a copy with VDDK ran at about 150 MiB/s, and a warm cutover that kept the VM’s address took the VM away for about 2 minutes for Ubuntu and 6–7 minutes for Windows.`]})}),`\n`,_jsxs(_components.p,{children:[`A plan is `,_jsx(_components.strong,{children:`validating`}),`, `,_jsx(_components.strong,{children:`needs attention`}),`, `,_jsx(_components.strong,{children:`ready`}),`, `,_jsx(_components.strong,{children:`running`}),`, `,_jsx(_components.strong,{children:`succeeded`}),`, `,_jsx(_components.strong,{children:`failed`}),`, `,_jsx(_components.strong,{children:`canceled`}),` or `,_jsx(_components.strong,{children:`archived`}),`. `,_jsx(_components.strong,{children:`Mappings`}),` shows where each network and datastore went, and each VM’s identity address with its state.`]}),`\n`,_jsx(Frame,{caption:`Mappings: networks, datastores, and the address each VM kept`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=d22f0f49be582d816c2b2004492ffae1`,alt:`The Mappings tab of a plan: a vCenter network mapped to the pod network, a datastore mapped to a StorageClass, and the VM with keeps its source address, its address and state done`,\"data-og-width\":`2048`,width:`2048`,\"data-og-height\":`1200`,height:`1200`,\"data-path\":`images/migrations/plan-mappings.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=d2b760a515315e39a12d07007f7a5322 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=6c23d0e542ef1815597982751e9d4c0d 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=c1a2d0b93df7a9d8925ef28eed6f66aa 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=23fee52ab4ed2ee6ac44a6a33daa628f 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=a7fb7acc707a0876e332daf1c4843bd9 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/plan-mappings.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=d5ee1f0c7abf0e33b29b746940345a9f 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`reach-moved-vms-from-the-source-network`,children:`Reach moved VMs from the source network`}),`\n`,_jsxs(_components.p,{children:[`A VM that kept its address has left its source subnet. Hosts that stay behind in that subnet reach it again only when the subnet is `,_jsx(_components.strong,{children:`extended`}),`: an ARP-proxy appliance, a small VM on the source VLAN, answers for exactly the addresses that moved and hands their traffic to the subnet’s own gateway, which routes each one to the supervisor. Nothing on the fabric changes. It bridges a migration in progress: move the whole subnet as soon as you can, retire the source environment, then remove the hybrid subnet.`]}),`\n`,_jsxs(Tabs,{children:[_jsx(Tab,{title:`Dashboard`,id:`dashboard-6`,children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Migrations → Network extension`}),`. `,_jsx(_components.strong,{children:`Mapping`}),` lists the vCenter networks, the subnets their guests report, and how many hosts are still at the source. `,_jsx(_components.strong,{children:`ARP-proxy appliances`}),` has `,_jsx(_components.strong,{children:`Declare hybrid subnet`}),` and `,_jsx(_components.strong,{children:`Deploy ARP-proxy appliance`}),`.`]})}),_jsx(Tab,{title:`API`,id:`api-6`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`GET`}),`, `,_jsx(_components.code,{children:`POST /api/supervisors/{name}/networking/hybrid-subnets`}),`, and `,_jsx(_components.code,{children:`PUT`}),`, `,_jsx(_components.code,{children:`DELETE .../hybrid-subnets/{subnet}`}),`. `,_jsx(_components.code,{children:`PUT .../networking/vm-identity-adoptable`}),` declares which subnets’ addresses may be kept.`]})}),_jsx(Tab,{title:`MCP`,id:`mcp-6`,children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`list_hybrid_subnets`}),`, `,_jsx(_components.code,{children:`create_hybrid_subnet`}),`, `,_jsx(_components.code,{children:`update_hybrid_subnet`}),`, `,_jsx(_components.code,{children:`remove_hybrid_subnet`}),`, `,_jsx(_components.code,{children:`deploy_hybrid_subnet_appliance`}),`, `,_jsx(_components.code,{children:`get_hybrid_subnet_appliance_deployment`}),`, `,_jsx(_components.code,{children:`list_hybrid_subnet_appliances`}),`, `,_jsx(_components.code,{children:`rotate_hybrid_subnet_appliance_token`}),`, `,_jsx(_components.code,{children:`set_vm_identity_adoptable`}),`.`]})})]}),`\n`,_jsx(Frame,{caption:`Network extension → Mapping: how many networks keep their addresses, and how many are extended`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=3753a6035f6115dfc48c573a20102bbf`,alt:`The Mapping view of Network extension with counts of vCenter networks with VMs, networks whose addresses are kept, addresses adopted by migrated VMs, and kept networks that are extended`,\"data-og-width\":`1990`,width:`1990`,\"data-og-height\":`560`,height:`560`,\"data-path\":`images/migrations/network-extension.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=20cc70a8e666626995a520887dcf9bd6 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=75d69510a5bbae4b8a1a32fd10cc7eae 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=000ce2f7bdf2f7dd4c22fc4db51fe2e5 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=75084e958d66f76347747c43416eddd2 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=7321d26505f50ce0e246fd4c89f1297e 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/network-extension.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ed3795e596f883fa6cb13eb38f275068 2500w`})}),`\n`,_jsx(Frame,{caption:`ARP-proxy appliances: a hybrid subnet answering for every migrated address`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=db4d0464344f2807c41f866d5d7f068d`,alt:`The ARP-proxy appliances view with one hybrid subnet, its gateway and port group, one of one appliances answering, and three of three migrated addresses answered`,\"data-og-width\":`1990`,width:`1990`,\"data-og-height\":`680`,height:`680`,\"data-path\":`images/migrations/arp-proxy.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=280\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=ff48dacb71d813ee93b44f182ea1e9b1 280w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=560\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=79dc168db2f683b961c918d561360c4b 560w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=840\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=f8893e7d0ea7066ba7bb8a45bd7a82c9 840w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=1100\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=f564be3e464c0a583e065791012ab031 1100w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=1650\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=2171b1728fe97aba30b93c9b06ed7cf6 1650w, https://mintcdn.com/celum-e0119be0/6q56BAvBU9lKvSVc/images/migrations/arp-proxy.png?w=2500\u0026fit=max\u0026auto=format\u0026n=6q56BAvBU9lKvSVc\u0026q=85\u0026s=eb5d8dce63517637cc87e0cd2c45c05d 2500w`})}),`\n`,_jsx(Heading,{level:`2`,id:`verify`,children:`Verify`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The plan reads `,_jsx(_components.strong,{children:`succeeded`}),`, and `,_jsx(_components.strong,{children:`VMs migrated`}),` counts every VM of the latest run.`]}),`\n`,_jsxs(_components.li,{children:[`Each VM is in `,_jsx(_components.strong,{children:`Workloads`}),`, in the plan’s project, running (unless you chose Off).`]}),`\n`,_jsx(_components.li,{children:`A converted VM shows its guest agent connected. A copied-as-is VM has no guest agent, by design.`}),`\n`,_jsxs(_components.li,{children:[`A VM that kept its address shows it on `,_jsx(_components.strong,{children:`Mappings`}),` as `,_jsx(_components.strong,{children:`done`}),`, and answers on it. From a host left in the source subnet, it answers only once that subnet is extended.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`if-you-need-to-undo-it`,children:`If you need to undo it`}),`\n`,_jsx(_components.p,{children:`There is no reverse migration. The source VM is still in vCenter, powered off: power it back on there to return to it.`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Cancel the run`}),` powers back on the VMs Forklift shut down, removes a warm plan’s snapshot, and removes what the run had built on the supervisor.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Retry`}),` runs again only the VMs that did not get across. A plan that succeeded cannot be run again.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Archive`}),` cleans up what failed and canceled VMs left behind.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Delete`}),` removes the plan. It never touches the VMs that migrated.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Disable`}),` on the `,_jsx(_components.strong,{children:`VM migration on this supervisor`}),` card removes Forklift’s sources, their credentials and the plans, and leaves the CRDs. It is refused with `,_jsx(_components.code,{children:`409`}),` while a run is going; `,_jsx(_components.strong,{children:`Disable anyway…`}),` overrides that. It never touches migrated VMs.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`Removing a source, cancelling, archiving or deleting a plan, disabling migration and removing a vCenter have no MCP tool: they are left to a person on purpose. Use the dashboard or the API.`}),`\n`,_jsx(Heading,{level:`2`,id:`what-commonly-goes-wrong`,children:`What commonly goes wrong`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Symptom`}),_jsx(_components.th,{children:`Cause`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Enable VM migration`}),` answers `,_jsx(_components.code,{children:`409`})]}),_jsx(_components.td,{children:`A prerequisite is missing on the supervisor; the message names it, and the card links to its onboarding step.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`New plan`}),` is greyed out`]}),_jsx(_components.td,{children:`No source is ready yet.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A source is refused with “no CA for …”`}),_jsxs(_components.td,{children:[`Paste the CA the vCenter’s certificate chains to, use a registered vCenter, or accept `,_jsx(_components.code,{children:`insecureSkipVerify`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`A source without VDDK is refused with `,_jsx(_components.code,{children:`curl error 60`})]}),_jsxs(_components.td,{children:[`Without VDDK the copy ignores the CA. Use a VDDK image, or accept `,_jsx(_components.code,{children:`insecureSkipVerify`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The wizard lists no VMs`}),_jsx(_components.td,{children:`The cluster agent on the supervisor is older than chart 1.30.462.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`The wizard will not let a VM through`}),_jsx(_components.td,{children:`Its name or MAC is already used on the supervisor, it has a critical concern, it has more than one NIC on the pod network, or (warm) it has no CBT or has shared disks.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A run stops at ImageConversion with 0%`}),_jsxs(_components.td,{children:[`The conversion pod in an isolated project is unreachable: the `,_jsx(_components.code,{children:`celum-forklift-v2v`}),` policy is missing. `,_jsx(_components.strong,{children:`Re-apply`}),` on the migration card restores it, and every `,_jsx(_components.strong,{children:`Start`}),` applies it again.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A run failed while a source was being changed`}),_jsxs(_components.td,{children:[`Changing a source re-reads its inventory. Change sources between runs, then `,_jsx(_components.strong,{children:`Retry`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[`A Windows guest does not boot after `,_jsx(_components.strong,{children:`Copy as is`})]}),_jsxs(_components.td,{children:[`A stock Windows guest has no virtio drivers, and one installed on PVSCSI may not boot from SATA either. Use `,_jsx(_components.strong,{children:`Convert`}),`.`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`A converted Windows VM takes minutes longer to come up`}),_jsx(_components.td,{children:`Services set to Automatic (Delayed Start) add about two minutes to its first boot.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`Disable`}),` answers `,_jsx(_components.code,{children:`409`})]}),_jsxs(_components.td,{children:[`A run is going. Let it finish or cancel it, or use `,_jsx(_components.strong,{children:`Disable anyway…`}),`.`]})]})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`permissions`,children:`Permissions`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Task`}),_jsx(_components.th,{children:`Action`}),_jsx(_components.th,{children:`KRN`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Read migration’s state`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`migration:GetStatus`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`krn:celum:supervisor:\u003cname>:migration:*`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Turn migration on / off`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`migration:Enable`}),`, `,_jsx(_components.code,{children:`migration:Disable`})]}),_jsx(_components.td,{children:`same`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`List, add, change, remove sources`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`migration:ListProviders`}),`, `,_jsx(_components.code,{children:`migration:CreateProvider`}),`, `,_jsx(_components.code,{children:`migration:UpdateProvider`}),`, `,_jsx(_components.code,{children:`migration:DeleteProvider`})]}),_jsx(_components.td,{children:`same`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Read a source’s inventory`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`migration:ReadInventory`})}),_jsx(_components.td,{children:`same`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`List and create plans`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`migration:ListPlans`}),`, `,_jsx(_components.code,{children:`migration:CreatePlan`})]}),_jsx(_components.td,{children:`same`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Read, start, cut over, cancel, archive, delete a plan`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`migration:GetPlan`}),`, `,_jsx(_components.code,{children:`migration:StartPlan`}),`, `,_jsx(_components.code,{children:`migration:CutoverPlan`}),`, `,_jsx(_components.code,{children:`migration:CancelPlan`}),`, `,_jsx(_components.code,{children:`migration:ArchivePlan`}),`, `,_jsx(_components.code,{children:`migration:DeletePlan`})]}),_jsx(_components.td,{children:_jsx(_components.code,{children:`krn:celum:supervisor:\u003cname>:migration:\u003cplan>`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Use a registered vCenter in a source`}),_jsx(_components.td,{children:_jsx(_components.code,{children:`vcenter:Use`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`krn:celum:vcenter:\u003cvcenter>`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Register and manage vCenters`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`vcenter:List`}),`, `,_jsx(_components.code,{children:`vcenter:Create`}),`, `,_jsx(_components.code,{children:`vcenter:Get`}),`, `,_jsx(_components.code,{children:`vcenter:Update`}),`, `,_jsx(_components.code,{children:`vcenter:Delete`})]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`krn:celum:vcenter:*`}),` or `,_jsx(_components.code,{children:`krn:celum:vcenter:\u003cvcenter>`})]})]})]})]}),`\n`,_jsxs(_components.p,{children:[`Three checks happen inside a request rather than on its route: `,_jsx(_components.strong,{children:`Create and start`}),` also needs `,_jsx(_components.code,{children:`migration:StartPlan`}),`; keeping addresses needs `,_jsx(_components.code,{children:`cilium:Apply`}),`; and `,_jsx(_components.strong,{children:`Load from vCenter`}),` needs `,_jsx(_components.code,{children:`capi:Install`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`next`,children:`Next`}),`\n`,_jsxs(CardGroup,{cols:2,children:[_jsx(Card,{title:`VM lifecycle`,icon:`rotate`,href:`/vms/lifecycle`,children:_jsx(_components.p,{children:`Start, stop, resize and live-migrate the VMs you just moved.`})}),_jsx(Card,{title:`VM identity pools`,icon:`location-dot`,href:`/networking/vm-identity-pools`,children:_jsx(_components.p,{children:`The addresses migrated VMs keep, and how they follow a VM.`})}),_jsx(Card,{title:`VM networking`,icon:`network-wired`,href:`/vms/networking`,children:_jsx(_components.p,{children:`Publish a migrated VM’s ports through a LoadBalancer or a Gateway.`})}),_jsx(Card,{title:`Create a project`,icon:`folder-tree`,href:`/get-started/create-a-project`,children:_jsx(_components.p,{children:`The project a plan’s VMs land in.`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Migrate VMs from vSphere","sidebarTitle":"Migrate from vSphere","description":"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM's address.","icon":"truck","href":"/vms/migrate-from-vsphere"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What this changes","slug":"what-this-changes","depth":2,"children":[]},{"title":"Before you start","slug":"before-you-start","depth":2,"children":[]},{"title":"The shape of it","slug":"the-shape-of-it","depth":2,"children":[]},{"title":"Step 1 — Turn VM migration on for the supervisor","slug":"step-1-—-turn-vm-migration-on-for-the-supervisor","depth":2,"children":[]},{"title":"Step 2 — Register the vCenter for the platform","slug":"step-2-—-register-the-vcenter-for-the-platform","depth":2,"children":[]},{"title":"Step 3 — Add a source","slug":"step-3-—-add-a-source","depth":2,"children":[]},{"title":"Step 4 — Build a plan","slug":"step-4-—-build-a-plan","depth":2,"children":[]},{"title":"Step 5 — Run it","slug":"step-5-—-run-it","depth":2,"children":[]},{"title":"Reach moved VMs from the source network","slug":"reach-moved-vms-from-the-source-network","depth":2,"children":[]},{"title":"Verify","slug":"verify","depth":2,"children":[]},{"title":"If you need to undo it","slug":"if-you-need-to-undo-it","depth":2,"children":[]},{"title":"What commonly goes wrong","slug":"what-commonly-goes-wrong","depth":2,"children":[]},{"title":"Permissions","slug":"permissions","depth":2,"children":[]},{"title":"Next","slug":"next","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"celum-e0119be0","siteName":"Celum","title":"Migrate VMs from vSphere - Celum","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-01T23:04:22.024Z","originalFileLocation":"vms/migrate-from-vsphere.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM\u0026#x27;s address.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Celum\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Migrate VMs from vSphere - Celum\">\u003cmeta data-mint-head property=\"og:description\" content=\"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM\u0026#x27;s address.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Celum\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.celum.io/vms/migrate-from-vsphere\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://celum-e0119be0.mintlify.site/_mintlify/api/og/v2?division=Virtual+machines\u0026amp;title=Migrate+VMs+from+vSphere\u0026amp;description=Move+VMs+from+VMware+vCenter+into+a+supervisor+with+Forklift%3A+turn+migration+on%2C+register+the+vCenter%2C+add+a+source%2C+build+a+plan%2C+run+it+cold+or+warm%2C+and+keep\u0026amp;theme=b18dc9aec4cff6709b68009f\u0026amp;signature=7270cebc01483dd4fb5de0fa736f8829bed3c19e5cc5f45bd0467886af4ca8a1\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Migrate VMs from vSphere - Celum\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM\u0026#x27;s address.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://celum-e0119be0.mintlify.site/_mintlify/api/og/v2?division=Virtual+machines\u0026amp;title=Migrate+VMs+from+vSphere\u0026amp;description=Move+VMs+from+VMware+vCenter+into+a+supervisor+with+Forklift%3A+turn+migration+on%2C+register+the+vCenter%2C+add+a+source%2C+build+a+plan%2C+run+it+cold+or+warm%2C+and+keep\u0026amp;theme=b18dc9aec4cff6709b68009f\u0026amp;signature=7270cebc01483dd4fb5de0fa736f8829bed3c19e5cc5f45bd0467886af4ca8a1\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/celum-e0119be0/8ykZiPODj77OBFTN/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Celum\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#4F46E5\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.celum.io/vms/migrate-from-vsphere\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/vms/migrate-from-vsphere.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.celum.io/#organization\",\"name\":\"Celum\",\"url\":\"https://docs.celum.io\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/celum-e0119be0/NF4EBzT06mCbloJe/images/icon-64.png?fit=max\u0026auto=format\u0026n=NF4EBzT06mCbloJe\u0026q=85\u0026s=5cc0f1352d4722abcd86fa910254326e\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.celum.io#website\",\"name\":\"Celum\",\"url\":\"https://docs.celum.io\",\"publisher\":{\"@id\":\"https://docs.celum.io/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.celum.io/vms/migrate-from-vsphere#webpage\",\"url\":\"https://docs.celum.io/vms/migrate-from-vsphere\",\"name\":\"Migrate VMs from vSphere\",\"description\":\"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM's address.\",\"dateModified\":\"2026-11-01T23:04:22.024Z\",\"isPartOf\":{\"@id\":\"https://docs.celum.io#website\"},\"breadcrumb\":{\"@id\":\"https://docs.celum.io/vms/migrate-from-vsphere#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.celum.io/vms/migrate-from-vsphere#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Virtual machines\",\"item\":\"https://docs.celum.io/vms/image-library\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Migrate VMs from vSphere\",\"item\":\"https://docs.celum.io/vms/migrate-from-vsphere\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.celum.io/vms/migrate-from-vsphere#article\",\"headline\":\"Migrate VMs from vSphere\",\"name\":\"Migrate VMs from vSphere\",\"description\":\"Move VMs from VMware vCenter into a supervisor with Forklift: turn migration on, register the vCenter, add a source, build a plan, run it cold or warm, and keep each VM's address.\",\"url\":\"https://docs.celum.io/vms/migrate-from-vsphere\",\"mainEntityOfPage\":{\"@id\":\"https://docs.celum.io/vms/migrate-from-vsphere#webpage\"},\"dateModified\":\"2026-11-01T23:04:22.024Z\",\"publisher\":{\"@id\":\"https://docs.celum.io/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.celum.io#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Celum\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Celum\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/vms/migrate-from-vsphere.md","siteName":"Celum","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get Started","pages":[{"title":"Introduction","icon":"hand-wave","href":"/get-started/introduction"},{"title":"Deploy the appliance on vCenter","sidebarTitle":"Deploy the appliance","icon":"server","href":"/get-started/deploy-the-appliance"},{"title":"Quickstart","icon":"rocket","href":"/get-started/quickstart"},{"title":"Authentication \u0026 IAM","icon":"key","href":"/get-started/authentication"},{"title":"Register a supervisor","icon":"plug","href":"/get-started/register-a-supervisor"},{"title":"Platform onboarding","icon":"layer-group","href":"/get-started/platform-onboarding"},{"title":"Create a project","icon":"folder-tree","href":"/get-started/create-a-project"},{"title":"Run a VM","icon":"server","href":"/get-started/run-a-vm"},{"title":"Add a disk to a VM","icon":"hard-drive","href":"/get-started/add-a-disk"},{"title":"Publish it on a public name","icon":"globe","href":"/get-started/publish-it"},{"title":"Live-migrate a VM","icon":"shuffle","href":"/get-started/live-migrate"},{"title":"See what is talking to what","icon":"circle-nodes","href":"/get-started/see-the-traffic"},{"title":"Lock it down with a policy","icon":"file-shield","href":"/get-started/lock-it-down"},{"title":"Delegate to a team","icon":"users","href":"/get-started/delegate-to-a-team"}]},{"group":"Concepts","pages":[{"title":"Architecture","icon":"sitemap","href":"/concepts/architecture"},{"title":"Supervisors \u0026 clusters","icon":"layer-group","href":"/concepts/supervisors-and-clusters"},{"title":"Projects","icon":"folder-tree","href":"/concepts/projects"},{"title":"Permissions model","icon":"shield-halved","href":"/concepts/permissions-model"},{"title":"Celum AI and MCP","icon":"robot","href":"/concepts/celum-ai"}]},{"group":"Clusters","icon":"circle-nodes","pages":[{"title":"Clusters overview","icon":"circle-nodes","href":"/clusters/overview"},{"title":"Create a cluster","icon":"circle-plus","href":"/clusters/create"},{"title":"Cluster templates","icon":"copy","href":"/clusters/templates"},{"title":"Day-2 operations","icon":"gauge-high","href":"/clusters/day-2-operations"},{"title":"Hosted control planes","icon":"boxes-stacked","href":"/clusters/hosted-control-planes"},{"title":"Access \u0026 credentials","icon":"key","href":"/clusters/access-and-credentials"},{"title":"Troubleshooting clusters","icon":"bug","href":"/clusters/troubleshooting"}]},{"group":"GitOps \u0026 Apps","icon":"code-branch","pages":[{"title":"GitOps \u0026 Apps overview","icon":"code-branch","href":"/gitops/overview"},{"title":"App catalog","icon":"box-open","href":"/gitops/app-catalog"},{"title":"Repositories \u0026 manifests","icon":"code-commit","href":"/gitops/repositories-and-manifests"},{"title":"Charts \u0026 the mirror","icon":"magnifying-glass","href":"/gitops/charts"},{"title":"Registries","icon":"box","href":"/gitops/registries"},{"title":"Registry mirroring in depth","sidebarTitle":"Registry mirroring","icon":"copy","href":"/gitops/registry-mirroring"}]},{"group":"Virtual machines","icon":"server","pages":[{"title":"Image library","icon":"compact-disc","href":"/vms/image-library"},{"title":"Create a VM","icon":"circle-plus","href":"/vms/create"},{"title":"VM lifecycle","icon":"rotate","href":"/vms/lifecycle"},{"title":"VM networking","icon":"network-wired","href":"/vms/networking"},{"title":"VM storage \u0026 disks","icon":"hard-drive","href":"/vms/storage"},{"title":"Console \u0026 access","icon":"terminal","href":"/vms/console-and-access"},{"title":"Guest customisation templates","description":"Reusable cloud-init and sysprep templates — a saved boot script with declared variables, rendered into a VM at create time.","href":"/vms/guest-customisation-templates"},{"title":"Migrate VMs from vSphere","sidebarTitle":"Migrate from vSphere","icon":"truck","href":"/vms/migrate-from-vsphere"}]},{"group":"Networking","icon":"network-wired","pages":[{"title":"Networking overview","description":"The engine model behind a supervisor's network — CNI, BGP, and north-south — and how the Networking page organizes pools, BGP, egress, gateways, and routes.","icon":"network-wired","href":"/networking/overview"},{"title":"Project networking","icon":"diagram-project","href":"/networking/project-networking"},{"title":"Pools \u0026 IPAM","icon":"chart-pie","href":"/networking/pools-and-ipam"},{"title":"VM identity pools","icon":"id-card","href":"/networking/vm-identity-pools"},{"title":"BGP \u0026 Egress","icon":"route","href":"/networking/bgp-and-egress"},{"title":"Gateways \u0026 Routes","icon":"globe","href":"/networking/gateways-and-routes"},{"title":"DNS","icon":"globe","href":"/networking/dns"}]},{"group":"Security","icon":"shield-halved","pages":[{"title":"Security overview","icon":"shield-halved","href":"/security/overview"},{"title":"Topology","icon":"circle-nodes","href":"/security/topology"},{"title":"Flow analytics","icon":"chart-simple","href":"/security/flow-analytics"},{"title":"Forensics","icon":"magnifying-glass-chart","href":"/security/forensics"},{"title":"Network policies","icon":"file-shield","href":"/security/policies"},{"title":"Pipeline \u0026 runtime","icon":"radio","href":"/security/pipeline-and-runtime"},{"title":"DNS views","icon":"radar","href":"/security/dns-views"},{"title":"PQC Readiness","icon":"atom","href":"/security/pqc-readiness"}]},{"group":"Platform Health","icon":"heart-pulse","pages":[{"title":"Platform health overview","icon":"heart-pulse","href":"/platform-health/overview"},{"title":"Supervisor overview","icon":"gauge","href":"/platform-health/supervisor-overview"},{"title":"Monitoring","icon":"chart-line","href":"/platform-health/monitoring"},{"title":"Certificates","icon":"lock","href":"/platform-health/certificates"},{"title":"Logs","icon":"file-lines","href":"/platform-health/logs"},{"title":"Flow telemetry","icon":"wave-square","href":"/platform-health/flow-telemetry"},{"title":"Infrastructure \u0026 nodes","icon":"server","href":"/platform-health/infrastructure"},{"title":"Slack notifications","icon":"bell","href":"/platform-health/slack-notifications"}]},{"group":"Storage","icon":"hard-drive","pages":[{"title":"Storage overview","icon":"hard-drive","href":"/storage/overview"},{"title":"The Storage tab","icon":"stethoscope","href":"/storage/storage-tab"},{"title":"Storage performance","icon":"gauge-high","href":"/storage/performance"},{"title":"LINSTOR","icon":"layer-group","href":"/storage/linstor"},{"title":"Rook-Ceph","icon":"database","href":"/storage/rook-ceph"},{"title":"NFS \u0026 Fibre Channel","icon":"plug","href":"/storage/nfs-and-fibre-channel"},{"title":"Classes \u0026 profiles","icon":"layer-group","href":"/storage/classes-and-profiles"},{"title":"PVCs \u0026 snapshots","icon":"box-archive","href":"/storage/pvcs-and-snapshots"}]},{"group":"Reference","icon":"book","pages":[{"title":"Permissions","icon":"list-check","href":"/reference/permissions"},{"title":"Environment variables","icon":"sliders","href":"/reference/environment-variables"},{"title":"Appliance configuration","icon":"sliders","href":"/reference/appliance-configuration"},{"title":"Onboarding options","icon":"table-list","href":"/reference/onboarding-options"},{"title":"Glossary","icon":"book","href":"/reference/glossary"}]},{"group":"Administration","icon":"sliders","pages":[{"title":"Settings","href":"/administration/settings"},{"title":"Audit log","href":"/administration/audit-log"},{"title":"Deletion approvals","href":"/administration/deletion-approvals"}]}]},{"tab":"API Reference","pages":[{"title":"API Reference","href":"/api-reference/ai-assistant/aichat"}]}]},"basePath":"","title":"Migrate VMs from vSphere - Celum","buildId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","deploymentId":"dpl_DqYu5MPb49gWBBbUGgpHQUmCHY3P","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-u3J1-UOn.js","DynamicMarkdown-B-f2cqXQ.js","zoom-image-lightbox-DTFzvaXJ.js","lightbox-handle-r17bVUz3.js"]}