Systemd nspawn ubuntu как установить
Обновлено: 05.07.2024
На данный момент я работаю в проекте который в качестве целевой платформы установки использует Debian 7 при этом хочется переехать на Debain 8, а сам я сижу на Arch Linux. В результате часто требуется быстренько оказаться в правильном окружении и пособирать свои последние правки. Чаще всего для этого я использовал VirtualBox как наиболее просто конфигурируемое решение, но всегда хотелось побаловаться с лёгкими контейнерами. Правда, всегда отпугивала скорость разворачивания таких решений. Я экспериментировал с LXC и systemd-nspawn, но в первом случае разворачивание виртуалки занимает больше времени чем хочется, а во втором случае всё гладко только если гостевая система использует systemd.
Но вот, свершилось, Debain 8 использует systemd по умолчанию и его можно быстренько разворачивать. Правда, кто-то успел немного подгадить с другой стороны. Теперь в арче сервис systemd-nspawn@ по умолчанию предлагает иметь противоестественные сношения с настройкой идеологически правильного разделения сети между контейнерами добавив ключ --network-veth. Раньше этот сервис позволял запустить контейнер так, что он просто видел хостовый интерфейс и им пользовался, что совершенно не подходит для облачных решений (для которых есть отличные и мощные проекты, такие как OpenVZ и LXC), но очень удобно для нужд разработчиков (а именно для этих целей и позиционировалась разработка systemd-nspawn). Дабы раз и навсегда искоренить этот печальный недостаток, копируем этот сервис из /usr/lib/systemd/system в /etc/systemd/system и уничтожаем использование ненужной "идеологической правильности".
Итак создаём гостевуху: Мы оказались в сверх-минималистичном дебиане с целью задать пароль пользователю root и установить пакет dbus (без него утилита machinectl не сможет подключиться к запущенному контейнеру). Выполнив эти две нехитрые операции нажимаем Ctrl+D чтобы вернуться в основное окружение и честно загрузив контейнер входим в него через парадное крыльцо для дальнейшей настройки:
Вот готово почти всё. Точнее для одноразового использования готово вообще всё. А вот если контейнер планируется использовать для тестов регулярно, то имеет смысл поставить туда ssh и научить systemd автоматически запускать виртуалку при попытке в неё зайти по этому самому ssh. Для этого пишем файл на хосте
/etc/systemd/system/systemd-nspawn@debian8.socket: А в гостевой ситеме надо отключить безусловный автозапуск SSH и настроить его активацию через сокет добавив два файла:
/etc/systemd/system/sshd.socket: и /etc/systemd/system/sshd@.service: После чего в контейнере переключаем SSH на активацию через сокет: И на хосте активируем сокет запуска машины:
Ну вот теперь можно настроить профиль в Konsole и быстренько заходить в виртуалку в два клика. Запуск контейнера до состояния принятия ssh соединения у меня занимает около 2х секунд, что несравнимо меньше времени ожидания старта VirtualBox виртуалки, а сборка кода с помощью ninja эффективно параллелиться по всем процессорам демонстрируя великолепную производительность.
Контейнеризация сегодня — одна из самых актуальныx тем. Количество публикаций о таких популярных инструментах, как LXC или Docker, исчисляется тысячами, если не десятками тысяч.
В этой статье бы хотели мы обсудить ещё одно решение, о котором публикаций на русском языке пока что мало. Речь идёт о systemd-nspawn — инструменте для создания изолированных сред, который является одним из компонентов systemd. А закрепление systemd в качестве стандарта в мире Linux — уже свершившийся факт. В свете этого факта есть все основания полагать, что в ближайшее время сфера применения systemd-nspawn существенно расширится, и познакомиться с этим инструментом поближе стоит уже сейчас.
Systemd-nspawn: общая информация
Название systemd-nspawn представляет собой сокращение от namespaces spawn. Уже из этого названия следует, что systemd-nspawn управляет только изоляцией процессов, но при этом не может изолировать ресурсы (однако это можно сделать средствами самого systemd, о чём ещё пойдёт речь ниже).
С помощью systemd-nspawn можно создать полностью изолированое окружение, в котором автоматически будут смонтированы псевдофайловые системы /proc и /sys, а также созданы изолированный loopback-интерфейс и отдельное пространство имён для идентификаторов процессов (PID), внутри которого можно запускать ОС, основанную на ядре Linux.
Cпециального репозитория образов, как в Docker, в systemd-nspawn не существует. Для создания и загрузки образов можно использовать любые сторонние инструменты. Поддерживаются форматы tar, raw, qcow2 и dkr (dkr — это образы для Docker; в документации к systemd-nspawn об этом в явной форме нигде не написано, а её авторы старательно избегают самого слова Docker). Работа с образами осуществляется на базе файловой системы BTRFS.
Запускаем в контейнере Debian
Знакомство с systemd-nspawn начнём с простого, но показательного практического примера. На сервере под управлением OC Fedora мы создадим изолированное окружение, в котором будет запущен ОС Debian. Все примеры команд ниже приводятся для Fedora 22 c systemd 219-й версии; в других дистрибутивах Linux и других версиях systemd команды могут отличаться.
Начнём с установки необходимых зависимостей:
Затем создадим файловую систему для будущего контейнера:
По завершении всех подготовительных работ можно приступать к запуску контейнера:
На консоли появится приглашение гостевой операционной системы:
Установим для неё root-пароль:
Выйдем из контейнера, нажав комбинацию клавиш Ctrl+]]], а затем выполним следующую команду:
В ней присутствует флаг -b (или −−boot), который указывает, что при запуске экземпляра операционной системы в контейнере нужно выполнить init с запуском всех демонов.Этот флаг можно использовать только в случае, если в контейнере будет запущена система с поддержкой systemd.В противном случае загрузка системы не гарантируется.
По завершении всех указанных операций система предложит ввести логин и пароль.
Итак, полноценная ОС в изолированном окружении запущена. Теперь нужно настроить для неё сеть, Выйдем из контейнера и создадим мост, через который он будет соединятся с интерфейсом на основном хосте:
Назначим для этого моста IP-адрес:
После этого выполним команду:
Для настройки сети можно также воспользоваться опцией −−network-ipvlan, которая свяжет контейнер с указанным интерфейсом на основном хосте с помощью ipvlan:
Запускаем контейнер как службу
С помощью systemd можно настроить автоматический запуск контейнеров при загрузке системы. Для этого добавим в директорию /etc/systemd/system вот такой конфигурационный файл:
Прокомментируем приведённый фрагмент. В cекции [Description] мы просто указываем имя контейнера. В секции [Service] мы сначала задаём лимит на количество открытых файлов в контейнере (LimitNOFILE), затем указываем команду на запуск контейнера с необходимыми опциями (ExecStart). Указание Restart=always означает, что контейнер нужно перезапустить в случае «падения». В секции [Install] указывается дополнительный юнит, который должен быть добавлен в автозапуск на хосте (в нашем случае это система межпроцесcного взаимодействия D-Bus).
Сохраним изменения в конфигурационном файле и выполним команду:
Запускать контейнер как службу можно и другим, более простым способом. В systemd имеется заготовка конфигурационного файла для автоматического запуска контейнеров, помещённых в директорию /var/lib/machines. Активировать запуск на базе этой заготовки можно с помощью следующих команд:
Управление контейнерами: утилита machinectl
Контейнерами можно управляться с помощью утилиты machinectl. Кратко рассмотрим её основные опции.
Вывести список всех имеющихся в системе контейнеров:
Просмотреть информацию о статусе контейнера:
Войти в контейнер:
Последняя команда cработает, если в контейнере установлена ОС, совместимая с systemd. Для операционных систем, использующих sysvinit, нужно воспользоваться опцией terminate.
Мы рассказали лишь о самых базовых возможностях утилиты machinectl; с подробной инструкцией по её использованию можно ознакомиться, например, здесь.
Загрузка образов
Выше мы уже говорили, что с помощью systemd-nspawn можно запускать образами любых других форматов. Есть, однако, одно важное условие: работа с образами возможна только на базе файловой системы BTRFS, которую нужно примонтировать к директории /var/lib/machines:
Если нет свободного диска, BTRFS можно сделать и в файле.
В более новых версиях systemd возможность загрузки образов поддерживается «из коробки», и монтировать BTRFS не нужно.
Попробуем загрузить образ Docker:
Запуск контейнера на базе загруженного образа осуществляется просто:
Просмотр логов контейнера
Информация обо всех событиях, происходящих внутри контейнеров, записывается в логи. Настройки логгирования можно устанавливать непосредственно при создании контейнера с помощью опции
−−link-journal, например:
Приведённая команда указывает, что логи контейнера будут храниться с на основном хосте в директории /var/log/journal/machine-id. Если же выставить опцию −−link-journal=guest, то вся логи будут храниться в контейнере в директории /var/log/journal/machine-id, а на основном хосте будет создана символическиая ссылка в директории c аналогичным адресом. Опция −−link-journal будет работать только в случае, если в контейнере будет запущена система с systemd. В противном случае корректное логгирование не гарантируется.
Просмотреть информацию о запусках и остановках контейнера можно с помощью утилиты journalctl, о которой мы уже писали одной из предыдущих публикаций:
В journalctl предусмотрена возможность просмотра логов событий внутри контейнера.
Для этого используется опция -M (приводим лишь небольшой фрагмент вывода):
Выделение ресурсов
Основные особенности systemd-nspawn мы рассмотрели. Остался один важный момент: выделение контейнерам ресурсов. Как уже отмечалось выше, systemd-nspawn ресурсы не изолирует. Ограничить потребление ресурсов для контейнера можно с помощью systemctl, например:
Ограничения ресурсов для контейнера можно прописать и в юнит-файле, в секции [Slice].
Заключение
Systemd-nspawn — инструмент интересный и перспективный. В числе его несомненных плюсов стоит выделить:
- тесную интеграцию с другими компонентами systemd;
- возможность работы с образами в разных форматах;
- отсутствие необходимости устанавливать какие-либо дополнительные пакеты или накладывать патчи на ядро.
Конечно, говорить о полноценном использовании systemd-nspawn в продакшне пока что рано: инструмент пока что находится в «сыром» состоянии и подходит только для тестирования и экспериментов. Однако по мере дальнейшего распространения systemd стоит ждать и усовершенствования systemd-nspawn.
Естественно, что в рамках обзорной статьи невозможно рассказать абсолютно обо всём. В комментариях приветствуются любые вопросы, замечания и дополнения.
Если мы упустили какие-то детали или не рассказали о каких-то интересных возможностях systemd-nspawn — напишите, и мы обязательно дополним наш обзор.
А если кто-то из вас пользуется systemd-nspawn, приглашаем поделиться опытом.
Читателей, которые по тем или иным причинам не могут оставлять комментарии здесь, приглашаем в наш блог.
Всякая всячина, которую дядюшка Раджа находит в интернете и хочет поделиться с читателями.
Об авторе
Архив блога
Мой блог смотрят
09 июля 2016
Как я с systemd-nspawn знакомился.
Systemd-nspawn - это такой механизм для запуска системы в изолированном пространстве (namespace). C помощью этого механизма можно запустить на одном ядре linux фактически несколько разных дистрибутивов. Очень похоже на chroot, но более ограничено во взаимодействии с системой.
У меня на домашнем сервере стоит Debian 8. Но истинному админу локалхоста всё время хочется что-то подкрутить и прикрутить. Вот тут такая система контейнеров и пригодится.
В результате очередного эксперимента всё упёрлось в версии пакетов в репозитории Debian Jessie. Я начал руками пересобирать пакеты из ветки sid, но в итоге цепочка зивисимостей вывела мена к версии gcc. Я плюнул на это дело, удалил весь мусор, который набрался при скачивании и сборке разных пакетов и поставил в систему "debootstrap", чтобы сделать в отдельно взятом каталоге свой Debian с пакетами и репозиториями.
По опыту общения с WD My Book Live я адаптировал скрипт запуска chroot-окружения. Всё запускалось и вроде как даже работало, но всё равно решение казалось очень костыльным. Тогда я попробовал натравить на развёрнутую систему "systemd-nspawn" такой командой:
Сразу же очутился в новой системе. В списке процессов практически пусто, но система работает и даже по сети с миром может общаться. Все необходимые виртальные файловые системы смонтированны, ничего руками и скриптами делать не надо. Но система пока не настоящая, потому что нужные сервисы всё равно надо запускать руками, пользователей фактический нет, если root не считать, да и выход из такого окружения тормозит систему в контейнере.
Вот тут сразу перепрыгну все свои пробы и ошибки и опишу процесс полноценного запуска окружения. Команды приводить не буду, просто опишу шаги.
Сначала я сменил пароль для root, чтобы можно было хоть как-то входить в систему. Потом поставил ssh-сервер "openssh-server", чтобы без лишних телодвижений попадать в нужную систему, и сразу перевёл его на другой порт, чтобы не конфликтовал с уже установленным в основной системе.
Теперь можно попробовать запустить контейнер с ключом "-b", чтобы система в нём действительно загрузилась.
Появится короткий лог загрузки и приглашение для ввода логина. После логина под root можно посмотреть список процессов и убедиться, что ssh-сервер работает и даже принимает соединения. Нажатие "Ctrl+]]]" всё равно убивает контейнер со всем содержимым.
Для запуска контейнера при загрузке системы достаточно сделать символическую ссылку на корневой каталог контейнера в " /var/lib/container/ " и активировать сервис "systemd-nspawn@conteiner", где "container" - это имя символической ссылки.
Теперь контейнером можно управлять как обычным systemd-сервисом.
UPDATE: Символической ссылки теперь не достаточно. Systemd 232 при такой схеме портит права внутри каталога контейнера, фактически ломая его.
Systemd полностью поддерживается в Ubuntu 15.04 и старше.
Запуск systemd-networkd
Чтобы использовать, запустите следующие две службы и включите их работу при загрузке системы (отключив при этом другие демоны, управляющие конфигурацией сети, например netplan):
Конфигурирование
Конфигурационные файлы systemd-networkd находятся в директории /etc/systemd/network. Доступны следующие типы файлов:
Все они следуют тем же правилам:
- Если все условия в [Match] разделе совпали, профиль будет активирован
- Пустая секция [Match] означает, что профиль будет применяться в любом случае (можно сравнить с шуткой *)
- Каждая запись с синтаксисом NAME=VALUE является ключевой
- все файлы настроек вместе сортируются и обрабатываются в лексическом порядке, независимо от каталога, в котором они живут
- файлы с одинаковым именем сменяют друг друга
[Match] раздел
Наиболее распространенные ключи:
- Name= имя устройства (например Br0, enp4s0, en*)
- Host= имя машины
- Virtualization= проверить, является ли система выполненной в виртуализированной среде или нет. Virtualization=no ключ будет применяться только на вашей машине, в то время как Virtualization=yes применяются к любому контейнеру или VM.
[Network] раздел
Наиболее распространенные ключи:
- DHCP= включает поддержку DHCPv4 и/или DHCPv6. Принимает: yes, no, ipv4 или ipv6
- DNS= является DNS адрес сервера. Вы можете указать этот параметр более одного раза
- Bridge= это имя моста, чтобы добавить ссылку на
- IPForward= по умолчанию no. Это разрешает IP forwarding, выполняя пересылку в соответствии с таблицей маршрутизации и необходим для настройки. Заметим, что включение IPForward= относится ко всем сетевым интерфейсам.
- Domains= список доменов, используемых для разрешения имен DNS хоста.
[Address] раздел
Большинство общих ключ в разделе [Address]:
- Address= статический IPv4 или IPv6 адрес и его длина префикса, разделенных символом / (например 192.168.1.90/24). Эта опция обязательна, если не используется DHCP
[Route] раздел
Большинство общих ключ в разделе [Route]:
- Gateway= это адрес шлюза вашей машины. Эта опция обязательна если не используется DHCP.
Конфигурация для примера: два интерфейса со статическим IP в LAN и WAN.
Необходимо создать 4 файла в директории /etc/systemd/network/
Вот и всё: конфигурация сети завершена. Теперь можно перезапустить сервис:
Читайте также: