Автор: Султан Усманов, DevOps компании Hostkey
В ходе проведения работ по оптимизации парка физических серверов и уплотнению виртуализации перед нами возникла задача переноса виртуальных серверов с oVirt на VMware. Дополнительной проблемой стала необходимость сохранить возможность отката на oVirt-инфраструктуру в случае возникновения каких-либо осложнений в процессе миграции, т.к. для хостинговой компании стабильность работы оборудования является приоритетной задачей.
Для проведения миграции серверов была развернута инфраструктура:
- NFS-сервер, презентован на серверах oVirt, ESXi и сервере-посреднике,
- Сервер-посредник, на котором проводилась конвертация дисков RAW и Qcow2 в формат VMDK.
Ниже описаны скрипты, команды и шаги, которые мы использовали при миграции.
Для частичной автоматизации и сокращения времени на подключение к серверам oVirt, чтобы скопировать диск виртуального сервера и разместить его на NFS для дальнейшей конвертации, был написан bash-скрипт, который запускался на сервере-посреднике и выполнял следующие действия:
- Подключался к Engine-серверу;
- Находил нужный виртуальный сервер;
- Отключал сервер;
- Переименовывал (имена серверов в нашей инфраструктуре не должны повторяться);
- Копировал диск сервера на NFS-раздел, примонтированный к oVirt и ESXi серверам.
Так как мы были ограничены по времени, был написан скрипт, работающий только с серверами, у которых один диск.
Bash-скрипт
#!/usr/bin/env bash
##Source
engine_fqdn_src= FQDN имя Engine сервера
engine_api_src="https://${engine_fqdn_src}/ovirt-engine/api"
guest_id=$1
##Common vars
engine_user=пользователь с правами на управление виртуальными серверами
engine_pass=пароль
export_path=/mnt/autofs/nfs
OVIRT_SEARCH() {
local engine_api=$1
local api_target=$2
local search
if [[ ! -z $3 ]]&&[[ ! -z $4 ]];then
local search="?search=$3=$4"
fi
curl -ks -user "$engine_user:$engine_pass" \
-X GET -H 'Version: 4' -H 'Content-Type: application/JSON' \
-H 'Accept: application/JSON' "${engine_api}/${api_target}${search}" |\
jq -Mc
}
##Source
vm_data=$(OVIRT_SEARCH $engine_api_src vms name $guest_id)
disk_data=$(OVIRT_SEARCH $engine_api_src disks vm_names $guest_id)
host_data=$(OVIRT_SEARCH $engine_api_src hosts address $host_ip)
vm_id=$(echo $vm_data | jq -r '.vm[].id')
host_ip=$(echo $vm_data | jq -r '.vm[].display.address')
host_id=$(echo $vm_data | jq -r '.vm[].host.id')
disk_id=$(echo $disk_data | jq -r '.disk[].id')
stor_d_id=$(echo $disk_data | jq -r '.disk[].storage_domains.storage_domain[].id')
##Shutdown and rename vm
post_data_shutdown="<action/>"
post_data_vmname="<vm><name>${guest_id}-</name></vm>"
##Shutdown vm
curl -ks -user "$engine_user:$engine_pass" \
-X POST -H 'Version: 4' \
-H 'Content-Type: application/xml' -H 'Accept: application/xml' \
--data $post_data_shutdown \
${engine_api_src}/vms/${vm_id}/shutdown
sleep 60
##Shutdown vm
curl -ks -user "$engine_user:$engine_pass" \
-X POST -H 'Version: 4' \
-H 'Content-Type: application/xml' -H 'Accept: application/xml' \
--data $post_data_shutdown \
${engine_api_src}/vms/${vm_id}/stop
##Changing vm name
curl -ks -user "$engine_user:$engine_pass" \
-X PUT -H 'Version: 4' \
-H 'Content-Type: application/xml' -H 'Accept: application/xml' \
--data $post_data_vmname \
${engine_api_src}/vms/${vm_id}
##Copying disk to NFS mount point
scp -r root@$host_ip:/data/$stor_d_id/images/$disk_id /mnt/autofs/nfs
В случае с серверами, у которых было два диска, проводились работы, которые будут описаны ниже.
Подключение к Engine и поиск нужного сервера
В разделе “Compute” >> “Virtual Machines” в окне поиска ввести имя сервера, который необходимо перенести. Найти сервер и отключить его:

Перейти в раздел “Storage” >> “Disks” и найти сервер, который необходимо перенести:

