[Из песочницы] Опыт переноса виртуальной машины с чужого хостинга XEN на свой KVM

Передо мной была поставлена задача переноса сайта с внешнего хостинга на сервер клиента. Особенность была в том, что виртуальный сервер был хорошо настроен, и очень не хотелось заново устанавливать и конфигурировать операционную систему, базу данных и все пакетыты окружения.Сайт крутился в облаке известного провайдера на виртаульной машине с гипервизором XEN. Я надеялся, что поддержка пойдёт навстречу и выдаст образ виртуальной машины, но чуда не случилось: отказ был холоден и учтив, наверное, как обычно. В результате родилась примерная схема переноса: сделать образ диска, передать его на свой сервер, создать у себя виртуалку, указав полученный образ в качестве источника.

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

1. Подключение к своему серверу Поскольку делать образ диска на сам этот диск достаточно хлопотно, нужно было подключить файловую систему, отличную от используемой. Первое, что пришло в голову — смонтировать домашнюю папку своего сервера в файловую систему на виртуалке с помощью sshfs. Команды привожу для дистрибутива Debian: # apt-get install sshfs # mkdir /mnt/vasya # sshfs vasya@pupkin.ru:/home/vasya /mnt/vasya Password: Чебурашка-2014 2. Перевод ФС в read-only Для того, чтобы файловая система не потеряла целостность, нужно было перевести её в режим защиты от записи (read-only). Для этого в линуксе предусмотрена возможность перемонтирования ФС: mount -o ro, remount /. Команда закономерно не сработала, ядро блокировало выполнение команды с ошибкой mount: / is busy. После некоторого гугления нашлась причина: многие файлы были открыты демонами. На сервере мне пришлось остановить ntp, apache2, mysql, rsyslogd (возможно, я что-то пропустил, но список запущенных процессов можно посмотреть командой htop или top). # invoke-rc.d ntp stop # invoke-rc.d apache2 stop # invoke-rc.d mysql stop # invoke-rc.d rsyslogd stop # mount -o ro, remount / # touch /test touch: cannot touch `/test': Read-only file system 3. Создание и передача образа Для создания образа я воспользовался программой dd. Также я воспользовался конвейером данных и направил их через программу сжатия gzip в файл, расположенный в папке, которая смонтирована на удалённый сервер. # dd if=/dev/xvda bs=64K | gzip -c > /mnt/vasya/xvda.raw.gz Через полтора часа я имел у себя на сервере файл /home/vasya/xvda.raw.gz с нужным мне образом. Коэффициент сжатия оказался неплохим: 8.5/12.

4. Подключение образа к новой виртуальной машине На локальном железе я использую Proxmox VE 3.1. Я создал виртуальную машину со следующей конфигурацией: balloon: 256 bootdisk: virtio0 cores: 2 ide2: nfs-da: iso/debian-7.2.0-amd64-netinst.iso, media=cdrom, size=222M memory: 768 name: pupkin net0: virtio=26:95:81:17: D9:14, bridge=vmbr0 ostype: l26 sockets: 1 virtio0: nfs-da:143/vm-143-disk-1.raw, format=raw Файл образа виртауальной машины я, конечно, разархивировал и положил в нужное место с нужными правами доступа (/mnt/nfs — это раздел, сконфигурированный как хранилище Proxmox VE, 143 — идентификатор новой виртуалки):

# zcat /home/vasya/xvda.raw.gz > /mnt/nfs/images/143/vm-143-disk-1.raw # chown nobody: nogroup /mnt/nfs/images/143/vm-143-disk-1.raw По своей неопытности я предвкушал победу, но не тут-то было: загрузчик Grub выпадал в свою консоль. Более того, попытки загрузиться вручную были обречены на провал: в полученном образе отсутствовал инициализатор окружения initrd, а ядро было узкоспециализированным и не содержало драйверов для virtio устройств (сеть и жёсткий диск). Опытные специалисты могут меня дополнить и объяснить, как сконфигурирована загрузка Linux в среде XEN, мне до этого не было дела, у меня уже зарождался новый план: нужно положить на образ ядро linux, его драйверы и initrd от работающей виртуальной машины с похожей операционкой.

5. Исправление загрузчика У меня была рабочая виртуалка, к которой я добавил новый диск, а затем удалил его образ с файловой системы и заменил его симлинком на сломанный образ. Предварительно я, конечно, выключил виртуалку 143, чтобы образ случайно не открыли 2 процесса одновременно. # rm /mnt/nfs/images/200/vm-200-disk-2.raw # ln -s /mnt/nfs/images/143/vm-143-disk-1.raw /mnt/nfs/images/200/vm-200-disk-2.raw Я загрузил виртуалку 200, смонтировал ФС сломанного образа и скопировал туда ядро linux, рабочий загрузчик и драйверы устройств.

# mkdir /mnt/vdb1 # mount /dev/vdb1 /mnt/vdb1 # cp /boot/vmlinuz-3.2.0–4-amd64 /mnt/vdb1/boot/vmlinuz-3.2.0–4-amd64 # cp /boot/initrd.img-3.2.0–4-amd64 /mnt/vdb1/boot/initrd.img-3.2.0–4-amd64 # cp /boot/System.map-3.2.0–4-amd64 /mnt/vdb1/boot/System.map-3.2.0–4-amd64 # cp -r /lib/modules/3.2.0–4-amd64 /mnt/vdb1/lib/modules Я выключил 200, включил 143 и ввёл команды ручной загрузки Grub:

grub> root (hd0, msdos1) grub> linux /boot/vmlinuz-3.2.0–4-amd64 root=/dev/vda1 grub> initrd /boot/initrd.img-3.2.0–4-amd64 grub> boot Система загрузилась и даже успешно стартовала mysql и apache2. Мне, конечно, пришлось поправить /etc/network/interfaces, чтобы система вышла в локальную сеть и смогла общаться с маршрутизатором и сетью Интернет.

На полноценно работающей машине дальше уже не возникало проблем: я запустил установку grub и установил ядро linux из репозитория, чтобы выпрямить загрузчик окончательно и следовать debian-way:

# grub-install /dev/vda # apt-get update # apt-get install linux-image-2.6.32–5–486 # reboot Вывод В результате всех манипуляций я получил виртуальную машину, почти идентичную исходной, но работающую в среде Proxmox VE с гипервизором KVM и не требующую специального загрузчика. Образ планируется передать клиенту для запуска в кластере VMware ESX.

© Habrahabr.ru