incus-contrib/notes/migration-guide.md

325 lines
9.6 KiB
Markdown

# Migration Guide: Importing Workloads into Incus
This guide covers migrating virtual machines and containers from other
hypervisors into Incus. Each section documents a specific migration path
with tested procedures where available.
All commands tested with Incus 6.21 on IncusOS.
---
## Overview
Incus provides several ways to import workloads:
| Tool | Use case |
|------|----------|
| `incus-migrate` | Official migration tool. Imports disk images, running instances, or physical machines |
| `incus import` | Import from an Incus backup file (`.tar.gz`) |
| `incus storage volume import` | Import a raw/qcow2 disk as a storage volume |
| `qemu-img convert` | Convert between disk formats (vmdk, qcow2, raw, vdi) |
### General migration workflow
1. **Export** the VM disk from the source hypervisor
2. **Convert** the disk to raw or qcow2 format (if needed)
3. **Import** into Incus via `incus-migrate` or manual volume import
4. **Configure** the Incus instance (network, boot, etc.)
5. **Verify** the migrated workload boots and runs correctly
---
## Proxmox VE to Incus
**Status**: documented, can be tested with lab VMs.
### Method 1: Using qemu-img (recommended)
```bash
# 1. Identify the disk on Proxmox
ssh root@proxmox pvesm list local-lvm | grep vm-<VMID>
# 2. Export the VM disk as raw
ssh root@proxmox qm disk export <VMID> scsi0 /tmp/disk.raw --format raw
# 3. Copy to the Incus host
scp root@proxmox:/tmp/disk.raw /tmp/disk.raw
# 4. Import as a storage volume
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
# 5. Create an empty VM
incus init --empty --vm migrated-vm <remote>:
# 6. Attach the imported disk
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
# 7. Configure for boot
incus config set <remote>:migrated-vm security.secureboot=false # if source lacks SB
incus start <remote>:migrated-vm
```
### Method 2: Using incus-migrate
```bash
# On the Incus host (or any machine with access to both)
incus-migrate
# Interactive prompts:
# 1. Select "Import from disk image"
# 2. Point to the exported raw/qcow2 file
# 3. Select target Incus server and storage pool
# 4. Choose VM instance type
```
### Notes
- Proxmox ZFS volumes can be exported with `zfs send` for faster transfer
- LVM-thin volumes: use `qm disk export` (abstracts the LVM details)
- UEFI VMs: ensure the Incus VM is configured with UEFI boot
(`security.secureboot=false` if the source OS lacks Secure Boot support)
- Network: the VM will get a new MAC address in Incus. Update any static
network config inside the VM after migration.
- Guest agent: install `incus-agent` inside the VM after migration for full
management capabilities.
---
## UTM to Incus
**Status**: documented (theoretical). Testable when running on macOS.
UTM stores VMs as `.utm` bundles (directories) containing qcow2 disk images.
### Procedure
```bash
# 1. Locate the UTM VM bundle
ls ~/Library/Containers/com.utmapp.UTM/Data/Documents/*.utm/
# 2. Find the qcow2 disk inside the bundle
ls <vm-name>.utm/Data/*.qcow2
# 3. Convert to raw (if needed)
qemu-img convert -f qcow2 -O raw <vm>.utm/Data/disk.qcow2 /tmp/disk.raw
# 4. Transfer to Incus host (if remote)
scp /tmp/disk.raw user@incus-host:/tmp/
# 5. Import into Incus (same as Proxmox method)
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
incus start <remote>:migrated-vm
```
### Notes
- UTM supports both Apple Virtualization (arm64 only) and QEMU backends.
VMs from the QEMU backend are most compatible with Incus.
- Apple Virtualization VMs use a different format and may not be directly
importable.
- arm64 VMs from UTM can be imported into arm64 Incus hosts.
- x86_64 VMs (via QEMU backend on Intel Macs) can be imported into x86_64
Incus hosts.
---
## VMware Fusion to Incus
**Status**: documented (theoretical). Testable when VMware Fusion is available.
VMware Fusion stores VMs as `.vmwarevm` bundles containing `.vmdk` disk files.
### Procedure
```bash
# 1. Locate the VM bundle
ls ~/Virtual\ Machines.localized/*.vmwarevm/
# 2. Find the VMDK disk
ls <vm-name>.vmwarevm/*.vmdk
# 3. Convert VMDK to raw
qemu-img convert -f vmdk -O raw <vm>.vmwarevm/disk.vmdk /tmp/disk.raw
# 4. Transfer and import into Incus (same workflow)
scp /tmp/disk.raw user@incus-host:/tmp/
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
incus start <remote>:migrated-vm
```
### OVA/OVF export (alternative)
```bash
# VMware Fusion can export VMs as OVA
# File -> Export to OVF...
# Extract VMDK from OVA (OVA is a tar archive)
tar xf machine.ova
ls *.vmdk
# Convert and import as above
qemu-img convert -f vmdk -O raw *.vmdk /tmp/disk.raw
```
### Notes
- Split VMDK files (multiple `.vmdk` files): use `qemu-img` which handles
split VMDK chains automatically.
- VMware Tools: uninstall before migration if possible, or install
`open-vm-tools` equivalent in the guest after migration.
- Network adapter type changes from vmxnet3 to virtio.
---
## Physical Machine to Incus
**Status**: documented. `incus-migrate` supports direct physical-to-virtual.
### Method 1: incus-migrate (recommended)
Run `incus-migrate` directly on the physical machine:
```bash
# On the physical machine (requires root)
sudo incus-migrate
# Interactive prompts guide you through:
# 1. Connect to Incus server
# 2. Select "Migrate this machine"
# 3. Choose instance type (container or VM)
# 4. incus-migrate streams the filesystem/disk to Incus
```
### Method 2: Disk image capture
```bash
# 1. Create a disk image from the physical machine
sudo dd if=/dev/sda of=/tmp/disk.raw bs=4M status=progress
# 2. Transfer to Incus host
scp /tmp/disk.raw user@incus-host:/tmp/
# 3. Import as usual
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
```
### Notes
- `incus-migrate` is the cleanest approach for physical machines.
- Disk image capture preserves everything (bootloader, partitions) but
creates very large files. Use compression: `dd | gzip > disk.raw.gz`
- Shrink the disk image after transfer: `qemu-img convert -O raw disk.raw
disk-shrunk.raw` (removes trailing zeros).
- Hardware drivers: the guest may need to regenerate initramfs for the new
virtual hardware (virtio drivers).
---
## Container Migration (Docker/Podman to Incus)
**Status**: documented. Container filesystem import is straightforward.
### Docker to Incus container
```bash
# 1. Export the container filesystem
docker export <container-id> > /tmp/container-fs.tar
# 2. Import into Incus as a container
incus import <remote>: /tmp/container-fs.tar imported-container
# 3. Start
incus start <remote>:imported-container
```
### Podman to Incus container
```bash
# Same approach -- podman export is compatible
podman export <container-id> > /tmp/container-fs.tar
incus import <remote>: /tmp/container-fs.tar imported-container
```
### Docker image to Incus
```bash
# Save image as tar
docker save <image-name> > /tmp/image.tar
# Note: docker save creates an OCI image archive, not a filesystem tar.
# incus import expects a filesystem tar. Use docker export (from a running
# container) instead.
```
### Notes
- Docker containers are typically single-process. Incus containers run a
full init system. The imported container may need an init process
(systemd, openrc) installed.
- Networking: Docker networking doesn't translate. The imported container
gets Incus networking (bridge-based).
- Volumes: Docker volumes are NOT exported with `docker export`. Copy
volume data separately.
- For complex Docker Compose stacks, consider running Docker inside an Incus
VM instead of migrating individual containers.
---
## Disk Format Reference
| Format | Extension | Tools | Notes |
|--------|-----------|-------|-------|
| Raw | `.raw`, `.img` | `dd`, `qemu-img` | No overhead, largest size |
| QCOW2 | `.qcow2` | `qemu-img` | Sparse, snapshots, common in KVM/QEMU |
| VMDK | `.vmdk` | `qemu-img` | VMware format, may be split across files |
| VDI | `.vdi` | `qemu-img` | VirtualBox format |
| VHD/VHDX | `.vhd`, `.vhdx` | `qemu-img` | Hyper-V format |
### Converting between formats
```bash
# QCOW2 to raw
qemu-img convert -f qcow2 -O raw input.qcow2 output.raw
# VMDK to raw
qemu-img convert -f vmdk -O raw input.vmdk output.raw
# Raw to QCOW2 (for storage efficiency)
qemu-img convert -f raw -O qcow2 input.raw output.qcow2
# VDI to raw
qemu-img convert -f vdi -O raw input.vdi output.raw
# Check image info
qemu-img info disk.qcow2
```
---
## Post-Migration Checklist
After importing a workload into Incus:
- [ ] Verify the instance boots and runs correctly
- [ ] Update network configuration (new MAC address, new IP range)
- [ ] Install `incus-agent` inside VMs for full management
- [ ] Remove source-hypervisor-specific tools (VMware Tools, etc.)
- [ ] Regenerate initramfs if hardware changed significantly
- [ ] Update `/etc/fstab` if disk device names changed
- [ ] Test application functionality
- [ ] Set up backups in Incus (`incus export` or snapshots)
---
## References
- [incus-migrate documentation](https://linuxcontainers.org/incus/docs/main/howto/server_migrate/)
- [qemu-img manual](https://www.qemu.org/docs/master/tools/qemu-img.html)
- [Incus import/export](https://linuxcontainers.org/incus/docs/main/howto/instances_backup/)