Linux + VirtualBox = сервер віртуальних машин

Якщо вам в руки потрапляє такий комп’ютер, а поруч з ним стоять треті пентіуми, які в кінці дев’яностих хтось гордо назвав серверами, то виникає бажання всі задачі перенести на нове залізо, а весь той хлам вимкнути, щоб не гудів даремно. Якщо ви одноосібно адмініструєте це все і все воно «живе» на чомусь одному — на Windows'i чи Linux'i, то проблем немає: налаштовуєте всі сервіси на одному комп’ютері і маєте повний фен-шуй. Проте частіше за все зробити таку «купку невеличку» не вдається: або крім вас різні сервіси адмініструють різні інші люди, або ви не хочете, щоб при зламі веб-сервера зловмисники отримали доступ ще й до електронної пошти чи внутрішнього документообігу, або різні сервери виконують однотипні задачі і просто «посваряться» за певні ресурси, або ...причини завжди знайдуться.

Спеціально для цього випадку розумні люди придумали поняття «віртуалізація» і в купі з ним — різного роду віртуальні машини. Деякі дозволяють ізоляцію лише певних ресурсів, інші створюють видимість повністю відокремленого обладнання. І в тих і в інших є свої переваги і недоліки в певних ситуаціях. В моєму випадку — повний зоопарк операційок (різні Windows'и і Linux'и) — найкращим виходом є повна емуляція обладнання, причому бажано реально існуючого.

Варіанти в даному випадку є наcтупні:

  • Hyper-V — коштує чималих грошей, та й Linux'и на ньому «живуть» почерез раз
  • VMWare — має безкоштовну версію і підтримує всі операційки «на ура», але безкоштовна версія має обмеження на використовувані ресурси сервера, так що з певного моменту upgrade заліза доведеться робити лише після придбання (теж недешевої) ліцензії
  • VirtualBox — проект з відкритим кодом, підтримується компанією Oracle. Безкоштовна версія має обмеження на функціонал: недоступні USB-пристрої і віддалений вхід через RDP-клієнт. Підтримує всі поширені операційки (не впевнений щодо MacOS, але вона все одно окремо не продається :-(, так що в роботі мені зустріч з нею найближчим часом «не світить»).

Флешки в сервери я не тикаю, а організувати віддалений доступ можна і без RDP, так що VirtualBox — «те що доктор прописав».

Подальші налаштування — наслідок послідовного процесу спроб і помилок, але загалом початкову конфігурацію я вгадав непогано, тому все запустилося досить швидко.

В загальних рисах все виглядає так:

  • одна віртуальна машина — один користувач. Створюємо користувачів не як завжди, а надаємо їм домашні каталоги окремо від інших в каталозі /VMS useradd -b /VMS -m -g VMS virtual-host1.your.domain окрема група для них також дозволить в разі потреби визначити, що маємо справу з користувачем-власником віртуальної машини, а також можна надати якісь права на спільні ресурси, тощо.
  • всі віртуальні машини називаємо одинаково: VM. Це дозволить в скриптах запуску та зупинки наперед знати до якого імені звертатися, а не відчитувати його кожен раз звідкись.
  • для кожного мережевого інтерфейсу створюємо «міст» (bridge), в який включаємо цей інтерфейс, а вже подальша конфігурація (якщо потрібно) пишеться на інтерфейсі «моста». Це пов’язано з тим, що віртуальна машина при безпосередньому підключенні до мережевого інтерфейсу виконує певні дії, внаслідок яких цей інтерфейс стає недоступним для інших користувачів — в нашому випадку — інших віртуальних машин. Тому ми в скриптах ініціалізації будемо створювати віртуальні мережні картки для кожної машини, включати кожну в відповідний «міст» і в конфігурації відповідної машини вказувати не реальний пристрій, а віртуальний — його вона може блокувати скільки влізе — нікому крім неї він не потрібен.
  • при вимкненні хоста на вимкнення віртуалок чекати не будемо, натомість просто збережемо їх стан. При ввімкненні окремої команди для відновлення стану не потрібно — команда ввімкнення відновлює збережений стан, якщо такий є, а якщо немає — запускає віртуальну машину наново.

В свіжому Debian'і скрипт завантаження в мене врешті-решт вималювався такий: #!/bin/sh
### BEGIN INIT INFO
# Provides: vmachines
# Required-Start: vboxdrv virtualbox networking
# Required-Stop:
# Should-Start:
# Should-Stop:
# X-Start-Before:
# X-Stop-After:
# Default-Start: 2 3 4 5
# Default-Stop:
### END INIT INFO

SCRIPTNAME=/etc/init.d/virtual-machines

#Список всіх інтерфейсів-«мостів» в системі
brlist=`/sbin/brctl show|grep ^br[0-9]|tr "\t" " "|tr -s " "|cut -d " " -f 1`

./lib/lsb/init-functions

do_start()
{
wd=`pwd`
modprobe vboxdrv
modprobe vboxpci
modprobe vboxnetadp
modprobe vboxnetflt
cd /VMS
for vm in * ; do
#дістаємо ідентифікатори користувача
gid=`id -rg ${vm}`
uid=`id -ru ${vm}`
for br in `echo $brlist`; do
#для кожного «моста» створюємо віртуальний відповідник
tunctl -u ${uid} -g ${gid} -t ${br}vm${uid}
#робимо учасником «моста»
brctl addif ${br} ${br}vm${uid}
#і вмикаємо
ip link set ${br}vm${uid} up
done
#тепер можна і машину ввімкнути
su -l ${vm} -c "/usr/bin/VBoxManage startvm VM --type headless"
done
cd "${wd}"
}

do_stop()
{
wd=`pwd`
cd /VMS
for vm in * ; do
#при вимкненні — зберігаємо стан
su -l ${vm} -c "/usr/bin/VBoxManage controlvm VM savestate"
#тут ще був код вимкнення і знищення віртуальних інтерфейсів, але він
#чомусь приводив до зависання процесу вимикання/перезавантаження,
#тому я його викинув «від гріха подалі»
done
cd «${wd}"
#більшість драйверів не вивантажаться через ті ж-таки «підвішані» мережеві
#інтерфейси. З цим би варто поборотися, але наразі може бути і так...
rmmod vboxnetflt
rmmod vboxnetadp
rmmod vboxpci
rmmod vboxdrv
}

case "$1" in
start)
log_action_begin_msg "Starting VMs"
do_start
case "$?" in
0|1) log_action_end_msg 0 ;;
esac
;;
stop)
log_action_begin_msg "Stopping VMs"
do_stop
case "$?" in
0|1) log_action_end_msg 0 ;;
esac
;;
restart|force-reload|status)
;;
*)
echo «Usage: $SCRIPTNAME start|stop" >&2
exit 3
;;
esac

Тепер до цього всього при бажанні можна «докрутити» ще phpvirtualbox, але добре подумайте чи воно вам треба — все-таки зайва можливість для різних йолопів наламати вам дров в системі. Хоча якщо ви цю схему прикрутили на сервер для VPS-хостингу(хостингу віртуальних серверів) — нікуди вам від нього не подітися.

До речі: для VPS-хостингу схема з розділенням користувачів вирішує проблему відсутності розподілу доступу в phpvirtualbox'i.

Як завжди сподіваюся, що це комусь стане в нагоді.




 

Працює на AutoGenCMS 0.2.6

А чому це всі вирішили, що в сайта має бути шапка?