
Продолжаем наш цикл статей о контейнеризации. Если первые две статьи (1 и 2) были посвящены теории, то сегодня мы поговорим о вполне конкретном инструменте и об особенностях его практического использования. Предметом нашего рассмотрения будет LXD (сокращение от Linux Container Daemon), созданный канадцем Стефаном Грабе из компании Canonical.
Имя создателя LXD хорошо известно в профессиональном сообществе: он также является одним из авторв другого популярного контейнерного решения — LXC. Собственно, LXD представляет собой надстройку над LXC, которая упрощает работу с контейнерами и добавляет широкий спектр новых возможностей.
В рамках этой статьи мы ограничимся лишь кратким введением в LXD: сравним его с Docker, приведём инструкцию по установке и настройке, а также продемонстрируем базовые возможности управления контейнерами.
LXD и Docker
LXD — инструмент относительно новый: первая версия вышла в свет в 2014 году, когда Docker уже получил широкое распространение и хорошо зарекомендовал себя на практике.
Как и Docker, LXD функционирует на базе LXC.
При этом cфера применения у двух инструментов совершенно разная: если Docker предназначен для запуска в контейнерах приложений, то LXD — для запуска полноценных операционных систем.
С помощью LXD можно создавать даже не контейнеры в буквальном смысле этого слова, а легковесные виртуальные машины. Чтобы подчеркнуть этот момент и одновременно указать на отличие от других инструментов контейнеризации, авторы многих публикаций называют LXD словом lightvisor (на русский язык его уже переводят как «легковизор»).
В публикациях Canonical отмечается, что LXD-контейнеры могут работать в 10 раз быстрее, чем традиционные виртуальные машины на базе KVM.
В LXD предпринята попытка решить целый ряд проблем, с которыми приходится сталкиваться при работе с другими инструментами контейнеризации: продуман механизм динамического управления ресурсами, расширены возможности миграции контейнеров (в том числе и в режиме реального времени), устранены проблемы безопасности. По сравнению с Docker у LXD гораздо шире возможности переконфигурации контейнеров.
LXD оснащён открытым API; имеются клиенты для различных языков программирования. Создан плагин для OpenStack, позволяющий управлять контейнерами с помощью клиента Nova.
Установка и настройка
Здесь и далее мы будем описывать особенности работы c LXD на материале Ubuntu 16.04. В этой ОС LXD включён в официальные репозитории и устанавливается стандартным способом:
apt-get install lxdСтефан Грабе в своей статье рекомендует в качестве бэкенда для хранения контейнеров использовать файловую систему ZFS. Чтобы работать с ZFS, нужно установить соответствующие пакеты:
apt-get install zfsutils-linuxЕсли ZFS вам по тем или иным причинам не подходит, вы можете воспользоваться BTRFS или LVM (подробнее об этом см. здесь).
По завершении установки выполним команду:
lxd initПрограмма настройки задаст несколько простых вопросов, после чего всё будет сконфигурировано автоматически. Подробнее об особенностях настройки LXD можно прочитать в этой статье.
Создание контейнера
Все контейнеры в LXD создаются на базе образов. Образы можно получить как из локального, так и из удалённого репозитория. Просмотрим список доступных репозиториев:
lxc remote list
+-----------------+------------------------------------------+---------------+--------+--------+
| NAME | URL | PROTOCOL | PUBLIC | STATIC |
+-----------------+------------------------------------------+---------------+--------+--------+
| images | https://images.linuxcontainers.org | lxd | YES | NO |
+-----------------+------------------------------------------+---------------+--------+--------+
| local (default) | unix:// | lxd | NO | YES |
+-----------------+------------------------------------------+---------------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | simplestreams | YES | YES |
+-----------------+------------------------------------------+---------------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | simplestreams | YES | YES |
+-----------------+------------------------------------------+---------------+-------Для первого знакомства с LXD вполне подойдёт локальный репозиторий (local). Запустим в контейнере ОС Ubuntu 16.04:
lxc launch ubuntu:16.04 container1В результате выполнения этой команды LXD создаст на базе указанного образа контейнер и запустит его.
Запустить в этом контейнере командную оболочку можно с помощью команды:
lxc exec container1 /bin/bashЕсли нужно просто создать контейнер, но не запускать его, достаточно выполнить команду:
lxc init ubuntu:16.04 container1Для последующего запуска и остановки контейнера используются команды lxc start и lxc stop.
LXC предоставляет хорошие возможности для управления контейнерами «на лету». Вот так, например, можно поместить созданный на основном хосте файл внутрь контейнера:
lxc file push [путь к файлу на основном хосте] [контейнер]/[путь]Можно совершить и обратную операцию — загрузить файл из контейнера на основной хост:
$ lxc file pull [контейнер]/[путь]Можно и редактировать файлы в контейнере напрямую:
lxc edit [контейнер]/[путь]Основные команды для создания и запуска контейнеров мы уже рассмотрели; желающих узнать больше отсылаем к подробной статье Стефана Грабе.
Управление ресурсами
Управление изолированными окружениями немыслимо без контроля ресурсов: мы должны предоставить контейнеру достаточное количество ресурсов для работы и в то же время быть уверенными в том, что контейнер не будет потреблять лишних ресурсов, нарушая тем самым работу остальной системы.
В LXD можно выделять контейнерам ресурсы при помощи специального набора команд:
# устанавливаем лимит памяти
lxc config set container1 limits.memory 512M
# привязываем контейнер к ядрам CPU
lxc config set container1 limits.cpu 1,3
# ограничиваем потребление ресурсов CPU
lxc config set container1 cpu.allowance 10%
# ограничиваем объём используемого контейнером дискового пространства(работает только с ZFS или btrfs)
lxc config set container1 root size 10GBБолее подробно почитать об управлении ресурсами можно в этой статье.
Просмотреть статистику потребления ресурсов для контейнера можно с помощью простой команды:
lxc info container1
Name: container1
Architecture: x86_64
Created: 2016/08/16 07:55 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 4110
Ips:
lo: inet 127.0.0.1
lo: inet6 ::1
eth0: inet6 fe80::216:3eff:fe18:faa9 vethA2SCMX
Resources:
Processes: 24
Memory usage:
Memory (current): 48.88MB
Memory (peak): 163.26MB
Network usage:
eth0:
Bytes received: 648 bytes
Bytes sent: 648 bytes
Packets received: 8
Packets sent: 8
lo:
Bytes received: 264 bytes
Bytes sent: 264 bytes
Packets received: 4
Packets sent: 4Работа со снапшотами
В LXD имеется возможность создания снапшотов и восстановления контейнеров из снапшотов. Посмотрим, как это работает на практике (пример взят из интерактивного туториала LXD).
Внесём некоторые изменения в уже созданный нами контейнер container1:
lxc exec container1 -- apt-get update
lxc exec container1 -- apt-get dist-upgrade -y
lxc exec container1 -- apt-get autoremove —purge -yСделаем снапшот этого контейнера и назовём его, например, new:
lxc snapshot container1 newПопробуем что-нибудь «поломать» в нашем первом контейнере:
lxc exec container1 -- rm -Rf /etc /usrПоcле этого запустим в нём в нём командную оболочку:
lxc exec container -- bash
I have no name!@container1:~#Выполним команду exit и вернёмся на основной хост. Восстановим работу контейнера container1 из снапшота:
lxc restore container1 newЗапустим командную оболочку в восстановленном контейнере:
lxc exec container1 -- bash
root@container1:#Всё работает так же, как раньше!
В приведённом выше примере мы рассмотрели так называемые stateless-снапшоты В LXD есть и другой тип снапшотов — stateful, в которых сохраняется текущее состояние всех процессов в контейнере. Со stateful-снапшотами связаны ряд интересных и полезных функций.
Чтобы создавать stateful-снапшоты, нам понадобится установить программу CRIU(CheckPoint/Restore in Userspace). C её помощью можно сохранить текущее состояние всех процессов, а затем восстановить их хоть на текущей, хоть на другой машине.
В Ubuntu 16.04 утилита CRIU устанавливается при помощи стандартного менеджера пакетов:
apt-get install criuПосле этого можно переходить к созданию снапшотов:
lxc snapshot container1 snapshot1 --statefulВ некоторых ситуациях такие снапшоты могут оказаться очень полезными. Представим себе, например, что нам нужно перезагрузить сервер, на котором запущены один или несколько контейнеров. Чтобы после перезагрузки не запускать всё заново, а продолжить с прерванного места, достаточно выполнить:
# перед перезагрузкой
lxc stop container1 --stateful
#после перезагрузки
lxc start container1На базе stateful-снапшотов реализован механизм «живой» миграции контейнеров, который пока что находится в несколько «сыром» состоянии.
Заключение
LXD представляет собой удобную систему управления контейнерами, обладающую целым рядом полезных функций. Надеемся, что проект LXD будет успешно развиваться и займёт достойное место в ряду современных инструментов контейнеризации.
Если у вас есть практический опыт использования LXD — добро пожаловать в комментарии.
Если вы по тем или иным причинам не можете комментировать посты здесь — добро пожаловать в наш корпоративный блог.
Естественно, в рамках одной статьи рассказать обо всех функциях LXD вряд ли возможно. Для желающих узнать больше приводим несколько полезных ссылок:
- https://www.stgraber.org/2016/03/11/lxd-2-0-blog-post-series-012/ — цикл статей об LXD в блоге Стефана Грабе;
- http://vasilisc.com/lxd-2-0-series — перевод всех статей по предыдущей ссылке на русский язык;
- https://insights.ubuntu.com/2016/04/19/directly-interacting-with-the-lxd-api/ — статья-введение в LXD API;
- https://www.openstack.org/summit/vancouver-2015/summit-videos/presentation/lxd-vs-kvm — видеозапись доклада о перспективах использования LXD в OpenStack.
Комментарии (21)

