Система виртуализации OpenVZ

Часть 2.Работаем с контейнерами

Серия контента:

Утилита управления vzctl

Снова рассмотрим команду создания нового контейнера:

vzctl create 101 --ostemplate ubuntu-9.04-x86_64

Здесь 101 – это вручную выбираемый VEID (virtual environment ID) или CTID (container ID), целочисленный номер нового контейнера, который будет использоваться для управления им. Рекомендуется не использовать: а) зарезервированные номера меньше 101 и б) одинаковые номера на разных VPS-фермах, чтобы не иметь потенциальных проблем с миграцией и легче идентифицировать физическое расположение контейнера по его номеру.

После завершения данной команды появятся файл /etc/vz/conf/101.conf с настройками и каталоги: /var/lib/vz/private/101 (заполненный содержимым шаблона) и /var/lib/vz/root/101 (пустой).

Затем выполняется настройка:

vzctl set 101 --save --name example1 --ipadd 192.0.2.101 --hostname example1.homelink.ru --nameserver 192.0.2.2 --onboot yes --privvmpages 72000:80000

В этом примере используются следующие аргументы:

  • «save» приказывает сохранить изменения в conf-файле. Без этого параметра они будут применены к запущенному контейнеру без сохранения;
  • «name» задаёт произвольное читабельное имя, которое затем можно использовать вместо VEID. Например, «vzctl status example1»;
  • «ipadd» назначает контейнеру IP-адрес во внутренней сети OpenVZ;
  • «hostname» изменяет имя системы, используемое внутри контейнера для самоидентификации;
  • «nameserver» конфигурирует контейнер на использование указанного DNS-сервера;
  • «onboot» приказывает запускать контейнер при старте OpenVZ;
  • «privvmpages» устанавливает новые лимиты для одного из параметров.

После этого контейнер можно запустить:

vzctl start example1

Проверить его выполнение:

# vzctl status example1 VEID 101 exist mounted running # vzlist VEID NPROC STATUS IP_ADDR HOSTNAME 20 53 running 192.0.2.101 example1.homelink.ru

Выполнить в нём одиночную команду:

vzctl exec example1 uname -a

Перейти в командную строку контейнера с правами суперпользователя:

vzctl enter example1

Лимиты

OpenVZ ограничивает для контейнеров потребление всех системных ресурсов: процессора, оперативной памяти, дискового пространства, системных буферов, сокетов и т. д. Начальные лимиты настолько строгие, что даже команда «apt-get update» в только что созданном контейнере завершается с сообщением об ошибке.

Управление ограничениями в системе с OpenVZ является двухуровневым: для контейнера в целом – средствами OpenVZ, внутри контейнера – стандартными средствами Linux, через ulimit и дисковые квоты.

Для проверки внешних ограничений служит файл /proc/user_beancounters . Внутри контейнера этот файл заполнен информацией по данному контейнеру, во внешней системе содержит сведения обо всех запущенных окружениях. Основной интерес в нём представляет последний столбец, «failcnt» («failure counter», т. е. «количество сбоев»):

egrep -v " 0$" /proc/user_beancounters

Для вывода в более удобном формате, а также для периодических отчётов рекомендуется использовать несколько небольших утилит, доступных на сайте :

# ubc_failstat Version: 2.5 uid resource held maxheld barrier limit failcnt 20: privvmpages 184917 209713 200000 250000 5 15: numproc 16 130 130 130 31 15: numfile 515 2048 2048 2048 1122 13: tcpsndbuf 0 332416 319488 524288 55341330 # ubc_faildiff /tmp/failstat.yesterday uid resource old new delta 13: tcpsndbuf 50463657 52879924 2416267 15: numfile 856 1122 266 15: numproc 13 31 18

Из вывода ubc_failstat видно, что проблемы имеются в трёх контейнерах (13,15,20) , а ubc_faildiff показывает динамику количества ошибок по сравнению с предыдущим запомненным результатом.

Примеры исправления:

vzctl set 20 --save --privvmpages 250000:300000 vzctl set 15 --save --numproc 200:200 --numfile 4096:4096

vzctl не полностью проверяет корректность вводимых аргументов (например, позволяет задавать разный лимит и барьер для таких параметров, как numproc и numfile, для которых лимит и барьер обязаны совпадать), поэтому рекомендуется проводить дополнительную проверку конфигурационных файлов с помощью утилиты vzcfgvalidate:

for n in /etc/vz/conf/??.conf;do echo Check $n; vzcfgvalidate $n; done

Обратите внимание, что проверяется именно файл (с указанием полного пути), а не текущие параметры, которые могут быть другими, если «vzctl set» запускался без ключа «--save». С другой стороны, vzcfgvalidate удобен тем, что может проверять параметры, когда контейнер не запущен.

Для исправления конфигурационного файла vzcfgvalidate следует запустить с ключом «-r» («repair mode», автоматическое исправление) или «-i» («interactive repair», ручное исправление).

Отличие между лимитом и барьером заключается в следующем: при превышении барьера счётчик ошибок увеличивается, но запрошенная операция выполняется. При превышении лимита операция завершается с ошибкой.

Сеть

OpenVZ создаёт в хост-системе и в каждом контейнере сетевой интерфейс venet0. Хост-система получает IP-адрес 192.0.2.1 и служит для контейнеров шлюзом по умолчанию:

# vzctl exec 101 ip route list 192.0.2.1 dev venet0 scope link default via 192.0.2.1 dev venet0

Если контейнер должен быть доступен только локально (например, в нём выполняется FastCGI-приложение, вызываемое через запущенный в соседнем контейнере Web-сервер), ему следует выделить адрес из диапазона 192.0.2.0/24, например, 192.0.2.$VEID. Если же контейнер должен быть виден из внешнего мира, ему следует назначить IP-адрес из той же сети, в которой находится внешний интерфейс VPS-фермы (допустим, что её IP-адрес на сетевом интерфейсе eth0 равен 1.2.3.10/24):

vzctl set 101 --save --ipadd 1.2.3.11 vzctl set 102 --save --ipadd 1.2.3.12

Проверка:

# vzctl exec 101 ip addr list dev venet0 3: venet0: link/void inet 127.0.0.1/32 scope host venet0 inet 1.2.3.11/32 scope global venet0:2 # ip route list | grep 1.2.3.11 1.2.3.11 dev venet0 scope link

При этом OpenVZ автоматически создаст для IP-адреса контейнера ProxyARP-запись на внешних сетевых интерфейсах VPS-фермы, как если бы была вызвана команда «arp -i eth0 -Ds 10.20.30.11 eth0 pub»:

# arp -ani eth0 ? (1.2.3.10) at 00:11:22:33:44:55 on eth0 ? (1.2.3.11) at * PERM PUP on eth0 ? (1.2.3.12) at * PERM PUP on eth0

Не забудьте также разрешить на VPS-ферме маршрутизацию между интерфейсами eth0 и venet0, например:

# iptables -A FORWARD -i venet0 -j ACCEPT # iptables -A FORWARD -o venet0 -j ACCEPT # sysctl net.ipv4.conf.all.forwarding = 1 # sysctl net.ipv4.ip_forward = 1

