четверг, 26 мая 2011 г.

Миграция с одного физического сервера на другой

Типичная ситуация, стартует проект, под него берут самый простенький сервер, который трудится полгода, проект вырастает и просит большой и злобный сервер.

Обычно ставят на новую железку новую ОС, поднимают софт, настраивают, переносят контент, базы и прочее, меняют DNS и через двое суток выключают старый сервер. Казалось бы простая процедура, сотни раз её делал любой сисадмин. НО, в процессе как показывает практика что-то забывается и уже на боевом сервере нужно делать правки и настройки, тащить старые костыли и адаптировать их на новом месте.

Этот вариант иногда неизбежен, например когда сервера в разных датацентрах. Но если сервера (новый и старый) стоят в соседних стойках, то можно просто перенести ОС на новую железку а старую сразу погасить. О том как это сделать я и напишу небольшую статью-чеклист. Итак поехали!

Умолчания:
— Сервера в одном датацентре у одного колокатора/дедикатора
— Вы договорились с колокатором/дедикатором о том что перецепите ip адреса со старого сервера на новый. Если этого не сделать могут быть косяки в случае если сервера в разных VLAN-ах.
— Вам дают IP-KVM как минимум на новый сервер, в идеале может понадобиться и на старый если вдруг хочется сохранить его доступность.
— Колдовство буду показывать на примере CentOS 5.x
— У вашего серверодателя есть pxe сервер с аварийным (т.н. rescue) образом CentOS 5.x и вашей платформы.
— Вы знаете root пароль от исходного сервера.
— Вы переписали, на чистый лист бумаги, со старого сервера настройки сети и разметку диска.

Итак, все условия выполнены, начинаем работу!
Загружаем новый сервер по сети, для этого у Supermicro например, нужно включить в BIOS pxe boot для первого сетевого адаптера, перезагрузить сервер и нажать F12. В случае если на сетевом коммутаторе включен STP на аксесных портах при появлении сообщении о попытке получить ip по dhcp нажать кнопку pause и выждать 30 секунд. После чего жмем пробел и загружаемся в CentOS 5.x 64 rescue.

fdisk -l смотрим зацепились ли диски, если нет то вкорячиваем драйвер RAID контроллера при помощи insmod. Если диски видны, размечаем их так же как на старом сервере, если нет контроллера и есть диски собираем с помощью mdadm software RAID. Да, и не забудьте про swap.

Создаем файловую систему:

mkswap /dev/md5
mkfs.ext3 /dev/md0
mkfs.ext3 /dev/md1
mkfs.ext3 /dev/md2
mkfs.ext3 /dev/md3
mkfs.ext3 /dev/md4

Монтируем корневую партицию в /mnt/sysimage

mount /dev/md0 /mnt/sysimage

Создаем структуру каталогов в /mnt/sysimage/, например так:

mkdir -p /mnt/sysimage/{var,usr,home,tmp}

Монтируем партиции в строгом соответствии со старым сервером:

mount /dev/md1 /mnt/sysimage/usr
mount /dev/md2 /mnt/sysimage/var
mount /dev/md3 /mnt/sysimage/home
mount /dev/md4 /mnt/sysimage/tmp

Начинаем синхронизацию данных со старого сервера, вот тут нам понадобится root доступ на старый сервер. Предположим что на старом сервере у нас ip 1.1.1.1

rsync -avrt --progress 1.1.1.1:/ /mnt/sysimage/ --exclude=/dev --exclude=/proc --exclude=/sys

Как только данные синхронизируются переходим на старый сервер и останавливаем все службы, например mysql/httpd/nginx/proftpd и прочее что у вас есть.

Снова возвращаемся на новый сервер и снова синхронизируем данные, но уже с параметром --delete

rsync -avrt --progress 1.1.1.1:/ /mnt/sysimage/ --exclude=/dev --exclude=/proc --exclude=/sys --delete

Теперь чрутимся в «новый сервер» и начинаем вносить изменения которые необходимы для того чтобы сервер загрузился:

