Назад | Перейти на главную страницу

Резервное копирование контейнера LXD на другой хост LXD

У меня есть два сервера A и B, на которых работает Ubuntu 16.04 и файловая система RAID1 ZFS для LXD. На данный момент на сервере A работает несколько контейнеров. Теперь я хочу делать ночные резервные копии из каждого контейнера на сервере A на сервер B. Таким образом я хочу иметь возможность запускать контейнер на сервере B в случае сбоя сервера A. Я также могу использовать локальные снимки на сервере A, чтобы очень быстро восстановить контейнер, например, если кто-то случайно удалит файлы.

Самый простой способ - остановить контейнер C на сервере A, сделать снимок Snap0 и запустить его снова. Затем используйте lxc copy C/Snap0 serverB:C чтобы скопировать снимок на сервер B, предполагая, что я уже добавил сервер B в качестве удаленного хоста на сервер A. Проблема в том, что это работает только в первый раз. Для другой резервной копии мне пришлось бы удалить контейнер C на сервере B, прежде чем я смогу скопировать его снова. И вторая проблема заключается в том, что контейнер увеличивается от резервной копии к резервной, и в конечном итоге на сервер B нужно передать так много данных, что у всех работающих на нем служб будет недостаточная пропускная способность.

Поэтому решением этой проблемы должно быть только перенос различий между ночными снимками. Этого можно добиться с помощью zfs send/receive который вместе с ssh может отправлять различия между снимками на сервере A на сервер B через ssh, а затем добавлять эти различия в файловую систему сервера B. Но опять проблема. Это не сработает, если я создал исходную файловую систему контейнера C, используя lxc copy потому что эта команда не использует zfs send/receive внутренне, но создает новую файловую систему на сервере B, которая, в свою очередь, имеет контрольную сумму, отличную от исходной файловой системы на сервере A. Таким образом, дифференциальное резервное копирование невозможно и zfs receive вернется с ошибкой при сравнении контрольных сумм файловых систем.

Моя следующая идея - использовать исключительно zfs send/receive передать всю файловую систему контейнера C с сервера A на сервер B без создания контейнера, используя lxc copy/init. После этого не составит труда посылать различия между двумя последовательными снимками каждую ночь, потому что контрольные суммы совпадают. Но есть проблема в том, что я не могу запустить копию контейнера C на сервере B в случае возникновения чрезвычайной ситуации, потому что в базе данных LXD, расположенной по адресу /var/lib/lxd/lxd.db, так lxc start C не будет работать. Думаю, я могу просто скопировать соответствующие записи из базы данных LXD сервера A в базу данных LXD сервера B, чтобы заставить ее работать, но я не уверен в этом. Может ты сможешь мне помочь здесь. Я не хочу ничего разрушать в этих базах данных.

Некоторая справочная информация: на самом деле оба сервера A и B работают с контейнерами, но каждый сервер должен содержать резервные копии контейнеров другого сервера.

Возможно, уже существует работающая стратегия резервного копирования с использованием двух или более хостов LXD, но я не смог ее найти. Там только rsync-как стратегии резервного копирования или копии всего контейнера каждую ночь.

Обновить: Я только что получил намек на это github commit который реализует новую подкоманду для команды lxd, а именно lxd import. Поэтому мне нужно было обновить lxd на обоих серверах, используя backports Ubuntu, используя apt-get install -t xenial-backports lxd lxd-client.

Никто не должен иметь возможность импортировать контейнер из существующей файловой системы. Я попробовал. Сначала перейдите на сервер A и сделайте снимок

lxc snapshot C Snap0

Отправьте снимок на сервер B, используя zfs send/receive используя дополнительный аргумент -p на сайте отправителя, чтобы также включить свойства файловой системы.

zfs send -p lxd/containers/C@snapshot-Snap0 | ssh serverB zfs receive lxd/containers/C

Переключитесь на сервер B и сделайте символическую ссылку:

ln -s /var/lib/lxd/containers/C.zfs /var/lib/lxd/containers/C

И теперь я могу импортировать:

lxd import C

Но вместо этого я получаю сообщение об ошибке:

error: open /var/lib/lxd/containers/C/backup.yaml: no such file or directory

Потому что я не знаю где это backup.yaml файл должен исходить я попытался скопировать существующий metadata.yawl к backup.yaml. После другой попытки я получаю эту ошибку:

error: no response!

И теперь я понятия не имею, что делать, потому что нет совета, где это backup.yaml должен исходить из.

Обновление 2: Как уже упоминалось в пузыре, можно получить это backup.yaml файл либо остановив и снова запустив контейнер, либо просто сделав еще один снимок после обновления до lxc 2.7+.

Итак, наконец, мой сценарий наконец-то работает нормально. Осталась только одна небольшая проблема. После импорта контейнера с lxc import Больше не могу удалить, не разрушив всю файловую систему контейнера. Я думаю о такой команде, как lxc import --update <container> или lxc delete --keep-root-fs или похожие. Я уже отправил запрос на добавление функции по этой идее.

Обновление 3: А вот и прогресс: Улучшение обработки резервного копирования LXD # 3005

Николас

Я обнаружил ту же проблему, с которой сталкиваетесь вы. В моем тесте мне нужно обновить lxd 2.0.8 до 2.7 и остановить lxc (который был создан или запущен из 2.0.x), затем снова запустить lxc, вы увидите backup.yaml и можете скопировать его в место назначения для используйте импорт lxd (перед импортом не забудьте установить zfs точку монтирования и создать имя контейнера ссылки на точку монтирования)

Надеюсь на эту помощь.