IP-адрес 192.0.2.1 на хост-системе является неявным – его нет в свойствах устройства venet0, хотя хост-система видит через tcpdump пакеты, посылаемые на этот адрес из контейнеров. Таким образом, если хост-система хочет предоставлять контейнерам какие-то сервисы, например, DNS или прокси, следует явно назначить интерфейсу venet0 дополнительный IP, например, 192.0.2.2/24. Например, в ALT Linux это делается созданием каталога /etc/net/ifaces/venet0 с двумя файлами:

  • ipv4address: 192.0.2.2/24
  • options: TYPE=venet ONBOOT=yes

Обратите внимание на «ONBOOT=yes». Благодаря ему интерфейс venet0 появится не в момент запуска OpenVZ, а существенно раньше – в момент запуска сети, т. е. перед запуском сетевых сервисов, и не будет исчезать при остановках OpenVZ. Это позволит явно привязать сервисы к venet0 и сделать их недоступными на остальных интерфейсах, не прибегая к помощи файрволла.

Пакет etcnet в ALTLinux содержит несколько относящихся к venet мелких ошибок, не влияющих на работоспособность, но приводящих к неверной диагностике при любых вызовах /etc/init.d/network. Исправление для них доступно на сайте bugzilla.altlinux.org .

Кроме venet (Virtual Network), OpenVZ способен предоставлять контейнерам ещё один тип устройств, veth (Virtual Ethernet). Veth предоставляет больше возможностей , но сложнее в настройке , менее производителен и требуется в исключительных случаях, поэтому здесь не описывается.

Доступ к устройствам

Из виртуальных окружений прямой доступ отсутствует и к железу, и к ядру. Каталог /dev почти пуст и содержит только логические устройства: null, zero, random, tty, console и т. д.

Сервисы, для работы которых требуется загрузка модулей ядра, смогут работать при выполнении трёх условий:

  • данный модуль загружен во внешней системе;
  • файл соответствующего устройства перенесён в /dev контейнера командой «vzctl set 11 --devnodes»;
  • модуль ядра во внешней системе и использующий его сервис в контейнере используют совместимые версии ABI («Application binary interface», «двоичный интерфейс для приложений»).

Если используемый в контейнере сценарий запуска сервиса в /etc/init.d пытается загружать необходимые сервису модули ядра с помощью команды modprobe, он не должен проверять результат загрузки ни через код завершения modprobe, так как modprobe завершится с ошибкой, ни с помощью команды lsmod, так как lsmod выведет пустой список.

Рассмотрим пример использования файловой системы FtpFs внутри контейнера:

  • для организации доступа используется пакет curlftpfs, входящий в большинство дистрибутивов. Этот пакет должен быть инсталлирован внутри контейнера;
  • curlftpfs использует fuse (Filesystem in USErspace) для получения из ядра обращений к файловой системе, которые он преобразует в вызовы библиотеки curl для обращения к FTP-серверу;
  • Fuse состоит из двух компонентов: драйвер файловой системы в ядре и библиотека-диспетчер в пространстве пользователя, которой драйвер передаёт все запросы;
  • драйвер и библиотека обмениваются данными через устройство /dev/fuse;
  • хотя программы и библиотеки запускаются внутри контейнера, драйвер и средства управления им должны быть инсталлированы в хост-системе;
  • каталог /dev в хост-системе и каталог /dev в контейнере – это разные каталоги; драйвер создаёт /dev/fuse в хост-системе и, чтобы /dev/fuse стал доступен в контейнере, требуется специальное указание.

Таким образом, настройка сводится к следующим шагам:

  • в контейнере инсталлируется curlftpfs. Вместе с ним автоматически установятся libfuse и libcurl, от которых он зависит;
  • в /etc/modules хост-системы вручную добавляется строка «fuse», чтобы драйвер, хранящийся в данном модуле ядра, автоматически загружался при старте системы;
  • альтернативно – во внешней системе инсталлируется пакет fuse; входящий в него сценарий /etc/init.d/fuse обеспечивает корректную загрузку драйвера,
  • для немедленного запуска драйвера выполняется команда «modprobe fuse» или «/etc/init.d/fuse start»,
  • созданный драйвером файл /dev/fuse копируется из внешней системы в контейнер: vzctl set 11 --devnodes fuse:rw --save
  • благодаря «--save» в /etc/vz/conf/11.conf добавится строка «DEVNODES="fuse:rw "», следуя которой OpenVZ будет автоматически создавать /dev/fuse внутри контейнера при его запуске.

Virtuozzo

OpenVZ разрабатывается фирмой Parallels как часть более крупного коммерческого продукта под названием Parallels Virtuozzo Containers или PVC (ранее называвшегося просто Virtuozzo). В число преимуществ Virtuozzo, по сравнению с OpenVZ, входят:

  • файловая система VZFS;
  • управление через графическую консоль и Web-интерфейс;
  • программный интерфейс на базе XML для создания собственных инструментов управления и контроля;
  • средства миграции с физической системы в контейнер и обратно;
  • средства контроля за полосой и суммарным потреблением трафика;
  • интеграция с Plesk , коммерческой панелью управления хостингом той же фирмы;
  • круглосуточная техническая поддержка.

VZFS позволяет совмещать файловые системы контейнеров, при этом базовый образ используется всеми контейнерами, а изменения в нём для каждого контейнера сохраняются раздельно (аналог UnionFS). Преимущества такого подхода:

  • место, занимаемое программами на диске, становится фиксированным и не зависит от количества контейнеров, в которых эти программы инсталлированы;
  • уменьшается расход ОЗУ, так как код нескольких экземпляров программы или библиотеки, запущенной из одного и того же исполняемого файла, размещается в ОЗУ в единственном экземпляре;
  • обновление программного обеспечения в группе контейнеров выполняется одной командой.

Термины и сокращения

  • HN, Hardware Node – хост-система, физический компьютер с непосредственно инсталлированной на него операционной системой, служащие платформой для запуска виртуальных окружений;
  • VE, Virtual Environment – виртуальное окружение, имитирующее отдельный компьютер и/или отдельную операционную систему за счёт части ресурсов настоящего компьютера и запущенной на нём ОС;
  • CT, Container – более современный синоним VE;
  • VEID и CTID – числовой идентификатор контейнера, используемый для управления им;
  • CT0 и VE0 – синоним хост-системы;
  • UBC, User Beancounters – набор ограничений на потребление системных ресурсов, назначаемый контейнеру;
  • VPS, Virtual Private Hosting, виртуальный приватный хостинг – хостинг с поддержкой одной операционной системы (а также, возможно, единственного набора программ), в котором виртуализируется программное окружение. Ядро ОС запущено в единственном экземпляре, доступа к нему клиенты-владельцы виртуальных окружений не имеют;
  • VDS, Virtual Dedicated Hosting, виртуальный выделенный хостинг – хостинг с поддержкой различных операционных систем, в котором виртуализируется аппаратное окружение. В каждой виртуальной среде загружается своё ядро, доступное для управления клиенту-владельцу данной среды.

Заключение

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

Ресурсы для скачивания

static.content.url=http://www.сайт/developerworks/js/artrating/

ArticleID=472857

