Сейчас наблюдается большой ажиотаж в отношении технологий контейнерной виртуализации. И почему-то в этом контексте особенно часто упоминается Docker , словно это вообще единственное решение для создания контейнеров. А тем временем существует технология, которая не только ничем не уступает Docker, но и по некоторым оценкам опережает ее как минимум лет на пять. Технология эта называется OpenVZ. О причинах малой популярности OpenVZ мне остается только гадать. Однако, надеюсь, что данная статья хотя бы отчасти исправит положение дел.
Мотивация
В отношении OpenVZ справедливо следующее:
- С точки зрения пользователя контейнеры выглядят, как полноценные VDS со своими дисками и сетевыми интерфейсами. Никаких «слоеных» ФС, никаких коллизий номеров портов на хост-системе, и так далее. Действительно очень удобно;
- Накладные расходы на контейнеризацию оцениваются в 1-3%, что очень мало, особенно если вспомнить о накладных расходах в Docker при работе с диском;
- Очень гибкая настройка того, какому контейнеру сколько и каких ресурсов выделяется. CPU, память, диск, сеть — все под вашим контролем;
- Существуют веб-панели, например, OpenVZ Web Panel и Proxmox (UPD: Proxmox перешел на LXC), благодаря которым можно за пол дня поднять AWS на собственном железе. Это может быть оправдано не только с точки зрения безопасности, но и в связи с последними изменениями в российском законодательстве. Плюс вы сможете менять все квоты на лету, у вас не будет ограничений в стиле «держите все данные на сетевых дисках (EBS)» и так далее;
- OpenVZ уже много лет используется в Parallels, Яндексе, FastVPS, Atlassian, Pixar, Travis CI, WarGaming и ряде других компаний;
Как любая технология контейнерной виртуализации, OpenVZ имеет и ряд ограничений. Вы можете запускать в контейнерах различные дистрибутивы Linux, но не можете запустить Winodws или FreeBSD. Также, например, нельзя загрузить в контейнере произвольный модуль ядра. Такова плата за малые накладные расходы на виртуализацию.
Установка OpenVZ
Официальный сайт рекомендует ставить OpenVZ на СentOS или RHEL. Debian или Ubuntu также поддерживаются , но далее мы будем следовать рекомендации и воспользуемся CentOS 6. Должен предостеречь вас от желания поставить OpenVZ на ноутбук с Ubuntu. В OpenVZ используется собственная сборка ядра Linux , в результате чего, скажем, может отвалиться какое-то железо. Хотя попробовать ничего не мешает, так как вы всегда сможете переключиться на старое ядро. Кстати, чтобы поиграться с OpenVZ, совсем не обязательно использовать отдельный комьютер. OpenVZ отлично работает под Vagrant .
OpenVZ хранит все контейнеры в каталоге /vz. Допустим, есть контейнер с номером 100. Сам контейнер будет лежать в каталоге /vz/private/100/. Когда контейнер запущен, его файловую систему можно найти в каталоге /vz/root/100. А вот настройки контейнеров лежат не в /vz, для контейнера 100 их следует искать в файле /etc/vz/conf/100.conf. Таким образом, перед установкой OpenVZ рекомендуется соответствующим образом разбить диск, ну или хотя бы создать линк /vz туда, где побольше свободного места.
Далее говорим:
sudo rpm —import http: // ftp.openvz.org / RPM-GPG-Key-OpenVZ
sudo yum install vzkernel
sudo yum install vzctl vzquota ploop
Правим /etc/sysctl.conf:
# packet forwarding enabled and proxy arp disabled
net.ipv4.ip_forward = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.default.proxy_arp = 0
# Enables source route verification
net.ipv4.conf.all.rp_filter = 1
# Enables the magic-sysrq key
kernel.sysrq = 1
# We do not want all our interfaces to send redirects
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.send_redirects = 0
SELinux нужно отключить, правим /etc/sysconfig/selinux:
Перезагружаемся:
После перезагрузки uname -a
покажет ту же версию ядра, что мы видели при установке пакета vzkernel. У меня это 2.6.32-042stab111.12
.
Вот и все! Не так уж и сложно, согласны?
Основные команды
Создать контейнер:
—hostname test-container
Важно! Контейнеры должны иметь номера 100 или больше. Прочие номера зарезервированы. В частности, с ними может отказаться работать утилита vzdump, речь о которой пойдет ниже.
Полный список доступных шаблонов можно найти здесь . Первая загрузка шаблона занимает время, 219 Мб как-никак.
Запустить контейнер:
Список контейнеров:
Выполнить команду в контейнере:
Зайти в контейнер:
Сменить пароль пользователя:
Перезапустить контейнер:
Остановить контейнер:
Приостановить/возобновить работу контейнера:
sudo vzctl resume 100
Примонтировать/отмонтировать файловую систему контейнера:
sudo ls / vz / root / 100
sudo vzctl umount 100
Удалить контейнер:
Основные настройки контейнера
Запускать контейнер при старте системы:
Количество ядер:
Выделяем 512 Мб памяти:
Разрешаем использовать 2 Гб под своп:
Выделяем под контейнер 20 Гб на диске:
Меняем имя хоста:
Меняем IP и маску сети:
Меняем DNS:
Резервное копирование, восстановление и клонирование
Утилиты vzdump и vzrestore устанавливаются отдельно. Понадобится скачать два RPM пакета — первый , второй . Затем говорим:
sudo rpm -i cstream-2.7.4- 3 .el5.rf.x86_64.rpm
sudo rpm -i vzdump- 1.2 — 4 .noarch.rpm
Резервное копирование контейнера:
Резервная копия будет называтьcя как-то так:
Восстановление контейнера с присвоением ему номера 101:
Таким же образом можно клонировать контейнеры.
Использование veth-интерфейса
OpenVZ может создавать два типа сетевых интерфейсов — venet (Virtual Network) и veth (Virtual Ethernet). Подробно различия описаны здесь . Если в двух словах:
- venet используется по умолчанию. Он чуть быстрее veth, но требует вручную указывать сетевые настройки контейнера и не позволяет использовать broadcast сообщения из контейнера. Также venet безопаснее (см далее);
- veth разрешает использовать broadcast сообщения из контейнера, что, помимо прочего, позволяет назначать контейнеру сетевые настройки при помощи DHCP. Но veth при этом менее безопасен, чем venet. Поимев рута внутри контейнера, можно получить такой же доступ к сетевому интерфейсу, как и из хост-системы. Это позволяет, например, снифать весь трафик, идущий через интерфейс;
Рассмотрим, как при помощи veth-интерфейса можно пробрасывать трафик из контейнеров в локальную сеть, а также использовать в контейнерах DHCP этой локальной сети.
Примечание: Аналогичную инструкцию для Debian и Ubuntu вы найдете в заметке Туториал по контейнеризации при помощи LXC .
На хост-системе ставим bridge-utils, если пакет еще не установлен:
Далее создаем файл /etc/sysconfig/network-scripts/ifcfg-vmbr0. Здесь и далее нужно использовать имя vmbr0, а не какое-то другое. Это имя используется в скрипте vznetaddbr, речь о котором пойдет далее.
Итак, если хост использует DHCP, в файле пишем:
TYPE=»Bridge»
BOOTPROTO=»dhcp»
IPV6INIT=»no»
IPV6_AUTOCONF=»no»
ONBOOT=»yes»
Если же IP у хоста статический, пишем что-то вроде:
TYPE=»Bridge»
BOOTPROTO=»static»
IPADDR=»10.110.0.12″
NETMASK=»255.255.255.0″
DELAY=»0″
IPV6INIT=»no»
IPV6_AUTOCONF=»no»
ONBOOT=»yes»
В случае со статическим IP в файле /etc/sysconfig/network также указываем шлюз:
Теперь правим /etc/sysconfig/network-scripts/ifcfg-eth0, где eth0 — ваш сетевой интерфейс, а 08:00:27:2D:82:3A — его MAC-адрес:
HWADDR=»08:00:27:2D:82:3A»
ONBOOT=»yes»
BRIDGE=»vmbr0″
Применяем новые настройки сети:
В ifconfig теперь должны увидеть vmbr0.
Далее создаем файл /etc/vz/vznet.conf такого содержания:
Добавляем в контейнер veth-интерфейс:
Заходим в контейнер, правим /etc/sysconfig/network-scripts/ifcfg-eth0:
TYPE=»Ethernet»
BOOTPROTO=»dhcp»
IPV6INIT=»no»
IPV6_AUTOCONF=»no»
ONBOOT=»yes»
Рестартуем контейнер:
Если все было сделано правильно, должны увидеть строчку:
При этом внутри контейнера по DHCP подхватятся настройки сети.
Заключение
В качестве источников дополнительной информации можно рекомендовать:
- Сайт-wiki проекта OpenVZ ;
- Официальный форум OpenVZ ;
- Список рассылки users@openvz.org ;
- Планета OpenVZ ;
- Книга OpenVZ Essentials ;
Лично я считаю, что OpenVZ — прекрасная технология. И мне бесконечно грустно от того, что так много людей прутся от убогого Docker просто потому что сейчас он в моде, и возможно даже не подозревают о существовании куда более зрелых альтернатив.