Как стать автором
Обновить

Как перенести OpenVZ 6 контейнер на KVM сервер без головной боли

Время на прочтение5 мин
Количество просмотров4.5K

Каждый, кому понадобилось хотя бы раз в жизни перенести OpenVZ контейнер на сервер с полноценной виртуализацией KVM, сталкивался с некоторыми проблемами:


  • Большинство информации банально устарело и было актуально для уже давно прошедших EOL цикл ОС
  • По разным ОС всегда предоставляется различная информация, и никогда не рассматриваются возможные ошибки при миграции
  • Иногда приходится иметь дело с конфигурациями, которые то и дело не хотят работать после миграции

Когда переносишь 1 сервер всегда можно что-то исправить на ходу, а когда переносишь целый кластер?


В этой статье я постараюсь рассказать, как правильно мигрировать OpenVZ контейнер на KVM с минимальным даунтаймом и быстрым решением всех проблем.


Небольшой ликбез: что такое OpenVZ и что такое KVM?


Не будем углубляться в терминологию, а скажем в общих чертах:


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


KVM — полноценная виртуализация, использующая всю мощь CPU и способная виртуализировать что угодно, как угодно, резать вдоль и поперек.


Вопреки расхожему мнению, что в среде хостинг-провайдеров OpenVZ оверселлится, а KVM нет — к счастью для последних, KVM нынче оверселлится ничуть не хуже своего собрата.


Что будем переносить?


В качестве подопытных для переноса пришлось использовать весь лес операционных систем, которые доступны на OpenVZ: CentOS (6 и 7 версии), Ubuntu (14, 16 и 18 LTS), Debian 7.


Предполагалось, что на бОльшей части контейнеров OpenVZ уже крутится какой-никакой LAMP, а у некоторых даже есть какой-то очень специфический софт. Чаще всего, это были конфигурации с панелью управления ISPmanager, VestaCP (и чаще всего, не обновляемые годами). Необходимо учесть и их запросы к переносу.


Миграция осуществляется со сохранением IP-адреса переносимого контейнера, будем считать что IP, который был у контейнера, сохраняется на VM и будет работать без проблем.


Перед переносом убедимся, что имеем всё на руках:


  • Сервер OpenVZ, полный рут-доступ к хост-машине, возможность останавливать/монтировать/запускать/удалять контейнеры
  • Сервер KVM, полный рут-доступ к хост-машине, со всеми вытекающими. Предполагается, что всё уже настроено и готово к работе.

Приступаем к переносу


Прежде чем начать перенос, обозначим термины, которые позволят не запутаться:


KVM_NODE — хост-машина KVM
VZ_NODE — хост-машина OpenVZ
CTID — контейнер OpenVZ
VM — виртуальный сервер KVM


Подготовка к переносу и создание виртуальных машин.


Шаг 1


Так как нам нужно куда-то переносить контейнер, то создадим VM с аналогичной конфигурацией на KVM_NODE.
Важно! Создавать VM нужно именно на той операционной системе, которая сейчас крутится на CTID. Например, если на CTID установлена Ubuntu 14, то и на VM нужно ставить Ubuntu 14. Минорные версии не важны и их несовпадение не столь критично, а вот мажорные — должны быть одинаковыми.


После создания VM, выполним обновление пакетов на CTID и на VM (не путать с обновлением ОС — её не обновляем, обновляем только пакеты и, если прилетит, версию ОС в пределах основной версии).


Для CentOS этот процесс выглядит безобидно:


# yum clean all
# yum update -y

И не менее безобидно для Ubuntu, Debian:


# apt-get update
# apt-get upgrade

Шаг 2


Устанавливаем на CTID, VZ_NODE и VM утилиту rsync:


CentOS:


# yum install rsync -y

Debian, Ubuntu:


# apt-get install rsync -y

Больше ничего не устанавливаем ни там, ни там.


Шаг 3


Производим остановку CTID на VZ_NODE командой


vzctl stop CTID

Монтируем образ CTID:


vzctl mount CTID

Переходим в папку /vz/root/CTID и выполняем


mount --bind /dev dev && mount --bind /sys sys && mount --bind /proc proc && chroot .

Под чрутом создаем файл /root/exclude.txt — он будет содержать список исключений, которые не попадут на новый сервер


/boot
/proc
/sys
/tmp
/dev
/var/lock
/etc/fstab
/etc/mtab
/etc/resolv.conf
/etc/conf.d/net
/etc/network/interfaces
/etc/networks
/etc/sysconfig/network*
/etc/sysconfig/hwconf
/etc/sysconfig/ip6tables-config
/etc/sysconfig/kernel
/etc/hostname
/etc/HOSTNAME
/etc/hosts
/etc/modprobe*
/etc/modules
/net
/lib/modules
/etc/rc.conf
/usr/share/nova-agent*
/usr/sbin/nova-agent*
/etc/init.d/nova-agent*
/etc/ips
/etc/ipaddrpool
/etc/ips.dnsmaster
/etc/resolv.conf
/etc/sysconfig/network-scripts/ifcfg-eth0
/etc/sysconfig/network-scripts/ifcfg-ens3