В данном окне необходимо запомнить ID дисков, подключенных к переносимому серверу. Затем перейти на сервер-посредник по SSH и подключиться к серверу oVirt, на котором находится виртуальный сервер. В нашем случае мы использовали приложение “Midnight Commander” для подключения к физическому серверу и копирования нужных дисков:

После того, как скопировали диски, необходимо проверить их формат (raw или qcow). Для проверки можно использовать команду qemu-img info
и указать имя диска. После выбора формата следует выполнить конвертацию при помощи команды:
qemu-img convert -f qcow2 (название диска) -O vmdk (название диска.vmdk) -o compat6
В нашем случае мы конвертируем из формата qcow2 в vmdk.
По окончанию конвертации необходимо перейти в vCenter или, если установлен просто ESXi-сервер, зайти на него через web-интерфейс для создания виртуального сервера без диска. В нашем случае был установлен vCenter.
Создание виртуального сервера
Так как у нас настроен кластер, необходимо кликнуть по нему правой кнопкой мыши и выбрать вариант “New Virtual Machine”:

Затем выбрать пункт “Create new virtual machine”:

Задать имя сервера и нажать “Next”:

Выбрать физический сервер, на котором планируется разместить виртуальный сервер, и нажать “Next”:


Указать версию ESXi для совместимости, если в инфраструктуре имеются сервера версии 6, необходимо выбрать нужную версию. В нашем случае это 7.

Выбрать операционную систему и версию, которая была установлена на сервере, что мы переносим. В нашем случае это Linux с операционной системой CentOS 6.

В окне “Customize Hardware”, необходимо выставить все параметры, идентично тем, что были выставлены в переносимой системе. Также необходимо удалить диск, т.к вместо него будет подключен сконвертированный диск.

Если требуется оставить старый mac-адрес на сетевой карте, его необходимо задать вручную:

После создания виртуального сервера необходимо зайти по SSH на ESXi хост и выполнить конвертацию диска из Thick в Thin provision и указать его расположение, т.е. имя сервера, который создали выше.
vmkfstools -i /vmfs/volumes/NFS/название диска/название диска.vmdk(что мы сконвертировали на предыдущем шаге) -d thin /vmfs/volumes/название хранилища на ESXi/имя сервера/название диска.vmdk
После успешной конвертации необходимо подключить диск к серверу. Снова переходим в web интерфейс ESXi или vCenter находим нужный сервер, кликаем по его названию правой кнопкой мыши и выбираем “Edit Settings”.
В открывшемся окне с правой стороны щелкаем на “ADD NEW DEVICE” и в выпадающем списке выбираем “Existing Hard Drive”.

На нашем хранилище - диске ESXi находим сервер и диск, который мы конвертировали ранее, и щелкаем “OK”.

В результате выполнения указанных действий будет создан виртуальный сервер:

Для запуска сервера необходимо в настройках диска в разделе ”Virtual Device Node” выбрать контроллер IDE. В противном случае при загрузке системы будет выведено сообщение “Диск не найден”.
Описанных выше шагов по созданию виртуального сервера и подключения диска будет достаточно для корректного запуска системы, если на сервере-источнике в настройках диска был интерфейс “Virtio-SCSI”. Проверить тип интерфейса можно в настройках oVirt на самом виртуальном сервере в разделе “Compute >> Virtual Machines” находим сервер и переходим в “Disks”:

В процессе миграции мы столкнулись c проблемой переноса серверов с Virtio - это старый контроллер и диски в /etc/fstab называются не sda, как в новых системах, а vda. Для переноса подобных серверов мы использовали следующее решение - перед запуском системы необходимо подключить LiveCD и выполнить следующие действия:
- Загрузиться под LiveCD;
- Создать и смонтировать диски, например,
mount /dev/sda1 /mnt/sda1;
- Перейти в раздел mnt и подключиться к системе посредством chroot, выполнив команды:
mount -t proc proc /sda1/proc
mount -t sysfs sys /sda1/sys
mount -o bind /dev /sda1/dev
mount -t devpts pts /sda1/dev/pts
chroot /sda1
После входа в систему (chroot) необходимо изменить наименование дисков в fstab и пересобрать конфигурационный файл grub:
vim /etc/fstab
grub2-mkconfig -o /boot/grub2/grub.cfg
После выполнения указанных действий необходимо перезагрузить сервер.
Описанное решение позволило нам решить задачу по переносу большого парка серверов. В среднем перенос диска с настройками и запуском сервера в 15-20 ГБ занимал от 20 до 30 минут, а объемом в 100 Гб - от полутора до двух часов.