TL;DR

ZVOL = block device: dd if=/dev/zvol/pool/vol of=vm.raw. Snapshot first if the VM is running.

On Proxmox a VM disk on ZFS is a ZVOL (rpool/data/vm-101-disk-0), not a file. To copy it to another hypervisor or a USB stick, dump a RAW.

Thread: Import/convert/export RAW images to ZFS volume.

Snapshot and dd

If the VM is running, freeze the disk with a snapshot and read the snap (the @snap ZVOL shows up under /dev/zvol/…):

1
2
3
zfs snapshot rpool/data/vm-101-disk-0@export
dd if=/dev/zvol/rpool/data/vm-101-disk-0@export of=/mnt/backup/vm-101.raw bs=1M status=progress
zfs destroy rpool/data/vm-101-disk-0@export

VM off, you can read the live zvol:

1
dd if=/dev/zvol/rpool/data/vm-101-disk-0 of=/mnt/backup/vm-101.raw bs=1M status=progress

bs=1M matters: the 512 B default takes forever.

qemu-img (qcow2 / vmdk)

1
qemu-img convert -p -f raw -O qcow2 /mnt/backup/vm-101.raw /mnt/backup/vm-101.qcow2

Or straight from the zvol:

1
qemu-img convert -p -f raw -O qcow2 /dev/zvol/rpool/data/vm-101-disk-0 vm-101.qcow2

The other way (RAW → ZVOL)

1
2
zfs create -s -V 32G rpool/data/vm-101-disk-0
dd if=file.raw of=/dev/zvol/rpool/data/vm-101-disk-0 bs=1M status=progress

-s = sparse. The RAW must not be larger than the zvol.

See also: basic commands.