mkdir /mnt/sysimage/{proc,sys,dev}
mount --bind /dev /mnt/sysimage/dev
mount -t proc none /mnt/sysimage/proc
mount -t sysfs none /mnt/sysimage/sys
chroot /mnt/sysimage

Если на старом сервере у вас были sda/sdb/sdc а на новом md0/md1/md2 или наоборот то нужно сделать соответствующие правки в /etc/fstab и /boot/grub/grub.conf
Записи в fstab из:

/dev/sda1 / ext3 defaults 1 1
/dev/sda2 /home ext3 defaults 1 2
/dev/sda3 /tmp ext3 defaults 1 2
/dev/sda4 /var ext3 defaults 1 2
/dev/sda5 /usr 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/sda6 swap swap defaults 0 0

Приводим к:

/dev/md0 / ext3 defaults 1 1
/dev/md4 /home ext3 defaults 1 2
/dev/md3 /tmp ext3 defaults 1 2
/dev/md2 /var ext3 defaults 1 2
/dev/md1 /usr 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/md5 swap swap defaults 0 0

И переходим к правкам grub.conf

title CentOS (2.6.18-238.9.1.el5)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-238.9.1.el5 ro root=/dev/sda1
initrd /boot/initrd-2.6.18-238.9.1.el5.img

приводим к виду:

title CentOS (2.6.18-238.9.1.el5)
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-238.9.1.el5 ro root=/dev/md0 panic=30
initrd /boot/initrd-2.6.18-238.9.1.el5.img

Пожалуйста, обратите внимание на panic=30 в строке инициализации ядра, это нужно на случай если где-то ошиблись и сервер выпал в Kernel Panic. Без этой panic=30 сервер будет ждать Hardware reset, с ней же он через 30 секунд перезагрузится.

Теперь нам нужно поставить grub:

# grub
grub> root (hd0,0)
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)
setup (hd0)
Checking if "/boot/grub/stage1" exists... yes
Checking if "/boot/grub/stage2" exists... yes
Checking if "/boot/grub/e2fs_stage1_5" exists... yes
Running "embed /boot/grub/e2fs_stage1_5 (hd0)"... 15 sectors are embedded.
succeeded
Running "install /boot/grub/stage1 (hd0) (hd0)1+15 p (hd0,0)/boot/grub/stage2 /boot/grub/grub.conf"... succeeded
Done.
grub> quit
quit
#

Граб не ругнувшись установился, значит всё нормально. На всякий случай проверяем:

# dd if=/dev/sda count=10|strings|grep stage
Loading stage1.5
/boot/grub/stage2 /boot/grub/grub.conf

Теперь нам надо создать новый initrd, т.к. в старом может не оказаться например mdadm.

gzip /boot/initrd-2.6.18-238.9.1.el5.img
mkinitrd /boot/initrd-2.6.18-238.9.1.el5.img 2.6.18-238.9.1.el5

Включаем firstboot командой:

chkconfig firstboot on

И перезагружаем сервер несколько раз нажав Ctrl+D

Пока сервер перезагружается идем на старый и в зависимости от того нужен он нам дальше или нет отключаем сеть или меняем ip адрес. Если ненужен то для всех сетевых адаптеров в конфиге /etc/sysconfig/network-scripts/ifcfg-ethX (где X номер сетевого адаптера) правим ONBOOT=yes на ONBOOT=no и «останавливаем» сеть /etc/init.d/network stop. Если старый сервер нужен нам то в тех же конфигах задаем новые сетевые настройки и «перезапускаем» сеть /etc/init.d/network restart

Итак со стары сервером мы закончили, переходим к новому. В IP-KVM мы уже видим синее окошко ncurses которое выдал нам firstboot, переходим к настройке сети и вбиваем старые настройки сети. После чего перезагружаем сервер для чистоты эксперимента.

Возможно всё вышесказанное покажется вам сложным и рука потянется написать комментарий в духе «ну и зачем этот геморрой?», не спешите, на практике все операции выполняются очень быстро и даунтайм минимален.

Источник