Бывает, возникает необходимость произвести какие-то серьезные изменения в системе, результат которых неочевиден, либо просто надо посмотреть, к чему это вообще приведет.
Если ваш сервер — это на самом деле виртуальная машина, и вы можете дотянуться до управления ею, то вам повезло, и вы можете создать снапшот, или резервную копию сервера, после чего производить изменения.
Рассмотрим ситуацию, когда у нас нет возможности создать резервную копию виртуалки, либо у нас и не виртуалка вовсе, а нам надо поднять в виртуалке (или не виртуалке) клон.
Работы будем проводить на Ubuntu Linux 12.04.
Идея простая: надо скопировать корневую файловую систему сервера на диск другой машины, прописать загрузчик и поднять клон.
Итак, поехали.
На машине, которая будет у нас клоном, грузимся с livecd того дистибутива, который установлен на исходной машине. По большому счету, не принципиально какого именно дистрибутива. Но лучше, все же, того самого.
Вариантов копирования контента может быть несколько. Начиная с подключения диска будущего клона (назовем его destination) к исходному серверу (назовем его source), и копирования всего локально, заканчивая копированием данных по сети. Я остановлюсь на варианте копирования по сети, когда инициатором копирования является исходный сервер. Для этого способа необходимо, чтобы с source был доступен по сети destination.
Работать непосредственно в консоли загруженной с livecd системы не совсем удобно. Лучше подключиться удаленно, и работать в терминале в комфортных условиях. Убеждаемся, что destination доступен по сети, на destination открываем терминал, ставим openssh-server, выставляем пользователю ubuntu пароль:
sudo apt-get update sudo apt-get install openssh-server sudo passwd ubuntu
Смотрим, какой у destination ip:
ifconfig | grep "inet addr"
Теперь мы можем подключиться к нашей системе удаленно с source:
ssh ubuntu@destination_ip
Переносить данные будем при помощи rsync. Для того, чтобы корректно передать аттрибуты файлов, копировать будем из-под рута. Зададим руту на destination пароль, после чего передадим на destination публичный ключ, чтобы организовать беспарольный вход.
На destination задаем пароль:
sudo passwd root
Передаем с source на destination публичный ssh-ключ. Говорим из-под пользователя root на source:
ssh-copy-id destination_ip
Если пара ключей на исходном сервере отсутствует, ее надо сгенерировать, после чего повторить попытку передачи ключа:
ssh-keygen ssh-copy-id destination_ip
Теперь при заходе на destination по ssh нам не придется вводить пароль.
Все дальнейшие действия на обеих системах выполняем из-под рута.
Смотрим на source, как и какие файловые системы у нас подмонтированы
root@ServerSource:~# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/SYSTEM-ROOT 14G 1.9G 12G 15% / udev 487M 4.0K 487M 1% /dev tmpfs 199M 228K 199M 1% /run none 5.0M 0 5.0M 0% /run/lock none 498M 0 498M 0% /run/shm /dev/sda1 236M 94M 130M 42% /boot
Видим, что настоящих файловых систем всего две: собственно корневая и /boot. Остальные файловые системы виртуальные.
Далее, смотрим, как у нас монтируется своп:
root@ServerSource:~# grep swap /etc/fstab /dev/mapper/SYSTEM-SWAP none swap sw 0 0
Своп располагается в LVM-томе /dev/mapper/SYSTEM-SWAP. Смотрим его размер:
root@ServerSource:~# lvscan ACTIVE '/dev/SYSTEM/SWAP' [1.86 GiB] inherit ACTIVE '/dev/SYSTEM/ROOT' [13.90 GiB] inherit
Размер свопа — два гига.
Итак, у нас должно быть три тома: один, монтирующийся в /boot, находится непосредственно на диске. Два других (ROOT и SWAP) расположены в группе томов SYSTEM.
Во-первых, нам надо на destination установить пакет lvm2 для работы с LVM:
apt-get install lvm2
Разбиваем диск на destination
По большому счету, нам не надо придерживаться тех же размеров томов, которые были на source. Нам необходимо, чтобы данные, находящиеся на source, вместились в соответствующие тома на destination. Поэтому разбивать можно «на глазок».
Диск на destination должен содержать три раздела: под загрузчик, под /boot, и под группу томов SYSTEM.
Разбиваем диск.
Создаем на диске таблицу разделов GPT:
parted /dev/vda mklabel gpt
Создаем раздел для размещения системных данных загрузчика GRUB:
parted /dev/vda mkpart biosgrub 0% 10M
Устанавливаем на этот раздел метку «bios_grub» для того, чтобы загрузчик понял, где располагать свои данные при установке:
parted /dev/vda set 1 bios_grub on
Создаем раздел под /boot размером 256M:
parted /dev/vda mkpart boot 10M 266M
Отдаем все остальное пространство на диске под группу томов SYSTEM:
parted /dev/vda mkpart system 266M 100%
Смотрим, что у нас получилось:
root@ubuntu:~# parted /dev/vda print Model: Virtio Block Device (virtblk) Disk /dev/vda: 34.4GB Sector size (logical/physical): 512B/512B Partition Table: gpt Number Start End Size File system Name Flags 1 1049kB 10.5MB 9437kB ext4 biosgrub bios_grub 2 10.5MB 266MB 256MB boot 3 266MB 34.4GB 34.1GB system
Не обращаем внимания на то, что у первого раздела на диске указан тип файловой системы «ext4«. Это просто информационное поле, и возиться с ним мы сейчас не будем.
В /dev/vda1 будут располагаться системные данные загрузчика GRUB. /boot у нас будет расположен в /dev/vda2, а группа томов SYSTEM — в /dev/vda3.
Создаем группу томов SYSTEM:
vgcreate SYSTEM /dev/vda3
Создаем логический том SWAP объемом 2G:
lvcreate -n SWAP -L 2G SYSTEM
Создаем логический том ROOT, и выделяем под него все оставшееся свободное пространство в группе томов SYSTEM:
lvcreate -n ROOT -l +100%Free SYSTEM
Смотрим, что у нас получилось:
root@ubuntu:~# lvscan ACTIVE '/dev/SYSTEM/SWAP' [2.00 GiB] inherit ACTIVE '/dev/SYSTEM/ROOT' [29.76 GiB] inherit root@ubuntu:~#
Форматируем разделы. /dev/vda2 и /dev/SYSTEM/ROOT, как ext4, и /dev/SYSTEM/SWAP, как своп:
mkfs.ext4 /dev/vda2 mkfs.ext4 /dev/SYSTEM/ROOT mkswap /dev/SYSTEM/SWAP
Структура нашей будущей файловой системы такова: /dev/SYSTEM/ROOT монтируется в корень (/), и /dev/vda2 монтируется в /boot.
Для того, чтобы скопировать данные с source, нам надо подмонтировать в правильном порядке целевые файловые системы к destination. Монтировать будем в каталог /mnt:
mount /dev/SYSTEM/ROOT /mnt # монтируем /dev/SYSTEM/ROOT в /mnt mkdir /mnt/boot # создаем будущую точку монтирования /boot mount /dev/vda2 /mnt/boot # монтируем туда /dev/vda2
Вот так у нас сейчас выглядят подмонтированные к destination файловые системы:
root@ubuntu:~# df -h Filesystem Size Used Avail Use% Mounted on /cow 1002M 149M 854M 15% / udev 993M 4.0K 993M 1% /dev tmpfs 401M 720K 401M 1% /run /dev/sr0 712M 712M 0 100% /cdrom /dev/loop0 676M 676M 0 100% /rofs tmpfs 1002M 16K 1002M 1% /tmp none 5.0M 0 5.0M 0% /run/lock none 1002M 84K 1002M 1% /run/shm /dev/mapper/SYSTEM-ROOT 30G 172M 28G 1% /mnt /dev/vda2 236M 6.1M 218M 3% /mnt/boot
Видим, что наш будущий корень подмонтирован в /mnt, а будущий /boot подмонтирован в /mnt/boot.
Готовимся к копированию данных.
В современном Линуксе многие точки монтирования содержат виртуальные файловые системы, которые монтируются по определенным правилам при старте системы. Содержимое этих точек нам копировать не надо, надо лишь создать каталоги под них.
Смотрим на source, какие каталоги надо исключить при копировании:
root@ServerSource:~# mount /dev/mapper/SYSTEM-ROOT on / type ext4 (rw,errors=remount-ro) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) none on /sys/fs/fuse/connections type fusectl (rw) none on /sys/kernel/debug type debugfs (rw) none on /sys/kernel/security type securityfs (rw) udev on /dev type devtmpfs (rw,mode=0755) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880) none on /run/shm type tmpfs (rw,nosuid,nodev) /dev/vda1 on /boot type ext4 (rw) root@ServerSource:~#
Исключаем «/proc«, «/sys«, «/dev» и «/run«.
Запускаем синхронизацию
На source выполняем:
rsync -aHAXv --progress --numeric-ids --exclude "/proc/*" --exclude "/sys/*" --exclude "/dev/*" --exclude "/run/*" / destination_ip:/mnt
Смотрим, есть ли в fstab на source инструкции монтировать том по UUID:
root@ServerSource:~# cat /etc/fstab | grep -i uuid # device; this may be used with UUID= as a more robust way to name devices UUID=2f577cee-dba0-4dc9-a535-846ff451ec59 /boot ext4 defaults 0 2 root@ServerSource:~#
Есть. На destination смотрим, какой UUID у нас теперь для /boot:
root@ubuntu:/mnt# blkid /dev/vda2 /dev/vda1: UUID="2b39fd7e-cea7-4a13-8d2e-e2635686bcd5" TYPE="ext4" root@xubuntu:/mnt#
Прописываем корректный UUID в файле /mnt/etc/fstab
Перезагружаем destination
Меняем на destination инсталляционный источник с десктопной версии дистрибутива на серверную для того, чтобы можно было стартовать в режиме восстановления системы и прописать на жесткий диск загрузчик.
Грузимся в режиме восстановления («Rescue a broken system«).
На этапе выбора корневой файловой системы в качестве рута выбираем /dev/SYSTEM/ROOT:
Запускаем shell в контексте клонированной системы:
Смотрим список подмонтированных файловых систем.
В нашем случае произошел сбой, и файловая система /boot отображается некорректно подмонтированной — у нее неверно указан размер раздела, плюс отсутствуют данные в самом разделе. Отмонтируем ее и примонтируем обратно:
При отмонтировании может возникнуть ошибка, как показанно на скриншоте. Не обращаем внимания.
Прописываем загрузчик:
grub-install /dev/vda
Обновляем конфигурацию загрузчика:
update-grub
Все
Выходим из инсталлятора, грузимся с диска. Перед вами — абсолютный клон source, который можно как угодно препарировать. Следует иметь в виду, что клон поднимется с идентичными оригиналу сетевыми настройками.
Добавить комментарий