LXD Containers

Продолжаем наш цикл статей о контейнеризации. Если первые две статьи (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 вряд ли возможно. Для желающих узнать больше приводим несколько полезных ссылок:

Поделиться с друзьями
-->

Комментарии (21)


  1. dmitry_ch
    22.08.2016 13:36

    В Proxmox 4 в комплекте есть поддержка LXC. Нет ли у вас опыта с ней? Как приличный GUI для управления контейнерами, хранением, резервным копированием это явно удобный вариант, но там все же Debian 8 в основе лежит.


    1. RicoX
      22.08.2016 14:43
      +1

      Пока все очень грустно с LXC, смотрите тему


      1. korzunin
        22.08.2016 15:19

        С момента написания той статьи прошло пол года, на текущий момент ничего не изменилось? =(


        1. RicoX
          22.08.2016 15:31

          Ну я каждую неделю в песочнице не тыкаю, но два месяца назад все еще было печально, в багтреккере висит просто уйма критичных багов, для продакшина LXC пока не готов. Поставить потыкать можно, но он сильно отстает даже от OpenVZ прошлого поколения на ядрах 2.6.


      1. dmitry_ch
        22.08.2016 21:38

        Читал, иначе бы не спрашивал.

        В том и дело, что в PVE вроде как все грустно (но о грусти рассказали некоторое время назад), в то время как LCX с LCD вот в статье хвалят.

        Получается, LXC вполне работает, и только «злой и страшный» Proxmox в составе себя мешает ему работать как надо, или все же виной тому в первую очередь LXC?

        Пока остается только верить слухам (потому что переводить рабочие машины на LXC, «чтобы посмотреть» — не самое быстрое и надежное решение для оценки). Очень рассчитывал получить комментарий от Selectel — все же компания уважаемая, и материалы пишет толковые.


      1. Temtaime
        22.08.2016 23:42

        Нет ничего грустного. Грустно только в проксмоксе. Там — да, баги и боль.
        Использую в продакшене порядка полутора лет с btrfs. Ничего ещё не падало и не ломалось.
        Всё работает из коробки.
        Честно, не вижу смысла в lxd. Есть же lxc и его команды.


  1. Sanes
    22.08.2016 13:52
    -1

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


    1. RicoX
      22.08.2016 14:46
      +2

      Так в контейнере имеется свой собственный локальный root, каких именно прав не хватает?


      1. Sanes
        23.08.2016 15:38

        Вы уверены, что у него полноценные права?


        1. RicoX
          23.08.2016 17:24

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


          1. Sanes
            24.08.2016 00:39

            Буквально сегодня попробовал.

            lxc exec ct-name bash
            passwd root
            exit
            ssh root@10.0.4.100
            Пароль неверный!
            


    1. vistoyn
      23.08.2016 09:21
      +1

      В LXD специально запускают контейнеры и не предоставляют полноценный рут, чтобы программы в контейнере не могли хаком через /proc получить root доступ к хост машине.
      Можно запустить контейнер в привелигированном режиме и тогда будет такой же рут как и на хосте. Делается это командой:


      lxc config set container_name security.privileged true

      Только так не рекомендуют делать.


      1. Sanes
        23.08.2016 15:44

        В том-то и дело, что это дыра.


      1. Sovigod
        23.08.2016 19:34

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


  1. devpreview
    22.08.2016 15:02
    -6

    Уважаемый Селектел! Вопрос не по теме.

    Вы закрыли услугу «Облачный сервер». На данный момент мы уже 10 дней пытаемся забрать образ диска от облачного сервера, т.к. самостоятельно создать сервер, подмонтировать к нему диск и снять образ не можем — услуга закрыта, новый сервер мы самостоятельно создать не можем.

    Поспособствуйте решению проблемы, пожалуйста. Тикет #386040


    1. devpreview
      22.08.2016 22:22

      Проблема решена, благодарю.


  1. icoz
    23.08.2016 07:54

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


    1. 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, но для них сходу документации не нашёл. Буду рад если кто-нибудь дополнит.


      1. icoz
        23.08.2016 19:22

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


        1. 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" (перевод)


  1. icoz
    23.08.2016 19:21

    Ещё вопрос. А как там организован сам образ системы? Почему нельзя через lxd запустить какое-то приложение, которое можно запустить в докере?