Sanes
22.08.2016 13:52-1Всё бы ничего. Но как в этом хозяйстве предоставить полноценные права root для контейнера? Я так понял, что это до сих пор остаётся для собственных нужд и никак не подходит для шареда.

RicoX
22.08.2016 14:46+2Так в контейнере имеется свой собственный локальный root, каких именно прав не хватает?

Sanes
23.08.2016 15:38Вы уверены, что у него полноценные права?

RicoX
23.08.2016 17:24Раскройте мысль каких именно прав не хватает, права полноценные но в рамках контейнера, естественно вырубить гипервизор или отключить глобально оборудование из контейнера не выйдет.

Sanes
24.08.2016 00:39Буквально сегодня попробовал.
lxc exec ct-name bash passwd root exit ssh root@10.0.4.100 Пароль неверный!

vistoyn
23.08.2016 09:21+1В LXD специально запускают контейнеры и не предоставляют полноценный рут, чтобы программы в контейнере не могли хаком через /proc получить root доступ к хост машине.
Можно запустить контейнер в привелигированном режиме и тогда будет такой же рут как и на хосте. Делается это командой:
lxc config set container_name security.privileged true
Только так не рекомендуют делать.

Sovigod
23.08.2016 19:34Давно хотел узнать. А зачем может быть нужно такое повышение прав в контейнере? Больше 2 лет держу все сервисы на продакшене в lxc-кантейнерах и никогда не было такой надобности.