ArticleTitle=Система виртуализации OpenVZ: Часть 2.Работаем с контейнерами

Система виртуализации OpenVZ

Часть 1.Введение

Серия контента:

Назначение систем виртуализации

Виртуализация – это термин, обозначающий, в частности, имитацию отдельного компьютера и/или отдельной операционной системы с помощью специального программного обеспечения.

В настоящее время виртуализация популярна по нескольким причинам.

Во-первых, она уменьшает потребность в физических компьютерах, так как одна машина получает возможность одновременно выполнять несколько разнотипных операционных систем. При этом улучшается утилизация вычислительных ресурсов, так как для большинства задач современное оборудование обладает избыточной мощностью.

Во-вторых, повышается безопасность за счёт возможности переноса в изолированные окружения таких сервисов, как Samba и Apache, работающих с правами суперпользователя и имеющих большое количество выявленных и потенциальных уязвимостей. Если различные сервисы управляются разными администраторами, каждый администратор может получить права суперпользователя в своём окружении, в то же время не имея доступа ни к соседним окружениям, ни к основной системе.

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

В-третьих, упрощается обслуживание. Например, так как гостевые окружения не содержат аппаратно-зависимых настроек, упрощается их перенос (миграция) с одного компьютера на другой. Создание новых виртуальных окружений происходит намного быстрее, чем инсталляция новой системы на компьютер. Настройки сервисов, разнесённых по разным окружениям, перестают пересекаться, что облегчает их сопровождение. Настройка дисков, межсетевого экрана, резервное копирование и прочие задачи выполняются однократно в основной системе.

Краткое сравнение популярных систем

Программное обеспечение для виртуализации полезно оценивать по следующим критериям:

  • необходимость аппаратной поддержки (например, Intel VT и AMD SVM);
  • возможность использовать аппаратную поддержку при её наличии;
  • установка и запуск из-под существующей операционной системы (Windows, Linux) или на «голое железо»;
  • способность запускать операционные системы, отличные от установленной;
  • наличие и необходимость драйверов паравиртуализации для запускаемых операционных систем;
  • необходимость графической консоли для работы.

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

С другой стороны, OpenVZ выигрывает по предъявляемым требованиям: аппаратная поддержка виртуализации ему не требуется, потребление ресурсов и разница в быстродействии между базовой и виртуальной средой минимальны, установка и управление упрощены до предела.

Таким образом, главной нишей применения OpenVZ являются:

  • хостинги Linux-VPS;
  • серверы, на которых запущено несколько сервисов с правами суперпользователя (разнесение по изолированным окружениям повысит безопасность) или со сложными настройками (разнесение упростит сопровождение).

В этой нише по набору возможностей OpenVZ превосходит FreeBSD Jails и linux-vserver, и приближается к Solaris Zones.

Данная статья в первую очередь адресована не специалистам хостинг-провайдеров, так как изложенная здесь информация им давно известна, а рядовым Linux-администраторам, серверы которых подпадают под второй пункт.

Архитектура

OpenVZ разрабатывается как патч (набор улучшений и дополнений) к исходным текстам ядра Linux. В модифицированном ядре добавлен массив дополнительных сущностей – виртуальных окружений (virtual environments, VE), а для всех имеющихся объектов (процессы, сокеты и т. д.) введены дополнительные поля – номер VE, к которому этот объект относится, и номер объекта внутри VE.

Каждое виртуальное окружение имеет собственный набор квот на потребление системных ресурсов и отдельный каталог для использования в качестве корневой файловой системы.

Дополнительные модули ядра – vzdev, vzmon и прочие – отвечают за работу ограничений, мониторинг, эмуляцию сети в VE, сохранение и восстановление текущего состояния запущенных контейнеров.

К преимуществам OpenVZ по сравнению с более универсальными инструментами виртуализации, такими как Xen и KVM, является прозрачный доступ из внешней системы к процессам, файлам и прочим ресурсам в гостевых. Например, если потребуется остановить во всех контейнерах сервис, в котором обнаружилась уязвимость, во внешней системе («хост-системе») достаточно выполнить команду «killall имя_исполняемого_файла».

Данный пример выводит номера (PID) всех процессов init с номерами контейнеров, в которых они запущены:

# ps -A | grep -w init | awk "{print $1}" | xargs vzpid Pid VEID Name 1 0 init 6905 11 init 7462 12 init

Процессы init, запущенные в контейнерах 11 и 12, внутри контейнеров, как им и положено, имеют PID 1, при этом в хост-системе они видны как PID 6905 и 7462. Номер контейнера, которому принадлежит процесс с указанным PID, сообщает утилита vzpid.

Установка OpenVZ

В ALT Linux Server поддержка OpenVZ присутствует из «коробки», ядро и утилиты находятся на инсталляционном CD-ROM"е и устанавливаются по умолчанию:

$ rpm -qa | grep vz vzctl-3.0.22-alt3 alterator-ovz-0.4-alt8 spt-profiles-ovz-0.2.2-alt1 vzquota-3.0.11-alt1 kernel-image-ovz-smp-2.6.27-alt6

Debian, начиная с текущей стабильной версии 5.0 «Lenny», также содержит OpenVZ в стандартном репозитории. Его установка выполняется следующей командой («-686» для 32-разрядной системы, «-amd64» для 64-разрядной):

sudo aptitude install vzctl vzquota linux-image-openvz-686

В Ubuntu ситуация обратная: OpenVZ поддерживался в версии 8.04, а из 8.10 был исключён в связи с появлением KVM. Так как версия 8.04 имеет увеличенный срок поддержки до 2013 года, с точки зрения безопасности допустимо подключить её репозитарий к более новой системе. Это делается созданием файла /etc/apt/sources.list.d/8.04-hardy-main со следующим содержимым:

deb http://mirror.yandex.ru/ubuntu hardy main deb http://mirror.yandex.ru/ubuntu hardy-updates main deb http://mirror.yandex.ru/ubuntu hardy-security main

Чтение подключённого репозитария и установка OpenVZ:

sudo apt-get update sudo apt-get install vzctl vzquota linux-openvz

Естественно, при этом в обмен на поддержку OpenVZ придётся пожертвовать функциональностью, появившейся в новых версиях ядра после выхода Ubuntu 8.04.

Поддержка Fedora, RHEL (RedHat Enterprise Linux) и CentOS выполняется самими разработчиками OpenVZ. Со своей стороны, разработчики Fedora добавили драйвер для OpenVZ в libvirt , универсальную библиотеку управления виртуальными окружениями, включаемую во многие Linux-дистрибутивы.

  1. Подключение yum-репозитария: cd /etc/yum.repos.d wget http://download.openvz.org/openvz.repo rpm --import http://download.openvz.org/RPM-GPG-Key-OpenVZ
  2. Отключение SELinux (строка «SELINUX=disabled» в файле /etc/sysconfig/selinux) и настройка sysctl.
  3. Установка ядра, перезапуск, установка утилит: yum install ovzkernel reboot yum install vzctl vzquota

Для всех дистрибутивов некоторые переменные ядра рекомендуется установить в следующие значения:

