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 эффективно параллелиться по всем процессорам демонстрируя великолепную производительность.

PR-1505-3

Контейнеризация сегодня — одна из самых актуальны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/

Вот и всё: конфигурация сети завершена. Теперь можно перезапустить сервис:

Читайте также: