У меня есть два сервера 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 точку монтирования и создать имя контейнера ссылки на точку монтирования)
Надеюсь на эту помощь.