Snap и deb противопоставляют друг другу, хотя deb - это по большей части архив аля zip. Snap пакет хоть и сжат с помощью squashfs, но содержимое никто никуда не распаковывает, а банально монтируют, передавая в руки системы мандатного доступа AppArmor. LXD так же является изоляцией, используя LXC в качестве низкоуровневого инструмента. И тут не могло не быть технических проблем, чтобы одна "изоляция" работала внутри другой. Стефан Грабер (Stéphane Graber) в своей новой статье, но не в рамках цикла статей про LXD, рассказывает о реализованной возможности поставить snap пакет внутри LXD контейнера.
Команды проектов LXD и AppArmor работали над решением поддержки профилей AppArmor внутри LXD контейнеров. С последними ядрами в Ubuntu, наконец-то, появилась возможность поставить программу в snap пакете внутри LXD. Пакеты snap, как многим стало известно, новый путь дистрибьюции ПО напрямую из апстрима с целым рядом функций безопасности, обёрнутые вокруг пакетов так, что они не смогут помешать работе друг друга или причинить вред системе.
Есть много различных кусочков мозаики, которые вместе заставляют заработать вместе эти две технологии - snap и LXD. Начальная работа была проделана, когда хостовой операционной системой и гостевой внутри контейнера была Ubuntu 16.10. Но всё нужное проталкивается через обновления и в Ubuntu 16.04 LTS.
Самый простой путь увидеть совместную работу технологий:
Вначале создадим нужный контейнер по имени nextcloud с нужной системой Ubuntu 16.10 и пакетом squashfuse.
lxc launch ubuntu:16.10 nextcloud
lxc exec nextcloud -- apt update
lxc exec nextcloud -- apt dist-upgrade -y
lxc exec nextcloud -- apt install squashfuse -y
Теперь внутри контейнера nextcloud можно поставить одноимённый snap пакет nextcloud.
lxc exec nextcloud -- snap install nextcloud
Теперь можно узнать IP адрес, чтобы браузером зайти и увидеть веб интерфейс.
lxc list nextcloud
+-----------+---------+----------------------+----------------------------------------------+ | NAME | STATE | IPV4 | IPV6 | +-----------+---------+----------------------+----------------------------------------------+ | nextcloud | RUNNING | 10.148.195.47 (eth0) | fd42:ee2:5d34:25c6:216:3eff:fe86:4a49 (eth0) | +-----------+---------+----------------------+----------------------------------------------+
Сначала нам нужен новый контейнер (в примере имя дано lxd) с Ubuntu 16.10 внутри и контейнер должен быть с поддержкой вложенности.
lxc launch ubuntu:16.10 lxd -c security.nesting=true
lxc exec lxd -- apt update
lxc exec lxd -- apt dist-upgrade -y
lxc exec lxd -- apt install squashfuse -y
Внутри контейнера будет предустановлен пакет lxd и его нужно удалить - lxc exec lxd -- apt remove --purge lxd lxd-client -y
Теперь нам нужно установить самую топовую версию lxd через канал edge - lxc exec lxd -- snap install lxd --edge
Заходим внутрь контейнера lxc exec lxd bash
Внутри контейнера инициализируем и настраиваем "внутренний" lxd.
root@lxd:~# lxd init
Name of the storage backend to use (dir or zfs) [default=dir]: We detected that you are running inside an unprivileged container. This means that unless you manually configured your host otherwise, you will not have enough uid and gid to allocate to your containers. LXD can re-use your container's own allocation to avoid the problem. Doing so makes your nested containers slightly less safe as they could in theory attack their parent container and gain more privileges than they otherwise would. Would you like to have your containers share their parent's allocation (yes/no) [default=yes]? Would you like LXD to be available over the network (yes/no) [default=no]? Would you like stale cached images to be updated automatically (yes/no) [default=yes]? Would you like to create a new network bridge (yes/no) [default=yes]? What should the new bridge be called [default=lxdbr0]? What IPv4 subnet should be used (CIDR notation, “auto” or “none”) [default=auto]? What IPv6 subnet should be used (CIDR notation, “auto” or “none”) [default=auto]? LXD has been successfully configured.
root@lxd:~# lxd.lxc launch images:archlinux arch
If this is your first time using LXD, you should also run: sudo lxd init To start your first container, try: lxc launch ubuntu:16.04 Creating arch Starting arch
root@lxd:~# lxd.lxc list
+------+---------+----------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +------+---------+----------------------+-----------------------------------------------+------------+-----------+ | arch | RUNNING | 10.106.137.64 (eth0) | fd42:2fcd:964b:eba8:216:3eff:fe8f:49ab (eth0) | PERSISTENT | 0 | +------+---------+----------------------+-----------------------------------------------+------------+-----------+
Теперь у нас есть LXD последней версии внутри LXD контейнера хоста и там внутри запущен ArchLinux. Помните, что LXD поставлен через snap технологию и использует канал edge, что подразумевает частое обновление новых версий, возможно несколько раз в день.
Здорово что пакеты snap можно нормально использовать внутри контейнера LXD. На производстве теперь можно поднять сотни различных контейнеров, связать сетью как нужно, настроить лимиты на ресурсы с помощью LXD и начать ставить софт прямиком от их апстрима через технологию snap.
Нельзя со 100% уверенностью сказать, что всё работает идеально. Некоторые вещи, благодаря которым всё и работает, появились в ядре относительно недавно - монтирование FUSE в непривилегированном режиме (unprivileged FUSE filesystem mounts) и работа профиля AppArmor в непривилегированном режиме (unprivileged AppArmor profile stacking and namespacing). Возможно есть шероховатости, которые нужно устранить, чтобы snap работал идентично snap, установленному непосредственно в хосте.
Если вы заметите расхождение в работе "snap внутри LXD" или "snap напрямую в хосте", то гляньте вывод dmesg на предмет строк DENIED, которые показывают что AppArmor запрещает что-то для данного snap.
Как правило, это симптом того, что есть баг в AppArmor самом или в том, как snapd генерирует профиль AppArmor при установке пакета. Если столкнётесь с проблемами, то можете отписать на канале #snappy irc.freenode.net или оформить баг launchpad.net/snappy/+filebug
Серия статей про LXD.
Серия статей про LXC.
Контейнеры против виртуализации.