Контейнерные утилиты Linux Containers (LXC)Источник: ibm
Контейнеры эффективно разделяют ресурсы, управляемые единственной операционной системой, на изолированные группы, для достижения лучшего баланса между конфликтующими запросами на использование ресурсов. В отличие от виртуализации, здесь не требуется ни эмуляция на командном уровне, ни компиляция "на лету" (just-in-time compilation). Контейнеры могут исполнять прямые процессорные команды, не прибегая к механизмам интерпретации. Также отпадают сложности паравиртуализации и преобразования системных вызовов. Предоставляя средства для создания и использования контейнеров, ОС дает приложениям возможность работать как бы на отдельной машине, при этом совместно используя множество базовых ресурсов. Например, кэширование страниц общих файлов - например, glibc - можно эффективно использовать совместно, потому что все контейнеры используют одно и тоже ядро и, в зависимости от настроек контейнера, обычно одну и ту же библиотеку libc. Часто такое совместное использование распространяется и на другие файлы и папки, в которые не происходит запись. Экономия от совместного использования ресурсов в сочетании с предоставляемой изоляцией приводит к тому, что контейнеры требуют значительно меньших накладных расходов, чем истинная виртуализация. Контейнерные технологии существуют уже довольно продолжительное время. В качестве примеров контейнеров из других Unix-систем следует назвать Solaris Zones и BSD jails. У контейнерных технологий в Linux также давние традиции: Linux-Vserver, OpenVZ и FreeVPS. Хотя каждая из этих технологий является вполне зрелой, решительных шагов по интеграции поддержки их контейнерных возможностей в основную ветвь ядра Linux не предпринималось. В статье Сержа Халлина (Serge Hallyn) "Модули безопасности Linux: Рецепты для работы с контейнерами" (developerWorks, февраль 2009 г.), рассказывается, как можно усилить безопасность легких контейнеров с помощью политик SELinux и Smack. Проект Linux Resource Containers, напротив, направлен на реализацию контейнеров в сотрудничестве с разработчиками основной ветви ядра Linux. Одновременно этот вклад может быть полезен и для более зрелых контейнерных Linux-решений, предоставляя для них общий внутренний интерфейс. Данная статья содержит краткое введение в использование утилит, созданных проектом LXC. Для лучшего понимания статьи необходимо уверенно чувствовать себя в командной строке в работе с такими программами, как make, gcc, и patch, а также быть знакомым с процессом распаковки тарболов (файлов с расширением .tar.gz). Получение, сборка и установка LXC Проект LXC состоит из патча для ядра Linux и утилит, работающих в пользовательском пространстве. Утилиты используют новую функциональность, добавляемую патчем в ядро, и предлагают упрощенный набор инструментов для управления контейнерами. Прежде чем начать использовать LXC, необходимо скачать исходный код ядра Linux, установить соответствующий LXC-патч, затем собрать, установить и загрузить новое ядро. Далее необходимо загрузить, собрать и установить инструментарий LXC. Мы использовали пропатченное ядро Linux 2.6.27. Скорее всего, lxc-патч для ядра 2.6.27 не подойдет для исходного кода ядра вашего любимого дистрибутива, и в то же время версии ядра Linux старше 2.6.27 могут уже содержать значительную часть функциональности, представленной в патче. Поэтому настоятельно рекомендуется использовать последние версии патча и ядра из основной ветви. Также вместо загрузки исходного кода ядра и установки на него патча можно получить код, используя
Инструкции по наложению патчей, настройке, сборке, установке и загрузке ядра можно найти на сайте kernelnewbies.org . Для LXC необходимы некоторые специфические настройки в ядре. Самый простой способ правильно настроить ядро для работы с LXC - это использовать В дополнение к ядру, поддерживающему контейнеры, нам понадобятся инструменты для упрощения запуска и управления контейнерами. Основными средствами управления в этой статье являются утилиты из библиотеки liblxc. В этом разделе обсуждаются:
Скачайте и распакуйте liblxc, затем выполните из папки liblxc команду:
Если вам удобнее собирать из SRPM, такой пакет также имеется. Для управления сетевыми интерфейсами внутри контейнеров необходим пакет iproute2 версии 2.6.26 или старше. Если в вашем дистрибутиве он отсутствует, то скачайте, настройте, соберите и установите его, следуя инструкциям из архива с исходным кодом. Еще один ключевой компонент многих функциональных контейнеров - сетевой доступ. Наилучшим способом подключения контейнера к сети в настоящее время является соединение сегментов Ethernet сетевым мостом таким образом, что они выглядят единым сегментом сети. Готовясь к использованию LXC, мы создадим сетевой мост и с его помощью соединим наш настоящий сетевой интерфейс и сетевой интерфейс контейнера. Создаем сетевой мост с именем br0:
Теперь поднимите интерфейс моста с вашим IP от уже существующего интерфейса (в этом примере
Любой интерфейс, добавленный к мосту Заполнение файловой системы контейнера Помимо сети, контейнерам часто нужна собственная файловая система. Существует несколько способов заполнить ее в зависимости предъявляемых требований. Обсудим два из них:
Собрать собственный Debian-контейнер проще всего с помощь команды
Если делается большое количество контейнеров сразу, то можно сэкономить время, предварительно скачав пакеты и объединив их в тарбол: В итоге мы получаем среду, чрезвычайно избыточную по отношению к основному хост-контейнеру. Запуск SSH-контейнера позволяет очень существенно снизить объём дискового пространства, выделяемого исключительно под файловую систему контейнера. Например, данный способ использует лишь несколько килобайт, чтобы включить множество ssh-демонов из разных контейнеров, работающих на порту 22 . Контейнер делает это, используя монтирование "только для чтения" (read-only bind mounts), таких важных корневых папок, как /bin, /sbin, /lib и др., для совместного доступа к содержимому пакета sshd из существующей системы Linux. При этом используется сетевое пространство имен и создается очень небольшое изменяемое содержимое. Методы, использованные выше для создания легких контейнеров, в основном такие же, какие используются для создания chroot-сред. Разница лишь в использовании синонимов "только для чтения" (read-only bind mounts) и в использовании пространств имен для повышения изолированности chroot-среды до такой степени, что она становится эффективным контейнером. Далее нам необходимо выбрать способ подключения к контейнеру. Следующий шаг - подключение к контейнеру. Здесь, в зависимости от настроек контейнера, возможно несколько способов:
Подключение через SSH хорошо подходит для тех случаев, когда контейнеру не требуется графический интерфейс. В этом случае вполне достаточно простого соединения ssh. Преимущество этого метода, основанного на IP-адресации, в возможности создавать произвольное количество контейнеров. Если ssh-соединение ожидает ввод пароля слишком долго, то широковещательный демон Avahi службы DNS/Service Discovery при запросе к DNS может остановить работу по тайм-ауту. Подключение через удалённый доступ к рабочему столу (VNC) позволит использовать контейнер с графическим интерфейсом. Для запуска X-сервера, обслуживающего только VNC-клиентов, используйте vnc4server. Установленный vnc4server необходимо будет запустить из файла /etc/rc.local контейнера таким образом:
Подключение через VT: tty (текстовый режим) удобно, когда контейнер делит tty с основной машиной (хостом). В этом случае для подключения к контейнеру можно использовать Linux Virtual Terminals (VT). Простейшее использование VT начинается с авторизации в одном из устройств tty, которые обычно совпадают с виртуальными терминалами Linux. Процесс, отвечающий за авторизацию, называется
Теперь при запуске контейнера будет запускаться Этот метод не позволяет использовать графический интерфейс контейнера. Более того, поскольку к tty8 в каждый момент времени может подключиться лишь один процесс, для подключения нескольких контейнеров потребуются дополнительные настройки. Подключение через VT: X позволит запустить графический интерфейс. Для запуска GNOME Display Manager (gdm) на VT 9, отредактируйте rootfs/usr/share/gdm/defaults.conf, заменив значения Хотя теперь мы получили графический режим, мы используем один терминал из ограниченного количества виртуальных Linux-терминалов. Теперь, когда у нас работает удовлетворяющее требованиям ядро, установлены утилиты LXC и есть рабочая среда, настало время научиться управлять экземплярами среды. (Совет: более подробное описание многих необходимых действий содержится в файле LXC README.) Для управления контейнерами LXC использует файловую систему cgroup. Первое, что нужно сделать, - это смонтировать ее: Далее в статье приводятся некоторые базовые сведения по LXC, конкретные замечания и обзор низкоуровневого доступа. Здесь мы рассмотрим следующие вопросы:
Создание контейнера связывает имя с файлом настроек. Имя будет использовано для управления единичным контейнером:
Это позволяет множеству контейнеров использовать один и тот же файл настроек. В конфигурационном файле задаются атрибуты контейнера, такие как имя хоста, настройки сети, корневая файловая система и точки монтирования в fstab. После запуска скрипта lxc-sshd (создающего для нас конфигурацию) конфигурация ssh-контейнера будет выглядеть так:
Независимо от файла настроек контейнеры, запускаемые утилитами LXC, по-своему видят процессы системы и доступные ресурсы межпроцессного взаимодействия (IPC), а также имеют собственное дерево точек монтирования (mount tree). Кроме того, при запуске контейнера подразумевается, что любые ресурсы, не указанные в файле конфигурации, используются совместно с хостом. Это позволяет администраторам компактно описывать ключевые различия между хостом и контейнером, а также обеспечивает переносимость настроек. Вывод информации о существующих контейнерах - ключевой момент в управлении ими. Просмотр состояния конкретного контейнера:
Просмотр процессов, принадлежащих контейнеру:
Запуск
Напротив, контейнер приложений лишь создает отдельное пространство имен, необходимое для изоляции единичного приложения. Запуск контейнера приложений:
Подача сигналов
Приостановка
Возобновление
Остановка
Уничтожение
Вот несколько практических моментов, которые могут казаться полезными (некоторые из них касаются мониторинга). Просмотр и настройка приоритета контейнера:
Непрерывное наблюдение за состоянием и изменением приоритета контейнера:
Нажмите Ctrl-C чтобы остановить наблюдение. Ждём, пока контейнер не войдет в одно из множеств состояний, разделенных
Ждём любого состояния, кроме
Эта команда, разумеется, приведет к немедленному возврату управления. Исключая непредвиденные ошибки, можно ожидать, что команда Для управления контейнерами LXC использует файловую систему cgroup. Посредством LXC возможно просматривать и производить определённые действия с частями файловой системы cgroup. Использование процессора каждым контейнером можно регулировать считыванием и регулировкой параметра cpu.shares:
Заключение Узнав из этого руководства об основах работы с контейнерными утилитами Linux, вы можете приступать к созданию собственных эффективных разделов ресурсов. Этот материал основан на работе, поддержанной Агентством передовых оборонных исследовательских проектов (DARPA), в рамках Соглашения HR0011-07-9-0002. |