HOWTO migrate LXC containers using old good LVM as backing storage to ZFS storage back-end and safe tons od disk space in process. This guide assumes that you already configured LXC to use ZFS for backend storage and created ZFS pool and dataset for it.It is probably not optimal, i guess it would be simpler just create new ZFS dataset manually and feed it to LXC, but I do not know all inner working of LXC, so I pick a safer path.
- Stop container:
# lxc-stop -n test
- Mount container storage to /mnt. You can get LVM path from lxc.rootfs.path variable in config file for the container /var/lib/lxc/test/config
# mount /dev/mapper/lcxhost--data--vg-test /mnt
root@lcx ~# ls /mnt bin/ boot/ dev/ etc/ home/ lib/ lib64/ lost+found/ media/ mnt/ opt/ proc/ root/ run/ sbin/ selinux/ srv/ sys/ tmp/ usr/ var/
- Create new LXC container to migrate data
# lxc-create -B zfs -n test-new -t debian
root@metaview ~# zfs list NAME USED AVAIL REFER MOUNTPOINT data 207M 724G 192K /data data/lxc 205M 724G 192K /data/lxc data/lxc/test-new 204M 724G 204M /var/lib/lxc/test-new/rootfs
- Mount new root dataset. It will be mounted to /var/lib/lxc/test-new/rootfs
# zfs mount data/lxc/test-new
root@metaview ~# ls /var/lib/lxc/switchmap-new/rootfs/ bin@ boot/ dev/ etc/ home/ lib@ lib32@ lib64@ libx32@ media/ mnt/ opt/ proc/ root/ run/ sbin@ selinux/ srv/ sys/ tmp/ usr/ var/
- Remove everything on mew root dataset. We do not need it
# rm -r /var/lib/lxc/switchmap-new/rootfs/ rm: cannot remove '/var/lib/lxc/switchmap-new/rootfs/': Device or resource busy # root@metaview ~# ls -a /var/lib/lxc/switchmap-new/rootfs/ ./ ../
- Copy data from old container to new dataset
# cp -av /mnt/* /var/lib/lxc/test-new/rootfs
root@metaview ~# ls /var/lib/lxc/switchmap-new/rootfs/ bin/ boot/ dev/ etc/ home/ lib/ lib64/ lost+found/ media/ mnt/ opt/ proc/ root/ run/ sbin/ selinux/ srv/ sys/ tmp/ usr/ var/
- Bit of cleanup
# rmdir /var/lib/lxc/test-new/rootfs/lost+found/
- Unmount everything
# umount /var/lib/lxc/test-new/rootfs/ # umount /tmp
- Check diff between old and new LXC containers and add missing parts to new one. At this stage you also need to sort out IP allocation but it depends on method you are using, so I’m not going to cover it.
# diff /var/lib/lxc/test/config /var/lib/lxc/test-new/config 2,3c2 < # Parameters passed to the template: --release=stretch < # Template script checksum (SHA-1): 2ad4d9cfe8988ae453172bd4fe3b06cf91756168 --- > # Parameters passed to the template: 10a10 > lxc.net.0.hwaddr = 00:16:3e:7f:1f:f0 13,15d12 < lxc.net.0.hwaddr = 00:16:3e:da:7c:69 < lxc.rootfs.path = /dev/mapper/lcxhost--data--vg-test < 17a15,16 > # lxc.bdev.zfs.root=data/lxc > lxc.rootfs.path = zfs:data/lxc/test-new 24c23 < lxc.uts.name = test --- > lxc.uts.name = test-new 26,30c25 < < < lxc.start.auto = 1 < lxc.start.delay = 15 < lxc.start.order = 3000 --- > lxc.pty.max = 1024
As you can see in this particular case I need to add lxc.start.* stuff to config of new container.
- Let’s toss containers around using lxc-copy
- Backup old one
# lxc-copy --name=test --newname=test-old
- Destroy originals
# lxc-destroy test
- Copy new to give it old name.
# lxc-copy --name=test-new --newname=test
- Destroy copy of new
# lxc-destroy test-new
- Backup old one
- Start container with new backend storage.
# lxc-start test