devpreview
22.08.2016 15:02-6Уважаемый Селектел! Вопрос не по теме.
Вы закрыли услугу «Облачный сервер». На данный момент мы уже 10 дней пытаемся забрать образ диска от облачного сервера, т.к. самостоятельно создать сервер, подмонтировать к нему диск и снять образ не можем — услуга закрыта, новый сервер мы самостоятельно создать не можем.
Поспособствуйте решению проблемы, пожалуйста. Тикет #386040

icoz
23.08.2016 07:54А как у lxd с репозиторием образов дела обстоят? Насколько сложно свой поднять?

clickfreak
23.08.2016 16:15+2Вот тут (перевод) сказано что самый простой способ — расшарить public-образы (соответствующий флаг образа) на одном из lxd-серверов:
lxc config set core.https_address "[::]:8443"
И затем на другом хосте добавить его как публичный источник образов:
lxc remote add <some name> <IP or DNS> --public
Однако аутентификации в этом случае не предусмотрено. Также можно поднять особым образом настроенный веб-сервер (заголовки и т.п.) с сертификатами. Ещё есть вариант с некими simplestrams, но для них сходу документации не нашёл. Буду рад если кто-нибудь дополнит.

icoz
23.08.2016 19:22Короче, как создать свой образ системы с нуля? Ибо в их перечне нет, например, Archlinux.

clickfreak
23.08.2016 20:11Коротко: создаёте файловую систему, добавляете метаинформацию, пакуете в тарбол и импортируете в LXD
На https://images.linuxcontainers.org/ пишут следующее:
"All images available on this server are generated using community supported, upstream LXC image templates available here." И далее по тексту идут ссылки на CI-скрипты сборки образов.
Так что можно посмотреть имена шаблонов lxc-контейнеров и использовать их для создания образов LXD с помощью представленных ci-скриптов.
Отдельная документация про формат образов:
https://github.com/lxc/lxd/blob/master/doc/image-handling.md#image-format
Про процедуру создания и импорта образа описано в "LXD 2.0: Image management" (перевод)

icoz
23.08.2016 19:21Ещё вопрос. А как там организован сам образ системы? Почему нельзя через lxd запустить какое-то приложение, которое можно запустить в докере?
dmitry_ch
В Proxmox 4 в комплекте есть поддержка LXC. Нет ли у вас опыта с ней? Как приличный GUI для управления контейнерами, хранением, резервным копированием это явно удобный вариант, но там все же Debian 8 в основе лежит.
RicoX
Пока все очень грустно с LXC, смотрите тему
korzunin
С момента написания той статьи прошло пол года, на текущий момент ничего не изменилось? =(
RicoX
Ну я каждую неделю в песочнице не тыкаю, но два месяца назад все еще было печально, в багтреккере висит просто уйма критичных багов, для продакшина LXC пока не готов. Поставить потыкать можно, но он сильно отстает даже от OpenVZ прошлого поколения на ядрах 2.6.
dmitry_ch
Читал, иначе бы не спрашивал.
В том и дело, что в PVE вроде как все грустно (но о грусти рассказали некоторое время назад), в то время как LCX с LCD вот в статье хвалят.
Получается, LXC вполне работает, и только «злой и страшный» Proxmox в составе себя мешает ему работать как надо, или все же виной тому в первую очередь LXC?
Пока остается только верить слухам (потому что переводить рабочие машины на LXC, «чтобы посмотреть» — не самое быстрое и надежное решение для оценки). Очень рассчитывал получить комментарий от Selectel — все же компания уважаемая, и материалы пишет толковые.
Temtaime
Нет ничего грустного. Грустно только в проксмоксе. Там — да, баги и боль.
Использую в продакшене порядка полутора лет с btrfs. Ничего ещё не падало и не ломалось.
Всё работает из коробки.
Честно, не вижу смысла в lxd. Есть же lxc и его команды.