Подключаемся к KVM_NODE и запускаем наш VM, чтобы он работал и был доступен по сети.


Теперь всё готово к переносу. Поехали!


Шаг 4


Всё ещё находясь под чрутом, выполняем


rsync --exclude-from="/root/exclude.txt" --numeric-ids -avpogtStlHz --progress -e "ssh -T -o Compression=no -x" / root@KVM_NODE:/

Команда rsync выполнит перенос, надеемся, что ключи понятны — перенос осуществляется с сохранением симлинков, прав доступа, владельцев и групп и отключено шифрование для бОльшей скорости (можно было использовать какой-нибудь более быстрый cipher, но это не так принципиально в рамках данной задачи), также как отключено и сжатие.


После завершения выполнения rsync, выходим из-под chroot (нажатием ctrl+d) и выполняем


umount dev && umount proc && umount sys && cd .. && vzctl umount CTID

Шаг 5


Выполним несколько действий, которые помогут нам в запуске VM после переноса с OpenVZ.
На серверах с Systemd выполним команду, которая поможет нам залогиниться в обычной консоли, допустим, через VNC экран сервера


mv /etc/systemd/system/getty.target.wants/getty\@tty2.service /etc/systemd/system/getty.target.wants/getty\@tty1.service

На серверах CentOS 6 и CentOS 7 обязательно установим свежее ядро:


yum install kernel-$(uname -r)

Сервер может быть с него загружен, но после переноса оно может перестать работать или будет удалено.


На сервере CentOS 7 необходимо применить небольшой фикс для PolkitD, иначе сервер упадет в вечный бут:


getent group polkitd >/dev/null && echo -e "\e[1;32mpolkitd group already exists\e[0m" || { groupadd -r polkitd && echo -e "\e[1;33mAdded missing polkitd group\e[0m" || echo -e "\e[1;31mAdding polkitd group FAILED\e[0m"; }

getent passwd polkitd >/dev/null 
&& echo -e "\e[1;32mpolkitd user already exists\e[0m" || { useradd -r -g polkitd -d / -s /sbin/nologin -c "User for polkitd" polkitd && echo -e "\e[1;33mAdded missing polkitd user\e[0m" || echo -e "\e[1;31mAdding polkitd user FAILED\e[0m"; }

rpm -Va polkit\* && echo -e "\e[1;32mpolkit* rpm verification passed\e[0m" || { echo -e "\e[1;33mResetting polkit* rpm user/group ownership & perms\e[0m"; rpm --setugids polkit polkit-pkla-compat; rpm --setperms polkit polkit-pkla-compat; }

На всех серверах, если был установлен mod_fcgid для Apache, выполним небольшой фикс с правами, иначе сайты, использующие mod_fcgid, будут падать с ошибкой 500:


chmod +s `which suexec` && apachectl restart

И последнее, пригодится для Ubuntu, Debian дистрибутивов. Эта ОС может упасть в вечный бут с ошибкой


looping too fast. throttling execution a little

неприятно, но легко фиксится, в зависимости от версии ОС.


На Debian 9 фикс выглядит так:


выполняем


dbus-uuidgen

если получаем ошибку


/usr/local/lib/libdbus-1.so.3: version `LIBDBUS_PRIVATE_1.10.8′ not found

проверяем наличие LIBDBUS


ls -la /lib/x86_64-linux-gnu | grep dbus
libdbus-1.so.3 -> libdbus-1.so.3.14.15 
libdbus-1.so.3.14.15 <-- нужен этот
libdbus-1.so.3.14.16

если всё в порядке, выполняем


cd /lib/x86_64-linux-gnu
rm -rf libdbus-1.so.3
ln -s libdbus-1.so.3.14.15  libdbus-1.so.3

Если не помогает — пробуем второй вариант.


Второй вариант решения проблемы с throttling execution a little подходит практически для всех Ubuntu и Debian дистрибутивов.


Выполняем


bash -x /var/lib/dpkg/info/dbus.postinst configure

А для Ubuntu 14, Debian 7 дополнительно выполняем:


adduser --system --home /nonexistent --no-create-home --disabled-password --group messagebus

rm -rf /etc/init.d/modules_dep.sh 

Что мы сделали? Восстановили messagebus, которого не хватало для запуска Debian/Ubuntu и удалили modules_dep, который пришел от OpenVZ и мешал загрузки многих модулей ядра.


Шаг 6


Перезагружаем VM, проверяем в VNC как идёт загрузка и в идеале — всё загрузится без проблем. Хотя, возможно, появятся некоторые специфические проблемы после миграции — но они выходят за рамки данной статьи и исправляются по мере появления.


Надеюсь, данная информация будет полезна! :)

Теги:
Хабы:
Всего голосов 12: ↑12 и ↓0+12
Комментарии7

Публикации

Истории

Работа

DevOps инженер
42 вакансии

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань