Клонирование Linux с сервера на сервер

План работ

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

  1. создать файловый архив всей ФС root и каталога EFI, вместе с файлами устройств, процессов и пр.
  2. загрузиться в диска liveCD, разбить целевые диски на разделы
  3. смонтировать эти разделы во временные папки на liveCD
  4. распаковать архивы, созданные на шаге 1 в соответствующие папки
  5. зайти в chroot-окружение только что созданной копии ОС и произвести установку загрузчика ОС.
  6. выйти из chroot-окружения, отмонтировать все каталоги
  7. загрузиться с новых дисков

Создание архива ФС

Есть два варианта создания копии текущей ОС на сервере Linux:

  1. загрузиться с liveCD, подмонтировать root-раздел и системные каталоги, а затем сделать архив системы
  2. сделать архив текущей системы не перезагружаясь - прямо из “боевой” системы.

Более интересен именно второй вариант, который и будет рассмотрен далее. Сначала смонтируем текущий root-раздел во временный каталог:

mkdir /mnt/current /data
mount --bind / /mnt/current
Когда система Linux загружается, она создает некоторые виртуальные файловые системы, которые нет смысла копировать, т.к. они отражают специфику конкретного оборудования данного сервера.
К таким каталогам относятся /dev, /sys, /proc, /run.
При монтировании с ключом “–bind” мы имеем доступ к файлам загрузочного раздела сразу из двух точек монтирования, что нам и надо.

Теперь, когда у нас есть смонтированная файловая система root, мы можем начать архив нашего образа. Нам надо сохранить содержимое корневой файловой системы (за исключением специальных файловых систем, таких как /dev) в tar-архив:

tar --exclude '/data/*' -C /mnt/current -c . > /data/source-fs.tar
Флаг -C (--directory) указывает tar на использование каталога /mnt/current в качестве объекта для архивирования с исходной точкой без префикса /mnt/current.
То есть, в архив будет попадать путь сразу из корня этого каталога, что нам и надо.
Ключ -c переводит tar в режим создания архива.
Опция --exclude указывает, что не надо архивировать любые файлы из каталога /opt - это исключает попадание в целевой архив нашего итогового архивного файла source-fs.tar

Далее, отмонтируем root-каталог и удалим все лог-файлы:

umount /mnt/current
cd /data
tar tf source-fs.tar --wildcards ./var/log/*{.gz,.log,.1,.xz} --wildcards ./var/log/journal/*.*  --wildcards ./var/log/installer/* --wildcards ./var/log/{syslog,faillog,lastlog,debug,wtmp} | tar --delete -f source-fs.tar -T -

Дополнение liveCD

Теперь, когда у нас есть архив эталонной системы, необходимо включить его в состав загрузочного LiveCD диска.
Тогда мы сможем установить полную копию ОС на новом “чистом” сервере даже не имея доступа к сети.
Для этого берем последнюю версию Debian LiveCD, необязательно совпадающую с нашей версией ОС (Debian 11.7). В принципе можно использовать даже не Debian, а любую другую версию debian-like Linux для нашей аппаратной платформы (amd64).
Лучше всего взять образ минимального размера, чтобы загрузка по IPMI-сети занимала меньше времени.

Для начала надо установить необходимое ПО и распаковать iso-файл:

apt install -y xorriso squashfs-tools cdrkit-utils bsdtar libarchive-tools syslinux-common
mkdir -p /home/debian/iso/extract
cd /home/debian/iso
wget https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-12.2.0-amd64-standard.iso
xorriso -osirrox on -indev debian-live-12.2.0-amd64-standard.iso -extract / extract
ls -l extract/
Или с помощью утилиты bsdtar:

cd extract
bsdtar -xf ../debian-live-12.2.0-amd64-standard.iso
Теперь скопируем наш архив в новую папку:

mkdir gpm
cp ../gpm-hv-v01.tar.gz gpm/
После этого необходимо получить файл MBR для загрузчика образа ISO в Legacy-режиме.
При сборке ISO-образа утилита xorriso устанавливает MBR в начале образа ISO. Нам нужно извлечь первые 432 байта исходного ISO в файл на диске и передать этот файл в качестве аргумента для нашей опции -isohybrid-mbr.

dd if=debian-live-12.2.0-amd64-standard.iso of=/usr/lib/syslinux/isohdpfx.bin bs=1 count=432
Запускаем команду для сборки нового ISO-образа с нашим архивом в составе:

xorriso -as mkisofs -isohybrid-mbr /usr/lib/syslinux/isohdpfx.bin -J -joliet-long -c isolinux/boot.cat -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot -isohybrid-gpt-basdat -o gpm-d11-livecd-v3.iso extract

Восстановление ОС из архива на целевой сервер

Теперь необходимо загрузиться с нашего кастомного liveCD и восстановить систему из архива.
Сначала разбиваем диски на нужные разделы и собираем mdadm RAID-1. Монтируем ФС root на раздел созданного RAID.

mount /dev/md127 /opt/root
mount /dev/nvme0n1p1 /opt/efi
Далее, необходимо распаковать архив на целевой раздел /opt/root:

cd /run/livecd/medium/gpm/
tar -xvf source-fs.tar -C /opt/root .
Монтируем наш EFI-раздел внутрь новой root ФС:

mount --bind /opt/efi /opt/root/boot/efi

Подготовка к загрузке с нового раздела

Далее, все операции выполняются в среде chroot.
Сначала монтируем все служебные ФС, затем надо пропатчить файл /etc/fstab - записать в него правильные идентификаторы ФС:

for mp in /dev /dev/pts /proc /sys /run; do mount --bind $mp /opt/root${mp}; done
chroot /opt/root /bin/bash --login
## patch fstab
sed -i '/errors/d' /etc/fstab
sed -i '/vfat/d' /etc/fstab
#md_uuid=$(blkid /dev/md127 | awk '{print $2}' | tr -d '"')
echo -e "/dev/nvme0n1p1\t/boot/efi\tvfat\tumask=0077\t0\t1" >> /etc/fstab
echo -e $(blkid /dev/md127 | awk '{print $2}' | tr -d '"')"\t/\text4\terrors=remount-ro\t1\t0" >> /etc/fstab

Теперь осталось перегенерировать initramfs и записать загрузчик:

update-initramfs -u
mount -t efivarfs none /sys/firmware/efi/efivars
grub-install /dev/nvme0n1
grub-install /dev/nvme1n1
update-grub
exit
После этого можно перезагрузиться уже с жесткого диска и мы попадаем в свежеустановленную ОС.

Обновлено: 01.03.2024