Хочешь организовать публичный доступ к сетевым сервисам, но беспокоишься за безопасность? Решил переложить часть своих обязанностей на другого человека, но не хочешь наделять его правами? Управляешь хостингом и желаешь дать своим клиентам настоящую свободу? С помощью системы виртуализации Linux VServer легко решишь все эти задачи без головной боли и потери производительности.
Мы не раз говорили о системах виртуализации уровня операционной системы (песочницы) на примере FreeBSD Jail. Такой тип виртуализации позволяет разделить одну ОС на несколько виртуальных, каждая из которых будет обладать собственным окружением исполнения (библиотеки, каталоги /devH / proc, набор стандартных утилит), процессами и IP-адресом.
В отличие от эмуляции, обеспечиваемой такими технологиями, как Xen, VMWare и KVM, виртуализация уровня операционной системы не эмулирует аппаратные составляющие компьютера, а создает изолированные контейнеры поверх ядра ОС. Это своего рода расширенная трактовка понятия «процесс» с более глубоким уровнем изоляции и разделения ресурсов, предоставляемых ядром. Обладая всего одним явным недостатком, заключенным в невозможности создания контейнеров для исполнения приложений других ОС, песочница наделена двумя неоспоримыми преимуществами: незначительной потерей производительности (в районе 2-3%) и простотой развертывания виртуальных окружений. Виртуализация особенно популярна среди хостинг-провайдеров и создателей сервисов, предоставляющих площадки для организации облачных вычислений. Ведь в отличие от обычного хостинга, который выделяет клиентам аккаунт на сервере и доступ к набору предустановленных служб, хостинг, использующий виртуализацию, способен дать пользователям безграничный контроль над виртуальным сервером, возможностью устанавливать любое программное обеспечение и полным отсутствием ограничений на количество сайтов, почтовых ящиков, баз данных, интерпретаторов языков программирования. И все это с полной изоляцией виртуального сервера от хост-системы и простой системой развертывания.
ПОЧЕМУ VSERVER? Сегодня каждая из наиболее популярных UNIX-систем предоставляет возможности для организации виртуализации на уровне операционной системы. Во FreeBSD уже давно существует технология Jail, в Solaris изолированные контейнеры называются зонами (Zones), а среди решений для Linux наибольшей популярностью пользуются OpenVZ и Linux VServer.
Традиционно OpenVZ (openvz.org’) считается более взрослой, серьезной и развитой системой, этаким выбором профессионалов. Развиваемая сообществом Linux VServer (linux-vserver.org)« напротив, отличается простотой реализации и непретенциозностью. В то время как OpenVZ развивается по пути многофункциональной и сложной технологии для поддержки и управления VPS (Виртуальные Частные Серверы) в больших организациях и крупных сервисах, VServer следует идеологии простоты и удобства FreeBSD Jail. Система Linux VServer—это проверенный годами (более 7 лет разработки) небольшой, вылизанный и отлаженный патч для ядра Linux; он наделяет всем необходимым для организации надежной и производительной системы виртуализации, единственный недостаток которой— невиртуализируемый сетевой стек.
Программный пакет Linux VServer состоит из двух частей: патча для Linux-ядра и набора утилит для управления виртуальными серверами. Прекомпилированные ядра с включенным VServer доступны в пакетах для многих популярных дистрибутивов, поэтому сначала мы рассмотрим вариант установки средствами менеджера пакетов в Ubuntu 9.04, а уже после перейдем к ручному способу инсталляции, предполагающему выкачивание исходников ядра с kernel.org и компиляцию утилит. Итак, операционная система Ubuntu 9.04, ядро 2.6.28, ночь, серверная.
Шаг 1. Добавляем в apt keyring ключ для доступа к репозиторию VServer:
$ sudo apt-key adv –recv-keys –keyserver keyserver.ubuntu.com BB9BFB5B
Шаг 2. Добавляем ссылки на репозитории VServer в /etc/apt/sources.list:
deb http://ppa.launchpad.net/ christoph-lukas/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/ christoph-lukas/ppa/ubuntu jaunty main
ШагЗ. Устанавливаем новое ядро и утилиты:
$ sudo apt-get update
$ sudo apt-get install linux-image-vserver linux-headers-vserver util-vserver
Та же процедура, с полной пересборкой ядра и компиляцией утилит.
Шаг 1. Получаем ядро и патч:
# cd /usr/src
# wget http://www.kernel.org/ pub/linux/kernel/v2.6/linux-2-.6.28.7.tar.bz2
# wget http://vserver.13thfloor. at/Experimental/patch-2.6.28.7-vs2.3.0.36.8.diff
Шаг 2. Накладываем патч на ядро, копируем существующий конфиг и запускаем конфигуратор:
# tar -xjf linux-2.6.28.7.tar.bz2
# cd linux-2.6.28.7
# cp /boot/config-X.X.X .
# patch -pi < ../patch-2.6.28.7-vs2.3.0.36.8.diff
# make menuconf ig
Шаг 3. Изменяем конфигурацию пункта меню Linux VServer:
Enable Legacy Kernel API - Поддержка устаревшего API первой версии патчей. Отключаем
Enable Virtualized Guest Time — Возможность установки индивидуальной временной зоны для каждого окружения. Актуально для владельцев хостингов, во всех остальных случаях бесполезна и создаст дополнительный оверхед для системных вызовов, работающих со временем
Enable Proc Security — Скрывать все процессы, не принадлежащие окружению, в каталоге /ргос этого окружения. Hard CPU Limits — Жесткое ограничение окружений по времени использования процессора. Включаем Tag NFSD User Auth and Files — Поддержка встроенного в ядро NFS-демона
Maximum number of Contexts — Максимально возможное число окружений
Шаг 4. Устанавливаем ядро:
# make
# make modules_install
# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.28.7-vs2.3 Шаг 5. Правим конфигурационный файл загрузчика:
#VI/BOOT/GRUB/MENU.LST
title Linux 2 . 6 .28 .7-vs2 . 3 root (hdO,0)
kernel /boot/vmlinuz-2.6.28.7-vs2.3 root=/dev/hdal ro
initrd /boot/initrd.img-2.6.28.7-vs2.3
boot
Шаг 6. Получаем и устанавливаем набор утилит для управления виртуальными серверами:
# cd /tmp
# wget http://ftp.linux-vserver.org/pub/utils/util-vserver/util-vserver-0.30.215.tar.bz2
# tar xjf util-vserver-0.30.215.tar.bz2
# cd util-vserver-0.30.215
# ./configure –prefix=/usr –sysconfdir=/etc
# make install
Перед тем как перейти к запуску виртуальных окружений («контекстов» в терминологии Linux VServer), мы должны соответствующим образом подготовить операционную систему. Первое, что следует сделать—примонтировать файловую систему, на которой будут располагаться виртуальные окружения, с опцией tag. Это даст ядру возможность устанавливать принадлежность определенных файлов конкретному контексту, что, в свою очередь, позволит устанавливать дисковые квоты на этот контекст.
Открываем файл /etc/fstab, находим строку, ответственную за монтирование файловой системы, содержащей каталог /var/lib (виртуальные окружения по умолчанию хранятся в /var/lib/vservers), и добавляем к опциям ее монтирования флаг tag. Результирующая строка должна выглядеть примерно так:
/dev/sda3 /var ext3 tag 1 1
Если каталог находится на файловой системе reiserfs, добавляем также опцию attrs. Отправляем сервер в ребут.
Теперь необходимо установить так называемый «Chroot Вагпег», который закроет процессы виртуальных сред в указанном каталоге, откуда ни один процесс окружения не сможет выбраться:
# setattr –barrier /var/lib/vservers
В довершение подготовительных действий прописываем в переменную ядра kernel.vshelper путь к скрипту, который будет корректно останавливать виртуальный сервер:
# echo “kernel.vshelper = /usr/lib/util-vserver/vshelper” » /etc/sysctl.conf
# SySCtI -p If*
Для начала необходимо создать минимальное Linux-окружение, где будут работать изолированные процессы. Сделать это можно с помощью специальных утилит, но гораздо легче и быстрее просто скачать готовый образ (шаблон) с одного из специальных ресурсов. Мы обратимся к хранилищу ftp: //ftp. pld-linux.org/people/hawk/vserver-templates/, в котором размещены готовые образы последних релизов CentOS, Debian, Fedora и Ubuntu, предназначенные для применения в системе VServer. Получим образ последнего релиза Ubuntu (ты можешь выбрать любой другой, по своему вкусу):
$ cd /tmp
$ wget ftp://ftp.pld-linux.org/people/hawk/vserver-templates/Ubuntu/jaunty-i386.tar.bz2
С помощью специальной команды создадим из него готовый к работе виртуальный сервер:
# vserver vpsl build \
—context 10 \ –hostname vpsl.host.ru \ —interface ethO: 192 .168.1.1/24 \ –initstyle plain \ -m template — \ -d jaunty \ -t /tmp/jaunty-i386.tar.bz2
Приведенная команда развернет образ в каталог /var/lib/ vservers/vpsl и проведет его начальное конфигурирование. Первая строка говорит о том, что новое виртуальное окружение должно быть создано с именем vpsl, вторая указывает на номер контекста (он может быть любым), третья устанавливает сетевое имя виртуального сервера в vpsl. host.ru, четвертая—привязывает его к сетевому интерфейсу ethO и назначает IP-адрес 192.168.1.1, в пятой указан способ инициализации окружения (plain—запуск/sbin/init). Оставшиеся строки говорят о том, что в качестве источника для сборки окружения должен быть использован шаблон /tmp/ jaunty-i386.tar.bz2, основанный на дистрибутиве Ubuntu 9.04 (Jaunty Jackalope).
VServer поддерживает множество других методов сборки окружений, включая полностью автоматизированные (с автоматическим выкачиванием дистрибутива), с которыми ты можешь ознакомиться, прочитав man-страницу vserver-build.
Теперь запустим вновь созданный виртуальный сервер и убедимся в его работоспособности:
# vserver vpsl start
# vserver-stat
Сервер должен присутствовать в списке. Остановим сервер:
# vserver vpsl stop
Все внешние по отношению к окружению настройки виртуальных серверов, такие как ограничения, доступные сетевые интерфейсы и т.д., хранятся в каталоге / etc/vservers/HMH_cepBepa. Поэтому переходим в каталог / etc/servers/vpsl и приступаем к шаманству с конфигурационными файлами.
Для начала взглянем на каталог interfaces, который уже содержит один подкаталог с названием «О». Он хранит настройки первого виртуального сетевого интерфейса, доступного внутри виртуального окружения. Linux VServer, как и система FreeBSD Jail, использует сетевой интерфейс
хост-системы и закрепленный за ним IP-псевдоним для предоставления виртуальным окружениям доступа во внешний мир. Для хранения настроек каждого сетевого интерфейса используется отдельный каталог с числовым именем (0— первый интерфейс, 1—второй и т.д.) Поэтому для того чтобы оснастить виртуальный сервер дополнительным сетевым интерфейсом, необходимо создать каталог с именем «1» и поместить в него несколько файлов с настройками:
Привяжем сетевой интерфейс к устройству ethl хост-системы
# echo “ethl” > dev
Зададим IP-адрес и маску сети
# echo “192.168Л.2й > ip
# echo “24″ > prefix
Обрати внимание, что если ты сейчас запустишь виртуальный сервер и взглянешь на вывод его команды ifconfig, то увидишь, что оба сетевых интерфейса уже полностью настроены и готовы к работе. Скрипты и утилиты VServer делают всю грязную работу сами, и любой виртуальный сервер можно настроить с помощью внешних конфигурационных файлов.
Это же утверждение относится и к монтируемым файловым системам. Вместо того, чтобы заходить на сервер и редактировать /etc/fstab, ты можешь поместить монтируемые ФС в файл /etc/vservers/vpsl/fstab. По умолчанию он уже содержит строки, ответственные за подключение файловых систем /dev, /ргоси /tmp, к которым можно добавить, например, монтирование дерева портежей хост-системы (если в качестве виртуального сервера используется Gentoo):
/usr/portage /usr/portage none bind,rw 0 0
Мы присвоили виртуальному окружению «фиктивный» IP-адрес из внутреннего диапазона адресов, поэтому гостевой сервер не сможет получить доступ к внешней сети, а без этого он и не сервер. Есть два распространенных способа решения этой проблемы:
1. Присвоить виртуальному окружению белый IP-адрес (нужно покупать у провайдера).
2. Настроить NAT между хост-машиной и виртуальным сервером, что позволит перенаправлять исходящий от виртуального сервера трафик на внешний сетевой интерфейс хост-системы и пускать нужный входящий трафик прямиком на адрес виртуального сервера.
Рассмотрим второй вариант подробнее. Настроим SNAT, чтобы исходящий от виртуального сервера трафик выходил наружу:
# iptables -t nat -A POSTROUTING -s 192.168.1.1/24 \
-d ! 192.168.1.1/24 -j SNAT –to-source <Внешний IP>
И DNAT, чтобы предназначенный для определенных сетевых сервисов трафик перенаправлялся на IP-адрес виртуального сервера (пример для web-сервера, работающего под управлением VServer):
# iptables -t nat -A PREROUTING -s ! 192.168.1.1/24 \
-m tcp -p tcp –dport 80 \
-j DNAT –to-destination 192.168.1.1:80
Настройки ограничений ресурсов, накладываемых на виртуальный сервер, хранятся в каталогах dlimits и rlimits. По умолчанию эти каталоги не существуют, поэтому сервер может отъедать ресурсы почти на равных с хост-системой. Чтобы исправить ситуацию, создадим каталог /etc/vservers/vpsl /dlimits, который будет хранить настройки, накладывающие лимит на использование дискового пространства:
# cd /etc/vservers/vpsl
# mkdir dlimits
Создадим каталог для настроек корня файловой системы виртуального сервера (на самом деле имя может быть любым):
# mkdir dlimits/root
# cd dlimits/root
Укажем каталог, для которого будут действовать ограничения:
# echo “/var/lib/vservers/vpsl” > directory
Лимит на количество индексных дескрипторов (максимальное количество файлов):
# echo “10000″ > inodes_total
Максимальное пространство, которое могут занимать файлы этого виртуального окружения (укажем 10 Гб):
# echo “10485760″ > space_total
Процент зарезервированного для пользователя root пространства:
# echo “5″ > reserved
Теперь установим тэг на существующие файлы виртуального сервера, чтобы ядро смогло определить их принадлежность vpsl и правильно рассчитать лимиты (файлы, созданные виртуальным окружением, автоматически получат этот тэг):
# chxid -URx -c vpsl /var/lib/vservers/vpsl
Все, теперь можно запустить виртуальный сервер и выполнить команду vdlimit, которая покажет занятые виртуальным сервером ресурсы ФС и лимиты:
# vdlimit –xid vpsl /var/lib/vservers/vpsl
От лимитов всегда можно избавиться, просто удалив каталог /etc/ vservers/vpsl/dlimits/root и выполнив команду vdlimit с флагом ‘–remove’, которая отменит их для запущенного сервера:
# vdlimit —xid vpsl –remove /var/lib/vservers/vpsl
Для хранения настроек лимитов на виртуальную память и процессорное время предусмотрен каталог /имя_контекста/ rlimits. Linux VServer использует системный вызов setrlimit(2) для накладывания лимитов на ресурсы контекста. Всего существует 22 различных вида ресурсов (15 в ванильном ядре + 7, добавляемые Linux VServer), наиболее интересные из них перечислены ниже (страница = 4 Кб для х86):
сри — Процессорное время, выделяемое контексту, в миллисекундах
f size — Размер файла в килобайтах
rss - Размер резидентной памяти в страницах пргос — Количество процессов
as — Размер адресного пространства контекста в страницах nice — Приоритет, который может получить процесс контекста nsock - Число открытых сокетов openf d — Число открытых файловых дескрипторов
Чтобы установить максимальное значение для каждого из этих ресурсов, достаточно записать число в одноименный файл внутри каталога /etc/ vservers/имя_cepвepa/rlimits. Например, ограничим адресное пространство контекста значением 100 Мб (25600*4 Кб):
# mkdir /etc/vservers/vpsl/rlimits
# echo “25600″ > /etc/vservers/vpsl/rlimits/as
Кроме того, в Linux VServer встроена гибкая система ограничения контекстов в правах и полномочиях, возможности которой можно использовать для наделения контекста особыми привилегиями или, наоборот, лишения прав. Все, что позволено контексту, должно быть перечислено в файле / еКАзегсеге/имя.контекста/ссараЬШпез. Вот возможные флаги этого файла:
SET_UTSNAME — Возможность использовать системные вызовы setdomainname (2) и sethostname(2) для установки имени хоста SET_RLIMIT — Право использовать set г limit (2) для управления лимитами • RAW_ICMP — Право использовать “сырые” сокеты SYSLOG — Использование syslog(2) для ведения журналов SECURE_MOUNT - Разрешить mount (2) SECURE_REMOUNT - Разрешить перемонтирование ВI NARY_MOUNT - Бинарное /сетевое монтирование QUOTA_CTL - Разрешить накладывать квоты ADM I N_MA Р PER - Разрешить доступ к “device mapper” ADMIN_CLOOP — Доступ к loop-устройству KTHREAD — Возможность создавать потоки ядра
Существует и множество других флагов, которые следует указывать в файлах flags, nflags, bcapabilities и neaps. Детальное их описание можно найти на страничке linux-vserver.org/util-vserver.Capabilities and Flags.