|
||||||||||||||||||||||||||||||||||||||||||||||
LXC: Kонтейнерные утилиты Linux
Время создания: 14.01.2021 18:18
Автор: alensav
Текстовые метки: LXC: Kонтейнерные утилиты Linux
Раздел: MyTetra - Ubuntu_Command
Запись: alensav/MyTetra2/main/base/1610637485nok7htxqdv/text.html на raw.githubusercontent.com
|
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
LXC: Kонтейнерные утилиты Linux. Обзор и установка новых контейнерных утилит Linux® Containers Мэт Хэлсли Контейнеры эффективно разделяют ресурсы, управляемые единственной операционной системой, на изолированные группы, для достижения лучшего баланса между конфликтующими запросами на использование ресурсов. В отличие от виртуализации, здесь не требуется ни эмуляция на командном уровне, ни компиляция "на лету" (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 (который разрабатывается и поддерживается специалистом IBM Дэниелом Лезкано (Daniel Lezcano); см. ссылку на исходный код в Ресурсах ), напротив, направлен на реализацию контейнеров в сотрудничестве с разработчиками основной ветви ядра 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 могут уже содержать значительную часть функциональности, представленной в патче. Поэтому настоятельно рекомендуется использовать последние версии патча и ядра из основной ветви. Также вместо загрузки исходного кода ядра и установки на него патча можно получить код, используя git:
Инструкции по наложению патчей, настройке, сборке, установке и загрузке ядра можно найти на сайте kernelnewbies.org (см. ссылку в Ресурсах ). Для LXC необходимы некоторые специфические настройки в ядре. Самый простой способ правильно настроить ядро для работы с LXC — это использовать make menuconfig и включить Container support. Это, в свою очередь, автоматически включит набор других опций, зависящих от возможностей, поддерживаемых ядром. В дополнение к ядру, поддерживающему контейнеры, нам понадобятся инструменты для упрощения запуска и управления контейнерами. Основными средствами управления в этой статье являются утилиты из библиотеки liblxc (см. ссылку в Ресурсах , а также ссылку на libvirt в качестве альтернативного решения). В этом разделе обсуждаются:
Скачайте и распакуйте liblxc (см. Ресурсы ), затем выполните из папки liblxc команду:
Если вам удобнее собирать из SRPM, такой пакет также имеется (см. Ресурсы ). Для управления сетевыми интерфейсами внутри контейнеров необходим пакет iproute2 версии 2.6.26 или старше (см. Ресурсы ). Если в вашем дистрибутиве он отсутствует, то скачайте, настройте, соберите и установите его, следуя инструкциям из архива с исходным кодом. Еще один ключевой компонент многих функциональных контейнеров — сетевой доступ. Наилучшим способом подключения контейнера к сети в настоящее время является соединение сегментов Ethernet сетевым мостом таким образом, что они выглядят единым сегментом сети. Готовясь к использованию LXC, мы создадим сетевой мост (см. Ресурсы ) и с его помощью соединим наш настоящий сетевой интерфейс и сетевой интерфейс контейнера. Создаем сетевой мост с именем br0:
Теперь поднимите интерфейс моста с вашим IP от уже существующего интерфейса (в этом примере 10.0.2.15): ifconfig br0 10.0.2.15 promisc up. Добавьте в мост существующий интерфейс (в нашем примере eth0) и уберите его прямую связь с IP-адресом:
Любой интерфейс, добавленный к мосту br0, будет соответствовать IP-адресу моста. Напоследок убедитесь, что пакеты следуют к шлюзу через правильный маршрут по умолчанию: route add -net default gw 10.0.2.2 br0. Позже, при настройке контейнера, мы укажем br0 в качестве пути во внешний мир. Заполнение файловой системы контейнера Помимо сети, контейнерам часто нужна собственная файловая система. Существует несколько способов заполнить ее в зависимости предъявляемых требований. Обсудим два из них:
Собрать собственный Debian-контейнер проще всего с помощь команды debootstrap:
Если делается большое количество контейнеров сразу, то можно сэкономить время, предварительно скачав пакеты и объединив их в тарбол: debootstrap --make-tarball sid.packages.tgz sid http://debian.osuosl.org/debian/. Команда из этого примера соберет tar-файл размером около 71 МБ (52 МБ в сжатом виде), в то время как корневой каталог займет примерно 200 МБ. Теперь все готово к сборке корневой папки в rootfs: debootstrap --unpack-tarball sid.packages.tgz sid rootfs. (man-страница debootstrap содержит более полную информацию по сборке контейнеров меньшего размера или размера, более подходящего вам по другим параметрам. В итоге мы получаем среду (см. Ресурсы ), чрезвычайно избыточную по отношению к основному хост-контейнеру. Запуск SSH-контейнера позволяет очень существенно снизить объём дискового пространства, выделяемого исключительно под файловую систему контейнера. Например, данный способ использует лишь несколько килобайт, чтобы включить множество ssh-демонов из разных контейнеров, работающих на порту 22 (см. пример в Ресурсах ). Контейнер делает это, используя монтирование "только для чтения" (read-only bind mounts), таких важных корневых папок, как /bin, /sbin, /lib и др., для совместного доступа к содержимому пакета sshd из существующей системы Linux. При этом используется сетевое пространство имен и создается очень небольшое изменяемое содержимое. Методы, использованные выше для создания легких контейнеров, в основном такие же, какие используются для создания chroot-сред. Разница лишь в использовании синонимов «только для чтения» (read-only bind mounts) и в использовании пространств имен для повышения изолированности chroot-среды до такой степени, что она становится эффективным контейнером. Далее нам необходимо выбрать способ подключения к контейнеру. Следующий шаг — подключение к контейнеру. Здесь, в зависимости от настроек контейнера, возможно несколько способов:
Подключение через SSH хорошо подходит для тех случаев, когда контейнеру не требуется графический интерфейс. В этом случае вполне достаточно простого соединения ssh (см. выше " Запуск контейнера SSH Запуск контейнера SSH"). Преимущество этого метода, основанного на IP-адресации, в возможности создавать произвольное количество контейнеров. Если ssh-соединение ожидает ввод пароля слишком долго, то широковещательный демон Avahi службы DNS/Service Discovery при запросе к DNS может остановить работу по тайм-ауту. Подключение через удалённый доступ к рабочему столу (VNC) позволит использовать контейнер с графическим интерфейсом. Для запуска X-сервера, обслуживающего только VNC-клиентов, используйте vnc4server. Установленный vnc4server необходимо будет запустить из файла /etc/rc.local контейнера таким образом: echo '/usr/bin/vnc4server :0 -geometry 1024x768 -depth 24' >> rootfs/etc/rc.local. В результате при старте контейнера будет создан экран с разрешением 1024*768 пикселов и глубиной цвета 24 бита. Теперь для подключения достаточно ввести:
Подключение через VT: tty (текстовый режим) удобно, когда контейнер делит tty с основной машиной (хостом). В этом случае для подключения к контейнеру можно использовать Linux Virtual Terminals (VT). Простейшее использование VT начинается с авторизации в одном из устройств tty, которые обычно совпадают с виртуальными терминалами Linux. Процесс, отвечающий за авторизацию, называется getty. Чтобы использовать VT 8, вводим:
Теперь при запуске контейнера будет запускаться getty на tty8, что даст пользователям возможность авторизоваться в контейнере. Аналогичный прием можно использовать для перезапуска контейнера с помощью утилит LXC. Этот метод не позволяет использовать графический интерфейс контейнера. Более того, поскольку к tty8 в каждый момент времени может подключиться лишь один процесс, для подключения нескольких контейнеров потребуются дополнительные настройки. Подключение через VT: X позволит запустить графический интерфейс. Для запуска GNOME Display Manager (gdm) на VT 9, отредактируйте rootfs/usr/share/gdm/defaults.conf, заменив значения FirstVT=7 на FirstVT=9, и VTAllocation=true на VTAllocation=false. Хотя теперь мы получили графический режим, мы используем один терминал из ограниченного количества виртуальных Linux-терминалов. Теперь, когда у нас работает удовлетворяющее требованиям ядро, установлены утилиты LXC и есть рабочая среда, настало время научиться управлять экземплярами среды. (Совет: более подробное описание многих необходимых действий содержится в файле LXC README.) Для управления контейнерами LXC использует файловую систему cgroup. Первое, что нужно сделать, - это смонтировать ее: mount -t cgroup cgroup /cgroup. Файловую систему cgroup можно монтировать куда угодно. LXC будет использовать первую смонтированную cgroup из файла /etc/mtab. Далее в статье приводятся некоторые базовые сведения по LXC, конкретные замечания и обзор низкоуровневого доступа. Здесь мы рассмотрим следующие вопросы:
Создание контейнера связывает имя с файлом настроек. Имя будет использовано для управления единичным контейнером:
Это позволяет множеству контейнеров использовать один и тот же файл настроек. В конфигурационном файле задаются атрибуты контейнера, такие как имя хоста, настройки сети, корневая файловая система и точки монтирования в fstab. После запуска скрипта lxc-sshd (создающего для нас конфигурацию) конфигурация ssh-контейнера будет выглядеть так:
Независимо от файла настроек контейнеры, запускаемые утилитами LXC, по-своему видят процессы системы и доступные ресурсы межпроцессного взаимодействия (IPC), а также имеют собственное дерево точек монтирования (mount tree). Кроме того, при запуске контейнера подразумевается, что любые ресурсы, не указанные в файле конфигурации, используются совместно с хостом. Это позволяет администраторам компактно описывать ключевые различия между хостом и контейнером, а также обеспечивает переносимость настроек. Вывод информации о существующих контейнерах — ключевой момент в управлении ими. Просмотр состояния конкретного контейнера:
Просмотр процессов, принадлежащих контейнеру:
Запуск
Напротив, контейнер приложений лишь создает отдельное пространство имен, необходимое для изоляции единичного приложения. Запуск контейнера приложений:
Подача сигналов
Приостановка
Возобновление
Остановка
Уничтожение
Вот несколько практических моментов, которые могут казаться полезными (некоторые из них касаются мониторинга). Просмотр и настройка приоритета контейнера:
Непрерывное наблюдение за состоянием и изменением приоритета контейнера:
Нажмите Ctrl-C чтобы остановить наблюдение. Ждём, пока контейнер не войдет в одно из множеств состояний, разделенных |:
Ждём любого состояния, кроме RUNNING:
Эта команда, разумеется, приведет к немедленному возврату управления. Исключая непредвиденные ошибки, можно ожидать, что команда lxc-wait завершится только когда контейнер войдет в указанное состояние. Для управления контейнерами LXC использует файловую систему cgroup. Посредством LXC возможно просматривать и производить определённые действия с частями файловой системы cgroup. Использование процессора каждым контейнером можно регулировать считыванием и регулировкой параметра cpu.shares:
Узнав из этого руководства об основах работы с контейнерными утилитами Linux, вы можете приступать к созданию собственных эффективных разделов ресурсов. Этот материал основан на работе, поддержанной Агентством передовых оборонных исследовательских проектов (DARPA), в рамках Соглашения HR0011-07-9-0002.
|
||||||||||||||||||||||||||||||||||||||||||||||
Так же в этом разделе:
|
||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
|