Всем привет!
В данной заметке я расскажу о своем опыте клонирования сервера под управлением CentOS. Сама процедура в общем-то обычная и логичная, но есть некоторые моменты, про которые необходимо знать и помнить при переносе системы с одного железа на другое.
Постановка задачи
Имеется физический эталонный сервер с CentOS 5.5 на борту (впрочем версия ОС не имеет особо значения), на котором установлено и настроено программное обеспечение.
Так же имеется некоторое количество других серверов, разных конфигураций, на которые требуется поставить все то же самое, что стоит на эталонном сервере.
Отличие серверов только в настройках сети и конфигурации некоторого ПО.
Немного теории
В общем то, для решения данной задачи есть много разных способов, среди них такие как:
- dump/restore. Это 2 утилитки которые позволяют делать бекапы разделов, которые впоследствии можно восстановить. Так же имеется возможность делать инкрементальный бэкап с возможностью компрессии. Не смотря на то, что dump работает с разделами, в дампы попадают только данные. Неоднократно использовал эти утилиты в составе FreeBSD, они себя прекрасно зарекомендовали, наверное поэтому я и выбрал этот вариант.
- rsync. Это, по сути, синхронизация файлов по сети. Быстро, удобно, хорошо. Но я сам ни разу не использовал.
- dd, старый добрый dd. С dd основная тонкость в том, что эта утилита работает с устройствами на уровне блоков и копирует их байт-в-байт. Отсюда вытекает пара моментов: первое — это то, что если у вас раздел 50 гиг и из них занято всего 5, то dd все равно скопирует все 50; второе — как следствие из первого, если у вас исходный и целевой разделы разных разделов, точнее если целевой меньше исходного, то возможны проблемы.
- CloneZilla. В общем-то нормальный вариант, это live-cd, к которому прикручен какой-то GUI, в котором можно с помощью вопросов и ответов, а-ля визард, выбрать что склонировать и куда. Но так как это live-cd, то требуется перегружать сервер, и следовательно он какое-то время будет не работоспособен.
- Kickstart + Anaconda, так же как и DRBL — это установка по сети в том или ином виде. Для меня не подходит потому что серверы физически не находятся в одной сети.
- Acronis True Image платный, да и вообще это больше к виндам, и уж точно не Unix-way.
Что хочется добавить еще, какой бы способ вы не выбрали, это не спасет вас от последующей правки fstab, скриптов инициализации сети, hosts и т.д.
Пара слов о эталоне
Вот какие разделы и диски имеются на эталонном сервере:
2 раздела: /boot на /dev/sda1 и / на логическом разделе LVM LogVolRoot
root@Etalon: ~# df -h Файловая система Разм Исп Дост Исп% смонтирована на /dev/mapper/VolGroupRoot-LogVolRoot 60G 6,7G 51G 12% / /dev/sda1 99M 13M 81M 14% /boot tmpfs 2,0G 0 2,0G 0% /dev/shm
В системе один физический раздел
root@Etalon: ~# pvdisplay --- Physical volume --- PV Name /dev/sda2 VG Name VolGroupRoot PV Size 67,65 GB / not usable 24,47 MB Allocatable yes (but full) PE Size (KByte) 32768 Total PE 2164 Free PE 0 Allocated PE 2164 PV UUID 5lC4re-OsI6-zt7Z-LKGd-Nqa4-zGsK-Y0MaF0
И одна Volume Group которая состоит из этого одного физического раздела /dev/sda2
root@Etalon: ~# vgdisplay --- Volume group --- VG Name VolGroupRoot System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 3 VG Access read/write VG Status resizable MAX LV 0 Cur LV 2 Open LV 2 Max PV 0 Cur PV 1 Act PV 1 VG Size 67,62 GB PE Size 32,00 MB Total PE 2164 Alloc PE / Size 2164 / 67,62 GB Free PE / Size 0 / 0 VG UUID mbifBq-CW60-C5V7-U1dX-SBsY-kyIY-kYbd93
В этой группе есть 2 логических раздела: LogVolRoot — смонтированный как / и LogVolSwap — раздел для свапа
root@Etalon: ~# lvdisplay --- Logical volume --- LV Name /dev/VolGroupRoot/LogVolRoot VG Name VolGroupRoot LV UUID zLCehW-OWcN-gSem-GjQW-w5Tk-9JOs-O9i43Q LV Write Access read/write LV Status available # open 1 LV Size 61,81 GB Current LE 1978 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:0 --- Logical volume --- LV Name /dev/VolGroupRoot/LogVolSwap VG Name VolGroupRoot LV UUID OW4EOe-LKw2-VnRI-X2EA-PBGU-k950-uh6zeu LV Write Access read/write LV Status available # open 1 LV Size 5,81 GB Current LE 186 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 253:1
Ну и напоследок fstab:
root@Etalon: ~# cat /etc/fstab /dev/VolGroupRoot/LogVolRoot / ext3 defaults 1 1 LABEL=/boot /boot ext3 defaults 1 2 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 /dev/VolGroupRoot/LogVolSwap swap swap defaults 0 0
От слов к делу
Вся процедура выглядет примерно так:
- Делаем дампы разделов на эталонном сервере либо на внешний диск, либо на какой-то NAS.
- Грузимся с live-cd на целевом сервере.
- Подготавливаем диски целевого сервера: разбиваем на разделы, форматируем.
- Подцепляем внешний диск/nas где лежат наши бэкапы.
- Накатываем дампы.
- Правим системные конфиги
- Пересобираем initrd
- Ставим grub в MBR.
- Ребутимся и надеемся увидеть счастье.
Теперь по шагам.
1. Делаем дампы разделов. Поскольку этот целевой сервер я мог включить в общую сетку, то дампы я залил на самбовский сервер.
[12:59] cmd#:696 root@Etalon: ~# dump -0 -f boot.dmp -L "Etalon.boot" /boot DUMP: Date of this level 0 dump: Tue Nov 16 13:02:35 2010 DUMP: Dumping /dev/sda1 (/boot) to boot.dmp DUMP: Label: Etalon.boot DUMP: Writing 10 Kilobyte records DUMP: mapping (Pass I) [regular files] DUMP: mapping (Pass II) [directories] DUMP: estimated 7641 blocks. DUMP: Volume 1 started with block 1 at: Tue Nov 16 13:02:36 2010 DUMP: dumping (Pass III) [directories] DUMP: dumping (Pass IV) [regular files] DUMP: Closing boot.dmp DUMP: Volume 1 completed at: Tue Nov 16 13:02:36 2010 DUMP: Volume 1 7700 blocks (7.52MB) DUMP: 7700 blocks (7.52MB) on 1 volume(s) DUMP: finished in less than a second DUMP: Date of this level 0 dump: Tue Nov 16 13:02:35 2010 DUMP: Date this dump completed: Tue Nov 16 13:02:36 2010 DUMP: Average transfer rate: 0 kB/s DUMP: DUMP IS DONE [12:59] cmd#:696 root@Etalon: ~# dump -0 -f root.dmp -L "Etalon.root" / ...
2. Грузимся с live-cd. Я использовал тот же CentOS live-cd.
3. Далее нам нужно разбить диски в сервере на разделы и настроить LVM. Сделать это можно с помощью утилит fdisk/cfdisk/lvm. Хотя тем, кому лень возиться с этими утилитами из консоли, могу посоветовать самый наверное простой способ — это воспользоваться графическим инсталлером с установочного диска CentOS. Там после пары вопросов про язык и раскладку наступает шаг разбиения диска, все красиво, быстро и удобно. Собственно я так и сделал :-[ Разбил диск на 2 раздела: 100 mb под /boot и остальное под управлением LVM с двумя разделами для свапа и /. В новом сервере диск в системе видится как /dev/cciss/c0d0 с двумя разделами p1 и p2.
4. Поскольку дампы я залил на файловый сервер, то монтируем его:
[13:19] cmd#:700 root@Etalon: ~# mount.cifs //storage/Backups /mnt/storage -o user=kostik ip=192.168.24.111 Password:
5. Теперь надо накатить дампы на новенькие разделы. Но тут есть подстава в виде того, что в лив-сиди нет этих утилит. Надо их поставить. Берем с установочного диска CentOS 2 rpm’ки: rmt-0.4b41-4.el5.x86_64.rpm & dump-0.4b41-4.el5.x86_64.rpm. rmt нужна как зависимость для dump. Ставим их:
root@Etalon: ~# rpm -ivh rmt-0.4b41-4.el5.x86_64.rpm root@Etalon: ~# rpm -ivh dump-0.4b41-4.el5.x86_64.rpm
Далее монтируем новые разделы, если они еще не смонтированы
[root@livecd lvm]# mount /dev/mapper/VolGroupRoot-LogVolRoot VolGroupRoot-LogVolRoot [root@livecd lvm]# mount /dev/cciss/c0d0p1 boot/
Затем переходим в mount-point каждого раздела и накатываем dump:
[root@livecd lvm]# cd VolGroupRoot-LogVolRoot [root@livecd lvm]# restore -rf /mnt/storage/root.dmp [root@livecd lvm]# cd ../boot/ [root@livecd lvm]# restore -rf /mnt/storage/boot.dmp
6. Теперь нам надо поправить некоторые системные конфиги.
Поскольку диск мы разбили точно так же как и эталон, и LVM’овские тома и группы назвали так же, то fstab особо править не надо. Едиственное, что поскольку /boot у нас монтируется, используя метку а не путь к устройству, то надо убедиться, что у нашего boot’ового раздела такая же метка. Проверить и поставить метку можно с помощью e2label. Я, когда форматировал разделы, забыл указать метку и у меня ее не было, так что пришлось выставить:
[root@livecd lvm]# e2label /dev/cciss/c0d0p1 [root@livecd lvm]# e2label /dev/cciss/c0d0p1 "/boot" [root@livecd lvm]# e2label /dev/cciss/c0d0p1 /boot
Теперь надо поправить grub.
root@Etalon: ~# cat /boot/grub/device.map # this device map was generated by anaconda (hd0) /dev/sda
надо поменять на
root@Etalon: ~# cat /boot/grub/device.map # this device map was generated by anaconda (hd0) /dev/cciss/c0d0
7. Теперь нам надо пересобрать RAM-диск, инициализируемый загрузчиком, то есть initrd. Приведу кусок мана:
Специальный файл /dev/initrd — это блочное устройство только для чтения. Устройство /dev/initrd — это диск, расположенный в оперативной памяти, который инициализируется (т.е. загружается) загрузчиком до запуска ядра. Затем ядро может использовать содержимое блочного устройства /dev/initrd для двухфазовой загрузки системы.
Во время первой фазы ядро запускает и монтирует начальную корневую файловую систему из содержимого /dev/initrd (например, RAM-диска, инициализируемого загрузчиком). Во время второй фазы из начального содержимого корневого устройства загружаются дополнительные драйвера или другие модули. После загрузки дополнительных модулей с другого устройства монтируется новая корневая файловая система (т.е., нормальная корневая файловая система).
Для этого нам надо, во-первых, перемонтировать наш boot в boot, который находится в корне нашего подмонтированного рутового раздела, а не просто куда-нибудь. Это важно. Затем также смонтировать системные fs в дерево нашего образа, затем чрутнуться в наш образ и переинициализировать initrd:
[root@livecd lvm]# umount boot/ [root@livecd lvm]# cd VolGroupRoot-LogVolRoot [root@livecd VolGroupRoot-LogVolRoot]# mount /dev/cciss/c0d0p1 boot/ [root@livecd VolGroupRoot-LogVolRoot]# mount -t proc proc proc/ [root@livecd VolGroupRoot-LogVolRoot]# mount -t sysfs sys sys/ [root@livecd VolGroupRoot-LogVolRoot]# mount -o bind /dev dev/ [root@livecd VolGroupRoot-LogVolRoot]# chroot ./ [root@livecd /]# mkinitrd -v -f --force-ide-probe --force-scsi-probe --force-raid-probe --force-lvm-probe /boot/initrd-2.6.18-194.el5.img 2.6.18-194.el5 Creating initramfs Looking for deps of module ehci-hcd Looking for deps of module ohci-hcd Looking for deps of module uhci-hcd Looking for deps of module ext3: jbd Looking for deps of module jbd Looking for driver for device cciss/c0d0p2 Looking for deps of module megaraid_sas: scsi_mod Looking for deps of module scsi_mod Looking for deps of module sd_mod: scsi_mod Looking for deps of module ata_piix: scsi_mod libata Looking for deps of module libata: scsi_mod Looking for deps of module qla2xxx: scsi_mod scsi_transport_fc Looking for deps of module scsi_transport_fc: scsi_mod Looking for deps of module ide-disk Looking for deps of module dm-mod Looking for deps of module dm-mirror: dm-mod dm-log Looking for deps of module dm-log: dm-mod Looking for deps of module dm-zero: dm-mod Looking for deps of module dm-snapshot: dm-mod Looking for deps of module dm-mem-cache Looking for deps of module dm-region_hash: dm-mod dm-log Looking for deps of module dm-message Looking for deps of module dm-raid45: dm-message dm-mod dm-mem-cache dm-log dm-region_hash Looking for deps of module cciss: scsi_mod Using modules: /lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/ehci-hcd.ko /lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/ohci-hcd.ko /lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/uhci-hcd.ko /lib/modules/2.6.18-194.el5/kernel/fs/jbd/jbd.ko /lib/modules/2.6.18-194.el5/kernel/fs/ext3/ext3.ko /lib/modules/2.6.18-194.el5/kernel/drivers/scsi/scsi_mod.ko /lib/modules/2.6.18-194.el5/kernel/drivers/scsi/sd_mod.ko /lib/modules/2.6.18-194.el5/kernel/drivers/scsi/megaraid/megaraid_sas.ko /lib/modules/2.6.18-194.el5/kernel/drivers/ata/libata.ko /lib/modules/2.6.18-194.el5/kernel/drivers/ata/ata_piix.ko /lib/modules/2.6.18-194.el5/kernel/drivers/scsi/scsi_transport_fc.ko /lib/modules/2.6.18-194.el5/kernel/drivers/scsi/qla2xxx/qla2xxx.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mod.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-log.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mirror.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-zero.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-snapshot.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mem-cache.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-region_hash.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-message.ko /lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-raid45.ko /lib/modules/2.6.18-194.el5/kernel/drivers/block/cciss.ko /sbin/nash -> /tmp/initrd.dQ6087/bin/nash /sbin/insmod.static -> /tmp/initrd.dQ6087/bin/insmod copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/ehci-hcd.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/ehci-hcd.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/ohci-hcd.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/ohci-hcd.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/usb/host/uhci-hcd.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/uhci-hcd.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/fs/jbd/jbd.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/jbd.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/fs/ext3/ext3.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/ext3.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/scsi/scsi_mod.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/scsi_mod.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/scsi/sd_mod.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/sd_mod.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/scsi/megaraid/megaraid_sas.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/megaraid_sas.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/ata/libata.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/libata.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/ata/ata_piix.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/ata_piix.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/scsi/scsi_transport_fc.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/scsi_transport_fc.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/scsi/qla2xxx/qla2xxx.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/qla2xxx.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mod.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-mod.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-log.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-log.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mirror.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-mirror.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-zero.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-zero.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-snapshot.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-snapshot.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-mem-cache.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-mem-cache.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-region_hash.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-region_hash.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-message.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-message.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/md/dm-raid45.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/dm-raid45.ko' [elf64-x86-64] copy from `/lib/modules/2.6.18-194.el5/kernel/drivers/block/cciss.ko' [elf64-x86-64] to `/tmp/initrd.dQ6087/lib/cciss.ko' [elf64-x86-64] /sbin/lvm.static -> /tmp/initrd.dQ6087/bin/lvm /sbin/dmraid.static -> /tmp/initrd.dQ6087/bin/dmraid /sbin/kpartx.static -> /tmp/initrd.dQ6087/bin/kpartx Adding module ehci-hcd Adding module ohci-hcd Adding module uhci-hcd Adding module jbd Adding module ext3 Adding module scsi_mod Adding module sd_mod Adding module megaraid_sas Adding module libata Adding module ata_piix Adding module scsi_transport_fc Adding module qla2xxx Adding module dm-mod Adding module dm-log Adding module dm-mirror Adding module dm-zero Adding module dm-snapshot Adding module dm-mem-cache Adding module dm-region_hash Adding module dm-message Adding module dm-raid45 Adding module cciss [root@livecd /]# [root@livecd /]# exit
Если вы не подмонтируете специальные файловые системы /proc /sys /dev — то mkinitrd не сможет увидеть ваше железо и соответственно не добавит нужные драйвера в образ. Вот что может быть в этом случае:
[root@livecd /]# mkinitrd -v -f /boot/initrd-2.6.18-194.el5.img 2.6.18-194.el5 Creating initramfs Looking for deps of module ehci-hcd Looking for deps of module ohci-hcd Looking for deps of module uhci-hcd Looking for deps of module ext3: jbd Looking for deps of module jbd Looking for driver for device VolGroupRoot/LogVolRoot error opening /sys/block: No such file or directory Looking for driver for device VolGroupRoot/LogVolSwap error opening /sys/block: No such file or directory Looking for deps of module megaraid_sas: scsi_mod Looking for deps of module scsi_mod Looking for deps of module sd_mod: scsi_mod Looking for deps of module ata_piix: scsi_mod libata ...
Как показала практика, даже ручное указание, какие драйверы нужно добавить в образ, как показано ниже, не помогает.
[root@livecd /]# mkinitrd -v -f --with=cciss /boot/initrd-2.6.18-194.el5.img 2.6.18-194.el5
Даже в этом случае при попытке загрузить ОС появляется kernel panic
8. Теперь дело за малым, это проинсталлить grub в MBR, чтобы он указывал на правильный раздел /boot. Поскольку диск у нас в системе один, и бутовый раздел на нем первый, то делаем следующее:
[root@livecd /]# grub grub> root (hd0,0) grub> setup (hd0) grub> quit
Если grub будет не будет прописан в MBR, то сервер просто скажет «Non-System Disk», а если grub будет указывать на неверный раздел, то не сможет загрузиться ядро.
9. Ну и самое интересное — отправляем сервер на ребут и верим в счастье 🙂
Как же этот раздел обычно называется… АА! Список литературы!
Я наверное не буду инноватором и по большей части здесь будут ссылки на маны, но тем не менее, кому-то может пригодиться, какие именно маны надо читать 🙂
- man initrd. Если в системе русский язык, то там даже есть перевод 🙂
- man lvm.
- LVM — это просто!, заметка на Хабре.
- LVM Howto, очень хорошая документация по LVM.
- man dump.
- man restore.
- Clonezilla, лив-сиди для бэкапов.
- Линейка продуктов Acronis Backup & Recovery
В общем и целом, как оказалось, ничего кроме манов не требуется.
P.S. Если есть какие-то неточности/замечания или может быть даже пожелания — Велкам!