Заметки дилетанта широкого профиля

RSS

Как я писал замену libvirt для своего карманного хостинга

Для начала стоит подробней рассказать про libvirt. И стоит обратить внимание на момент появления данного инструмента. В момент тот задавали моду среди решений виртуализации продукты VMware. И в эту движуху собрались ворваться Red Hat, у которых, в качестве опоры, был стек из GNU/Linux и сопутствующих технологий. Но уж больно они, технологии эти, были разношёрстными. И написали Red Hat программу, которая предоставляла бы единый интерфейс для управления всем сервером виртуализации, тот самый libvirt собственно.

Надо ли отдельно писать, что чем больше всего разношёрстного пытаешься запихать в одну программу, тем сложней она получается? А Red Hat совсем не желали как-то ограничивать функционал libvirt. Наоборот. Этож фишка такая, что воспользовавшись libvirt можно использовать разные гипервизоры и хранить образы виртуальных машин на разных типах хранилищ. Гибкость, ага. Через усложнение libvirt’а и его конфигурации. Которая всё равно никогда в полной мере не будет покрывать все возможности составных компонентов. Потому что у любой гибкости есть пределы.

А ещё libvirt выполняет некоторые функции, которые, если мы говорим про отдельностоящий сервер, должны выполняются init’ом и штатными инструментами из состава дистрибутива ОС. И в этом нет никакого криминала, если вспомнить, что libvirt разработан раньше, чем тот же systemd. И разработан он под "тонкий" сервер, то есть машину, у которой и своего НЖМД может не быть, а загружаться она будет по iPXE какой-то очень урезанной редакцией ОС, где будут только init, acpid, syslog и, собственно, libvirt. Где именно последний и будет занят настройкой всего, что нужно для запуска виртуальных машин. Вот только незадача: а зачем этот функционал на отдельностоящем сервере, где сеть и хранилища есть забота именно init’а и каких-то специфичных для дистрибутива инструментов? Зачем там этот функционал libvirt’а? Зачем там сам libvirt, вносящий собой дополнительные прослойки и усложнения, когда от его функционала не используется и десятая часть?

Конечно он там не нужен. Более того, тот необходимый минимум, который бы позволил запускать QEMU/KVM в headless-варианте был уже в QEMU на момент появления KVM. А ещё сброс привилегий и уход в фон. То есть строить сервер виртуализации на QEMU/KVM можно было сразу, ещё до момента появления поддержки QEMU в libvirt. Я так и сделал, собственно, в далёком 2009ом году. И в этот раз, коль скоро я принял идею здравого минимализма, как основу для построения сервисов, предполагалось обойтись без libvirt вновь.

Понятное дело, что некоторый функционал libvirt стоило бы реализовать. Но того функционала надо было совсем не много, задачи обеспечения универсальности не стояло, а значит и необходимость что-то реализовывать меня не пугала. Ещё было понятно, что готовых решений для хостинг-провайдеров мне тоже более не светит, так как они завязаны на применение libvirt’а. И это тоже меня не расстраивало, так как реализовать админку с функцией просмотра состояния машин пользователя, — совсем не сложно. Сложно — биллинг развитый написать. Но он мне нужен не был, так как у меня предоплата по безналу, и важней было акты вовремя доставлять закрывающие (да, я почти вернулся в 2007ой год). За сим решение было принято, а я занялся разработкой собственных велосипедов.

Мне нужно было разработать три составные части, чтобы это работало как-то так:

схема функционирования vmld, webd и vncwsd
Упрощённая схема функционирования серверного ПО anotherhosting.ru
  1. Процесс-супервизор (vmld):
    1. способный запускать процессы виртуальных машин строго по-феншую, через fork(), сброс привилегий и exec();
    2. способный отслеживать состояние запущенных машин;
    3. организующий простенький API для управления;
    4. логирование действий пользователя (не графической консоли, но запросов на перезапуск/отключение);
    5. архитектурно — однопоток, с многозадачностью на базе объектно-событийной модели;
  2. Web-интерфейс (webd):
    1. аутентификация;
    2. авторизация;
    3. действия над машинами, через отправку команд в vmld;
    4. отображение лога действий пользователя над его виртуальными машинами;
    5. отображение доступных точек восстановления (да, я предоставлял бесплатные каждодневные бэкапы аж в две недели глубиной);
    6. предоставление информации об сессиях для VNC-WebSocket прокси;
    7. архитектурно — многопоток через PreFork, обмен информацией через IPC/SHMEM;
  3. VNC-WebSocket прокси (vncwsd):
    1. забирать информацию об сессиях из webd;
    2. гонять VNC поверх WebSocket, чтобы пользователь мог рулить машиной через браузер и noVNC (JavaScript-библиотека такая);
    3. архитектурно — однопоток (временно, предполагалось внедрить многопоток, если бы не хватило производительности, но этого не случилось).

Благо опыт позволил сделать всё относительно быстро, ведь многие решения были отработаны до этого. Так vmld опирался на мой опыт, полученный в рамках разработки mailadm. Webd заимствовал механизмы шаблонов, организации многопоточности и общих SHMEM-ресурсов у движка моего блога. Ну а для vncwsd удалось найти подходящий модуль на CPAN. Да, всё это было написано на Perl. Из внешних зависимостей только libfcgi для webd и WebSocket-модуль для vncwsd. Если бы я такое писал на C, то это бы на год растянулось. А если бы на Python, то внешних зависимостей было бы штук 15 — 20, ведь даже асинхронное I/O без специализированного модуля для Python — тяжкая задача.

Теперь же всё это приходится демонтировать. Ведь благодаря начальничкам и нашим великолепным законам, мне теперь не с руки держать хостинг. А для организации удобного мне интерфейса достаточно голой консоли. Надеюсь, что удастся найти должное количество времени, чтобы сформировать из наработок anotherhosting.ru самостоятельные проекты. Но… когда это ещё случится?