net.ipv4.conf.default.forwarding=1 net.ipv4.conf.default.proxy_arp = 0 net.ipv4.ip_forward=1 net.ipv4.conf.all.rp_filter = 1 kernel.sysrq = 1 net.ipv4.conf.default.send_redirects = 1 net.ipv4.conf.all.send_redirects = 0

Добавьте эти строки в /etc/sysctl.conf и примените командой «sudo sysctl -p».

После завершения установки можно запустить OpenVZ командой «/etc/init.d/vz start» и включить автоматический запуск при старте системы командой chkconfig или update-rc.d.

Структура каталогов

Ниже перечислены наиболее важные файлы и каталоги OpenVZ:

  • /etc/vz/vz.conf – файл с общими настройками;
  • /etc/vz/conf/*.conf – файлы с настройками контейнеров;
  • /var/lib/vz/private – каталог с корневыми файловыми системами контейнеров;
  • /var/lib/vz/root – каталог с точками монтирования корневых файловых систем запущенных контейнеров;
  • /var/lib/vz/template/cache – каталог для архивов с образами корневых файловых систем для заполнения создаваемых контейнеров;
  • /proc/user_beancounters – счётчики ограничений.

В тот момент, когда контейнер остановлен, его каталог в /var/lib/vz/root пуст, и редактирование данных следует производить в /var/lib/vz/private. Когда контейнер запущен, рекомендуется вносить изменения в.../root и ничего не менять в.../private. Синхронизация произойдёт автоматически.

В первых версиях OpenVZ каталог /var/lib/vz располагался в /vz, т.е. непосредственно в корневом каталоге. Некоторые описания рекомендуют создавать символьную ссылку с нового имени на старое («ln -sf /var/lib/vz /»), чтобы гарантировать правильность работы устаревших инструментов.

Шаблоны

При архивации файловой системы в шаблон желательно также очистить от ненужной информации каталоги /var/log, /var/spool, /var/cache и т. д.

Обновление шаблона свежими версиями программного обеспечения должно происходить по следующей схеме (на примере обновления ALT Linux с 4.1 до 5.0):

  • создаётся и запускается новый контейнер: vzctl create 101 --ostemplate altlinux-4.1-x86_64 vzctl start 101
  • в контейнере в /etc/apt/sources.list оставляется единственный файл branch50.list: rpm http://mirror.yandex.ru/altlinux/5.0/branch x86_64 classic rpm http://mirror.yandex.ru/altlinux/5.0/branch noarch classic #rpm http://mirror.yandex.ru/altlinux/updates/5.0 x86_64 updates #rpm http://mirror.yandex.ru/altlinux/backports/5.0 x86_64 backports
  • запускается обновление: vzctl enter 101 apt-get update apt-get dist-upgrade apt-get clean
  • удаляются файлы *.rpmnew (свежие варианты настроек, конфликтующие с изменёнными вариантами из шаблона) и *.rpmsave (старые настройки, не использующиеся в обновлённой системе)
  • контейнер останавливается, его каталог запаковывается в новый шаблон: vzctl stop 101 tar -C /var/lib/vz/private/101 \ -czf /var/lib/vz/template/cache/altlinux-5.0-x86_64.tar.gz.

Конфигурации

Информация в данном разделе не требуется для практического использования в большинстве случаев, но будет полезной для общего понимания структуры OpenVZ.

Кроме файловой системы, создаваемому контейнеру назначается конфигурация . Как правило, «vzctl create» определяет её автоматически по имени файла-шаблона, но при необходимости можно указать её вручную параметром «--config». После создания контейнера имя его конфигурации хранится в его файле настроек (/etc/vz/conf/*.conf) – либо в строке «CONFIG=...», либо вычисляется по строке «OSTEMPLATE=...».

Конфигурации хранятся в каталоге /etc/vz/dists и содержат списки команд для управления настройками в системе, работающей внутри контейнера. Например, назначение IP-адреса для контейнера производится следующей командой:

vzctl set 101 --ipadd 192.0.2.101

В зависимости от конфигурации, наряду с сохранением IP-адреса в /etc/vz/conf/11.conf, внутри запущенного контейнера будут выполнены следующие действия:

  • для Slackware: записать IP-адрес в файл /etc/rc.d/rc.inet1.conf
    и выполнить команду «/etc/rc.d/rc.inet restart»;
  • для Debian и Ubuntu: записать IP-адрес в /etc/network/interfaces
    и выполнить «/etc/init.d/networking restart»;
  • для ALT Linux: записать IP-адрес в /etc/net/ifaces/venet0/ipv4address
    и выполнить «ifup venet0».

Кроме перечисленных систем, готовые конфигурации имеются для Arch, Centos/Fedora/RHEL, Mandrake, SLES/OpenSUSE, Openwall, старых версий RedHat и SuSE. Конфигурация по умолчанию (dists/default) предназначена для систем от Redhat. Скелет для создания собственных конфигураций с подробными комментариями находится в dists/distribution.conf-template.

Заключение

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

Ресурсы для скачивания

static.content.url=http://www.сайт/developerworks/js/artrating/

ArticleID=471423

ArticleTitle=Система виртуализации OpenVZ: Часть 1.Введение

OpenVZ позволит Вам запустить еще один (или несколько) экземпляр Linux (в нашем случае Debian) на вашем хосте.

Установка в Debian

Для нормальной работы OpenVZ требуется ядро с vz-патчами. В Debian такие ядра имеют суффикс -openvz и для архитектуры i386 собраны с поддержкой памяти более 4 гигабайт. Установим ядро:

apt-get install linux-image-2.6.26-2-openvz-686

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

Дополнительно

Для работы с VZ необходимы:

    утилита управления vzctl

    утилита для создания образа системы debootstrap

  • произвольный текстовый редактор
apt-get install vzctl debootstrap vim

Подготовка гостевой системы

Для начала выберите место, где будет находиться Ваша гостевая OS. В данном руководстве будем считать, что гостевая система будет расположена в каталоге /vz/guest . Создадим базовый образ гостевой системы:

mkdir /vz/guest debootstrap lenny /vz/guest

Примечание : Необходимо отметить, что создание образа гостевой системы в OpenVZ предполагается осуществлять при помощи скачивания и распаковки tgz-шаблона операционной системы. Однако в случае Debian совсем необязательно качать сотни мегабайт данных: в Debian имеется утилита debootstrap, которая прекрасно справляется с задачей создания минимальной системы.

Подготовка гостевой системы традиционным для VZ способом

Этот способ стоит применять, если Вы хотите в гостевой системе установить не Debian, а другую операционную систему. Для этого нужно скачать шаблон интересующей нас системы с сайта . Затем можно распаковать этот шаблон в каталог /vz/guest , либо положить шаблон в каталог /var/lib/vz/template/cache . Во втором случае, для того, чтобы создать гостевую систему необходимо выдать команду:

vzctl create 10 --ostemplate имя_шаблона --private /vz/guest

где, 10 - идентификатор создаваемой системы, имя_шаблона - имя скачанного шаблона, /vz/guest - путь куда будет установлена гостевая система (распакован шаблон). В случае создания системы из шаблона файл 10.conf в /etc/vz/conf будет создан автоматически.

Выбор идентификатора Вашей гостевой системы

OpenVZ различает гостевые системы по их номеру. Хороший способ задания номера гостевой системы -- последний октет её ip-адреса. К сожалению, сейчас не имеется общепринятого способа отображения номеров VZ в человекочитаемые имена. Утилита vzctl может назначать синонимы для номеров VZ и работать с ними. Однако некоторые из других утилит для VZ могут их не понимать.

Для задания имени-синонима гостю с номером 256 можно создать симлинк:

/etc/vz/names/guestname -> /etc/vz/conf/256.conf

либо использовать для этой цели vzctl :

vzctl set 256 --name guestname --save

В дальнейшем можно будет использовать вместо номера VZ его имя (для данного примера - guestname ), но это уже после того как гость создан и номер ему назначен, а пока будем считать, что мы создаем гостя с номером 10.

Начало работы с гостем

Идем в каталог /etc/vz/conf и копируем файл-шаблон конфига ve-light.conf-sample в файл с именем 10.conf , где 10 - выбранный нами идентификатор системы. В этом файле мы исправим всего один параметр (вернее, добавим):

OSTEMPLATE="debian"

Это необходимо потому, что утилита vzctl , которой мы будем пользоваться далее, не умеет вносить изменения в это поле, а создание гостя из шаблона мы, по описанным выше причинам, пропустили.

Дальнейшее конфигурирование системы мы будем вести при помощи утилиты vzctl . Для того, чтобы изменить какой-то из параметров гостя, используется команда

vzctl set <номер гостя> --параметр значение --параметр значение --save

Открываем man vzctl и идем по параметрам сверху вниз, попутно собирая одну большую конфигурационную команду:

vzctl set 10 \ --onboot yes \ --private /vz/private \ --ipadd 1.2.3.4 \ --nameserver 4.3.2.1 \ --searchdomain mydomain.ru \ --numproc 100 \ --privvmpages 32768 --save

Большинство параметров, указанных здесь, можно опустить, а некоторые из них -- указать прямо во время создания гостя (смотрите вывод vzctl --help). Единственный необходимый на данный момент параметр -- --private : с его помощью мы укажем vztcl, где искать файлы гостевой системы. Более подробно некоторые параметры будут рассмотрены ниже, а пока, выполнив вышеприведенную команду, мы можем уже запустить гостя:

vzctl start 10

Для того, чтобы остановить гостя, наберите

vzctl stop 10

Ну и самое интересное -- зайти в запущенного гостя рутом:

vzctl enter 10

На этом шаге Вы можете приступить к собственно конфигурированию гостя: установке сервера ssh, любимого редактора, шелла и т.п. Скорее всего, Вы сразу наткнетесь на ограничения, выставленные гостю по умолчанию, например "слишком маленький диск" или "слишком мало памяти", ниже мы рассмотрим (а выше мы частично уже рассмотрели), как изменять эти ограничения, добавлю лишь, что изнутри гостя всегда можно посмотреть, какие ограничения у Вас установлены:

cat /proc/user_beancounters

Эта команда работает и на хост-системе, выведя ограничения для всех гостей, а также максимальные значения параметров (контейнер с номером 0 ).

Перезапускать гостя после изменения каких-то из его параметров чаще всего необязательно, например, параметры, связанные с ограничениями памяти, дисковой гостя всё-таки понадобилась, то сделать это можно с использованием той же утилиты:

vzctl restart 10

Параметры гостя

VZ позволяет устанавливать множество параметров для гостевой системы. На этом вики вы можете найти , а вот некоторые из них:

Параметр

vps.conf

Значение

Описание

Общие и сетевые параметры

Задает имя гостевой системе, которое можно использовать вместо числового идентификатора

Путь к расположению гостя в файловой системе

Путь отображения файловой системы гостя при старте

Запускать ли гостя при загрузке системы

Добавить IP адрес к гостевой системе

Удалить IP адрес из гостевой системы

Установить hostname гостевой системе

Установить используемый DNS-сервер гостевой системе

Установить домен поиска гостевой системе

интерфейс,параметры

установить сетевой интерфейс в гостевой системе

интерфейс

удалить сетевой интерфейс из гостевой системы

интерфейс

передать гостевой системе интерфейс из хостовой системы

интерфейс

удалить из гостевой системы интерфейс

Число одновременно запущенных процессов

Число TCP-сокетов

Число не-TCP-сокетов

Количество 4096-байтных блоков памяти выделенных гостю

Количество одновременно открытых файлов

Количество возможных файловых блокировок

Количество CPU делегируемых гостю

Объем дискового пространства, выделенный гостю

Необходимо отметить, что во многих случаях вместо просто числа можно писать два числа через двоеточие. Первое число будет означать "барьер" лимита параметра. А второе собственно лимит. При прохождении гостем "барьера" будет срабатывать счетчик, значение которого Вы можете посмотреть в файле /proc/user_beancounters в последней графе.

Многие параметры можно вводить несколько раз (с разными значениями), например, для добавления двух сетевых интерфейсов в гостя можно ввести два раза --netif_add с разными значениями.

Важно : Необходимо отметить, что некоторые параметры собственно гостевой системы нельзя или бессмысленно менять из гостевой системы. Это касается всех параметров, которые изменяются при помощи утилиты vzctl: при каждом новом старте гостя VZ изменяет его настройки на установленные в конфиг-файле этого гостя.

Вместо использования утилиты vzctl можно использовать традиционный способ правки конфигурационного файла. Каждый из параметров, изменяемых vzctl отображается в параметр вида

имя=значение

конфигурационного файла. Значения этих параметров можно посмотреть в man vz.conf и man vps.conf . После изменения произвольного параметра этим способом гостя необходимо перезапустить.

Оптимизации

Утилита debootstrap создает минимальный Debian для использования его в произвольном месте (не только в виртуальной системе), поэтому некоторые вещи во вновь созданной системе могут показаться Вам лишними. Например процессы getty явно не нужны в гостевой системе. Чтобы выключить их, откройте на редактирование файл /etc/inittab , найдите в нем строки, содержащие /sbin/getty и закоментируйте их. Затем выдайте внутри гостя команду telinit q , либо перезапустите гостя для уничтожения ненужных процессов.

Сейчас наблюдается большой ажиотаж в отношении технологий контейнерной виртуализации. И почему-то в этом контексте особенно часто упоминается 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 wget -P / etc/ yum.repos.d/ http:// ftp.openvz.org/ openvz.repo
sudo rpm --import http:// ftp.openvz.org/ RPM-GPG-Key-OpenVZ
sudo yum install vzkernel
sudo yum install vzctl vzquota ploop

Правим /etc/sysctl.conf:

# On Hardware Node we generally need
# 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:

SELINUX=disabled

Перезагружаемся:

После перезагрузки uname -a покажет ту же версию ядра, что мы видели при установке пакета vzkernel. У меня это 2.6.32-042stab111.12 .

Вот и все! Не так уж и сложно, согласны?

Основные команды

Создать контейнер:

sudo vzctl create 100 --ostemplate centos-6 -x86_64 \
--hostname test-container

Важно! Контейнеры должны иметь номера 100 или больше. Прочие номера зарезервированы. В частности, с ними может отказаться работать утилита vzdump, речь о которой пойдет ниже.

Полный список доступных шаблонов можно найти . Первая загрузка шаблона занимает время, 219 Мб как-никак.

Запустить контейнер:

sudo vzctl start 100

Список контейнеров:

sudo vzlist -a

Выполнить команду в контейнере:

sudo vzctl exec 100 ps

Зайти в контейнер:

sudo vzctl enter 100

Сменить пароль пользователя:

sudo vzctl set 100 --userpasswd root:PASSWORD

Перезапустить контейнер:

sudo vzctl restart 100

Остановить контейнер:

sudo vzctl stop 100

Приостановить/возобновить работу контейнера:

sudo vzctl suspend 100
sudo vzctl resume 100

Примонтировать/отмонтировать файловую систему контейнера:

sudo vzctl mount 100
sudo ls / vz/ root/ 100
sudo vzctl umount 100

Удалить контейнер:

sudo vzctl delete 100

Основные настройки контейнера

Запускать контейнер при старте системы:

sudo vzctl set 100 --save --onboot yes

Количество ядер:

sudo vzctl set 100 --save --cpus 1

Выделяем 512 Мб памяти:

sudo vzctl set 100 --save --ram 512M

Разрешаем использовать 2 Гб под своп:

sudo vzctl set 100 --save --swap 2048M

Выделяем под контейнер 20 Гб на диске:

sudo vzctl set 100 --save --diskspace 20G

Меняем имя хоста:

sudo vzctl set 100 --save --hostname centos.example.com

Меняем IP и маску сети:

sudo vzctl set 100 --save --ipadd 10.110.0.13/ 24

Меняем DNS:

sudo vzctl set 100 --save --nameserver 8.8.8.8 --nameserver 8.8.4.4

Резервное копирование, восстановление и клонирование

Утилиты vzdump и vzrestore устанавливаются отдельно. Понадобится скачать два RPM пакета — первый , второй . Затем говорим:

sudo yum install perl-LockFile-Simple.noarch
sudo rpm -i cstream-2.7.4-3 .el5.rf.x86_64.rpm
sudo rpm -i vzdump-1.2 -4 .noarch.rpm

Резервное копирование контейнера:

sudo vzdump --compress 100

Резервная копия будет называтьcя как-то так:

/vz/dump/vzdump-openvz-100-2015_01_02-12_13_14.tgz

Восстановление контейнера с присвоением ему номера 101:

sudo vzrestore / path/ to/ archive.tgz 101

Таким же образом можно клонировать контейнеры.

Использование veth-интерфейса

OpenVZ может создавать два типа сетевых интерфейсов — venet (Virtual Network) и veth (Virtual Ethernet). Подробно различия описаны . Если в двух словах:

  • venet используется по умолчанию. Он чуть быстрее veth, но требует вручную указывать сетевые настройки контейнера и не позволяет использовать broadcast сообщения из контейнера. Также venet безопаснее (см далее);
  • veth разрешает использовать broadcast сообщения из контейнера, что, помимо прочего, позволяет назначать контейнеру сетевые настройки при помощи DHCP. Но veth при этом менее безопасен, чем venet. Поимев рута внутри контейнера, можно получить такой же доступ к сетевому интерфейсу, как и из хост-системы. Это позволяет, например, снифать весь трафик, идущий через интерфейс;

Рассмотрим, как при помощи veth-интерфейса можно пробрасывать трафик из контейнеров в локальную сеть, а также использовать в контейнерах DHCP этой локальной сети.

Примечание: Аналогичную инструкцию для Debian и Ubuntu вы найдете в заметке .

Виртуализация позволяет сделать работу системного администратора простой и логичной, снизить расходы на оборудование и вдохнуть новую жизнь в простаивающие сервера. Но если ты считаешь, что за все это приходится платить сложностью и запутанностью самой технологии, то эта статья как раз для тебя. Я покажу, что поднять сотню-другую виртуальных серверов не сложнее, чем настроить среднестатистический web-сервер.

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

Сегодня существует множество технологий виртуализации, среди которых есть как простые виртуальные машины, используемые на ПК обычных пользователей, так и целые облачные инфраструктуры, позволяющие управлять десятками тысяч виртуальных машин, разбросанных по всему миру. Особое место среди них занимают так называемые «системы виртуализации уровня операционной системы » или, как их иногда называют сисадмины, «псевдовиртуальные машины».

Виртуализация уровня ОС

В отличие от «настоящих» виртуальных машин, которые программно воссоздают аппаратную начинку ПК, системы виртуализации уровня ОС виртуализируют операционную систему, позволяя как бы расщепить ее на несколько независимых друг от друга ОС.

Проще всего понять это на примере дистрибутива GNU/Linux. Грубо его можно разделить на два логических компонента: ядро, имеющее максимальные привилегии и управляющее всем оборудованием, и компоненты пространства пользователя, представляющие собой набор демонов, библиотек, систему инициализации, ПО и прочее, которые получают доступ к оборудованию через вызовы функций ядра (системные вызовы). В обычной ситуации все компоненты пространства пользователя работают в одном «контексте исполнения » или, говоря образным языком, находятся в одной комнате: они могут видеть друг друга, имеют доступ к одному дереву файлов, делят между собой оборудование и все остальные ресурсы. Использование прав доступа позволяет им вполне успешно сосуществовать, не нанося друг другу вреда, однако может наступить момент, когда кто-то начнет теснить остальных, а другой, найдя способ обхода прав доступа, захватит власть над операционной системой.

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

Для решения этой проблемы виртуализация уровня ОС позволяет создать множество контекстов исполнения, каждый со своим деревом файлов, собственными процессами, сетевым стеком, правами на доступ к оборудованию и так далее. Проще говоря, она делает из одной операционной системы - несколько независимых, каждая из которых может иметь различные права на ресурсы, наиболее подходящие в ее конкретном случае. Такая виртуализация выгодно отличается от «настоящих» виртуальных машин: она проще в настройке, легко масштабируется и накладывает совсем незаметный (около 1%) оверхед на скорость работы ОС. Серьезный недостаток у нее всего один: возможность исполнения операционных систем только одного типа.

Почему OpenVZ?

В мире UNIX существует много различных реализаций виртуализации уровня операционной системы. Одними из первых в свою ОС ее внедрили разработчики FreeBSD. Система получила название Jail («Тюрьма») и долгое время оставалась образцом для подражания в глазах разработчиков других открытых ОС, но в последнее время сдала позиции как наименее развитая в плане функциональности.

Наверное, лучшую реализацию системы создала компания Sun для операционной системы Solaris 10, однако Solaris Zones, равно как и сама ОС, не получила широкого распространения (кстати, мы писали о Solaris Zones в одном из предыдущих номеров журнала).

Многие разработчики неоднократно предпринимали попытки воссоздать обе реализации для Linux, и на сегодня в этой области сформировалось три заметных лидера. Во-первых, это развиваемая сообществом система Linux-VServer (о ней мы также уже писали). Во-вторых, это не так давно появившийся, но очень перспективный проект LXC (LinuX Containers), который отличается очень функциональной реализацией, а также тем, что использует в своей основе стандартные механизмы ядра Linux, а потому не требует накладывания каких-либо патчей и может быть развернут за считанные минуты. В-третьих, это наиболее функциональная и стабильная система виртуализации OpenVZ, выступающая в роли ядра коммерческой системы Virtuozzo, выпускаемой российской компанией Parallels.

Сегодня OpenVZ и Virtuozzo - это стандарт де-факто для систем виртуализации уровня ОC в Linux. Они используются на тысячах серверов по всему миру, а их разработчики находятся на одном из первых мест по количеству коммитов кода в ядро Linux. Кстати, основной плюс OpenVZ заключается в том, что ты всегда сможешь найти не только огромное количество других пользователей OpenVZ, которые ответят на твои вопросы, но и массу информации на русском языке.

Что умеет OpenVZ?

По сути, OpenVZ - это модифицированное ядро Linux, в которое добавлен слой виртуализации, построенный на концепции VE (Virtual Environment - виртуальной среды), которую мы будем называть более привычным для нас термином «контейнер».

Такое ядро может обеспечивать несколько контекстов исполнения. И даже если пользователь не собирается использовать эту возможность, ядро все равно создаст один контекст, называемый Hardware Node (или нулевой контейнер). Это основная хост-система, имеющая максимальные полномочия и права на ресурсы. Говоря простым языком - стандартное Linux-окружение.

В любой момент администратор нулевого контейнера может добавить в систему новый контейнер, назначив ему номер, имя, сетевой адрес, дав прямой доступ к нужному оборудованию (если это необходимо) и выделив нужное количество ресурсов, которые будут определять «мощность» виртуального сервера.

OpenVZ использует модифицированный планировщик процессов, который учитывает не только их приоритеты, но и то, в каком контейнере они исполняются. Это позволяет задать жесткое ограничение процессорного времени на каждый контейнер, не позволив ему полностью загрузить весь процессор, лишив возможности исполнения процессы других контейнеров.

Каждый контейнер OpenVZ получает собственный виртуальный сетевой интерфейс (venet или veth) и полноценный, полностью обособленный от нулевого контейнера, сетевой стек, обеспечивающий контейнер отдельными IP-адресом, таблицей маршрутизации и правилами брэндмауэра. Одной из важнейших возможностей OpenVZ является механизм так называемого «чекпоинтинга», позволяющий сохранить образ контейнера на жесткий диск и восстановить его работу с прерванного места. Более того, образ можно безболезненно перенести на другую машину и восстановить его работу уже на ней. Причем даже если в момент «заморозки » на адрес одного из сетевых сервисов контейнера придет запрос, он будет вполне успешно обработан после восстановления, а для клиента это будет выглядеть как обычная задержка в ответе (например, на открытие web-страницы ушла не доля секунды, а 5 секунд).

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

Ограничения

Помимо уже упомянутого ограничения на тип поддерживаемых ОС, которое вытекает из того факта, что все контейнеры работают на одном ядре Linux, у OpenVZ есть несколько более мелких, но заслуживающих внимания недостатков (справедливости ради следует отметить, что это проблема всех реализаций системы виртуализации уровня ОС). Во-первых, OpenVZ накладывает определенные ограничения на работу софта, который зависит от низкоуровневых функций ядра. Так, например, ядерный NFS, OpenVPN и IPSec внутри контейнера работать не будут.

Какие-то другие программы, зависимые от ядерных модулей, также откажутся правильно функционировать (хотя в некоторых случаях OpenVZ позволяет загрузить в контейнер модули).

О различных ядерных патчах тем более придется забыть раз и навсегда. Во-вторых, все контейнеры OpenVZ используют один дисковый своп, а это значит, что если оперативная память между контейнерами будет распределена неправильно, система может начать тормозить в самый неподходящий момент. К счастью, проблема решается с помощью разделения памяти таким образом, чтобы ее суммарный объем составлял не более 80-90% от общего количества. В-третьих, контейнеры OpenVZ используют один дисковый кэш, поэтому если какой-то контейнер начнет активно обращаться к жесткому диску, то он может заполнить весь кэш своими данными, и другим контейнерам придется долго ждать очереди, чтобы записать/прочитать данные с диска. В связи с этим я бы не рекомендовал использовать OpenVZ для «хостинга» серверов, активно работающих с диском (для таких задач вообще всегда рекомендуется использовать выделенный железный сервер).

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

Установка

Являясь «системой уровня предприятия» и основой платного продукта Virtuozzo, OpenVZ в первую очередь рассчитана на применение в дистрибутивах линейки RHEL, поэтому официальные сборки OpenVZ-ядра доступны только для этого дистрибутива.

Неофициально же OpenVZ доступен в Debian, разработчики которого самостоятельно патчат и готовят ядро OpenVZ (пакет linux-openvz-i386 FIXME).

В Ubuntu ядра OpenVZ нет еще с версии 8.10, поэтому у его пользователей остается два способа установить OpenVZ на сервер: пропатчить и собрать ядро самостоятельно либо взять уже патченое ядро из Ubuntu 8.04. Для тех, кто считает последний подход бредовым, поясню: во-первых, стабильное OpenVZ-ядро на сегодняшний день до сих пор имеет номер версии 2.6.18, тогда как в Ubuntu 8.04 используется даже более свежее ядро 2.6.24; во-вторых, Ubuntu 8.04 является LTS-дистрибутивом, а значит, обновления безопасности для любых его компонентов будут выходить вплоть до 2013 года, что, на мой взгляд, вполне приемлемо. Итак, если мы имеем дело с RHEL, то OpenVZ можно установить из официального источника. Для этого необходимо добавить репозиторий openvz.org в yum:

# cd /etc/yum.repos.d
# wget http://download.openvz.org/openvz.repo
# rpm --import http://download.openvz.org/RPM-GPG-Key-OpenVZ

Отключить SELinux:

# echo "SELINUX=disabled" > /etc/sysconfi g/elinux

И установить ядро и утилиты управления:

# yum install ovzkernel
# yum install vzctl vzquota

В Debian все просто, достаточно выполнить только одну команду:

$ sudo apt-get install vzctl vzquota
linux-openvz-i386

В Ubuntu сложнее. Сначала необходимо добавить репозиторий Ubuntu 8.04, для чего следует создать файл / etc/apt/sources.list.d/hardy-main.list и поместить в него следующие строки:

# vi /etc/apt/sources.list.d/hardy-main.list
hardy main
deb http://mirror.yandex.ru/ubuntu
hardy-updates main
deb http://mirror.yandex.ru/ubuntu
hardy-security main

Только после этого можно установить OpenVZ-ядро и утилиты:

$ sudo apt-get update
$ sudo apt-get install vzctl vzquota
linux-openvz

После установки в любом из трех дистрибутивов необходимо изменить некоторые настройки ядра, иначе OpenVZ будет работать некорректно. Открываем файл /etc/sysctl.conf и пишем в него следующее:

# vi /etc/sysctl.conf
net.ipv4.conf.default.proxy_arp = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_fi lter = 1
kernel.sysrq = 1
net.ipv4.conf.default.send_redirects = 1
net.ipv4.conf.all.send_redirects = 0

Перезагружаем машину и загружаемся уже с новым ядром. Чтобы запустить необходимые для правильной работы OpenVZ userspace-сервисы, набираем:

# /etc/init.d/vz start

Шаблоны ОС

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

Существует три способа это сделать:

  1. Скопировать файловое дерево из основной системы, что приведет к тому, что любой новый контейнер будет представлять собой копию существующей системы (нулевого контейнера).
  2. Взять существующий дистрибутив Linux и получить готовый шаблон, выбросив из него ядро, initramfsобраз и внеся несколько изменений.
  3. Скачать подходящий шаблон с сайта OpenVZ.

Мы пойдем по пути наименьшего сопротивления и воспользуемся третьим способом. Для этого переходим в каталог-хранилище шаблонов:

$ cd /var/lib/vz/template/cache

И скачиваем нужный шаблон с помощью wget:

$ sudo wget http://download.openvz.org/template/precreated/debian-5.0-x86.tar.gz

Весь список подготовленных шаблонов можно просмотреть, открыв страницу download.openvz.org/template/precreated в браузере.

Создаем контейнеры

Для управления OpenVZ используется несколько консольных утилит, наиважнейшая из которых носит имя vzctl. Она применяется для создания, удаления, запуска, остановки, а также изменения настроек контейнеров.

Любой сисадмин OpenVZ должен знать все ее параметры и опции назубок. Способ вызова утилиты следующий:

# vzctl команда номер_контейнера аргументы

Команда - это действие, которое должен выполнить OpenVZ, а аргументы уточняют или дополняют его.
Для создания контейнера используется команда create, для изменения параметров - set, для уничтожения - destroy. Также доступны команды enter, start, stop и restart, позволяющие «заходить» в контейнеры и управлять их работой.

Vzctl - очень гибкая утилита, с помощью которой можно создать и полностью настроить контейнер почти любой сложности, не затронув ни единого конфигурационного файла. Вот как это делается:

1. Сначала создаем новый контейнер с номером 100 (кстати, в качестве номера удобно использовать последнюю часть его IP-адреса):

# vzctl create 100 --ostemplate debian-5.0-x86
--confi g vps.basic

Здесь debian-5.0-x86 - это скачанный ранее шаблон без расширения tar.gz, а vps.basic - набор стандартных предустановок, которые мы все равно собираемся менять.

2. Меняем настройки контейнера так, чтобы он запускался при загрузке системы:

# vzctl set 100 --onboot yes --save

3. Меняем сетевое имя контейнера:

# vzctl set 100 --hostname my-fi rst-vps.org.ru --save

4. Даем ему новый IP-адрес:

# vzctl set 100 --ipdel all --ipadd 192.168.0.100 --save

5. Указываем дефолтный DNS-сервер:

# vzctl set 100 --nameserver 192.168.0.1 --save

6. Устанавливаем пароль пользователя root:

# vzctl set 100 --userpasswd root:password --save

7. Выделяем контейнеру 15% от общей мощности процессора (один процессор - это 100%, два - 200%, четыре - 400% и так далее):

# vzctl set 100 --cpulimit 15 --save

8. Выделяем контейнеру 20 Гб дискового пространства с возможностью его превышения до 25 Гб на небольшой промежуток времени:

# vzctl set 100 --diskspace 20G:25G --save

9. Устанавливаем ограничение на объем оперативной памяти (в первой строке устанавливаем гарантированный ресурс, во второй - негарантированный, он будет доступен контейнеру только в том случае, если в системе есть его излишек):

# vzctl set 100 --vmguarpages 256M:256M --save
# vzctl set 100 --privvmpages 512M:512M --save

10. Теперь можно войти в контейнер и продолжить настройку уже внутри него (установить необходимые сервисы, настроить брэндмауэр и маршрутизацию):

# vzctl enter 100

Более подробную информацию о настройке контейнеров можно почерпнуть из man-страницы vzctl.

UBC

В терминах OpenVZ лимиты и гарантии ресурсов называются User Beancounters (UBC). Всего существует около 20 UBC, контролирующих почти все возможные ресурсы системы. Каждый UBC имеет свою опцию в команде vzctl, а также строку в файле /proc/user_ beancounters, с помощью которого можно узнать о текущем количестве выделенных ресурсов и определить их нехватку. Файл представляет собой таблицу, каждая строка которой содержит информацию об одном ресурсе, а колонки отражают следующие данные:

Файл /proc/user_beancounters

  • uid - идентификатор контейнера;
  • resource - имя ресурса;
  • held - текущая утилизация ресурса;
  • maxheld - максимальный уровень утилизации ресурса за все время работы контейнера;
  • barrier - максимальный уровень утилизации ресурсов, который может быть временно превышен;
  • limit - жесткое ограничение утилизации ресурса, которое никогда не может быть превышено;
  • failcnt - счетчик отказов, который увеличивается каждый раз, когда контейнер делает запрос ресурсов сверх своего лимита.

Не обязательно разбираться во всех тонкостях системы подсчета ресурсов OpenVZ, чтобы эффективно управлять контейнерами. Достаточно время от времени поглядывать на значение колонки failcnt и, если оно оказывается больше нуля, начинать предпринимать меры либо по оптимизации исполняемого в рамках контейнера софта, либо по увеличению количества выделяемых контейнеру ресурсов.

Выводы

Эта статья охватывает лишь малую часть того, что принято называть термином «виртуализация уровня ОС», но изложенной в ней информации вполне достаточно, чтобы начать применять технологию и двинуться дальше.

О настройке контейнеров

Самое замечательное в настройке OpenVZконтейнеров - это целостность инструментов. При необходимости система сама изменяет конфигурационные файлы дистрибутива, расположенного в контейнере, так, чтобы они соответствовали запрошенным. К примеру, настройка адреса DNS-сервера с помощью vzctl автоматически приведет к его добавлению в файл /etc/resolv.conf в файловой системе контейнера.

Такой уровень гибкости гораздо сложнее получить при использовании «классических» систем виртуализации.

Список OpenVZ-утилит

  • vzlist используется для получения списка всех контейнеров;
  • vzmigrate предназначена для осуществления offlineи online-миграции;
  • vzcfgvalidate проверяет конфигурационные файлы на корректность;
  • vzmemcheck, vzcpucheck, vzcalc осуществляют проверку на доступные ресурсы внутри контейнера;
  • vzsplit автоматически генерирует конфигурационные файлы;
  • vzpid определяет номер контейнера по PID’у процесса;
  • vzquota управляет дисковой квотой контейнера.

Links

  • Все, что нужно знать о UBC: wiki.openvz.org/UBC ;
  • Руководство по созданию шаблонов: http://goo.gl/h1gNL .
  • О том, как производить чекпоинтинг: http://goo.gl/lZbzW .
  • Как превратить физический сервер в виртуальный: http://goo.gl/sYtxF ;
  • Настройка I/Oприоритетов для контейнеров: http://goo.gl/YtjiV .
  • Cписок панелей управления OpenVZ: http://goo.gl/KfEbB .
  • OpenVZ Web Panel, одна из лучших web-панелей для управления OpenVZ: http://goo.gl/x7UlF .
  • Настройка OpenVZ Web Panel: http://goo.gl/vx73u .
  • Описание процесса установки OpenVZ в Ubuntu 10.04 с помощью сборки из исходников: http://goo.gl/XEaou .