Статья 3 из 10, в которой речь пойдёт о продвинутых возможностях использования LXC: обмен хоста с гостем, вложенность, сетевой raw доступ.
Так как контейнеры обитают на файловой системе хоста, то передать данные можно разными способами.
Первое очевидное решение - перейти в /var/lib/lxc/имя-контейнера/rootfs/
Но иногда этого не достаточно, так как в контейнере могут использоваться и монтироваться файловые системы типа tmpfs. В таких случаях можно применить трюк:
sudo ls -lh /proc/$(sudo lxc-info -n p1 -p -H)/root/run/
Вам отобразят содержимое /run контейнера p1.
Из хоста брать данные у контейнера здорово, но что если нужно из контейнера получать доступ и писать данные в хост?
Допустим, что на хостовой машине есть папка /var/cache/lxc и мы хотим поделиться ею с контейнером p1. Добавим в файл /var/lib/lxc/p1/fstab строку
/var/cache/lxc var/cache/lxc none bind,create=dir
Строка означает, что /var/cache/lxc из хоста монтируется (bind-mount, файловый тип none и опция bind) в контейнере как /var/cache/lxc (отсутствие лидирующего / делает путь относительно корня контейнера) и создать любые отсутствующие каталоги в контейнере (create=dir). После рестарта p1 в его /var/cache/lxc можно увидеть тоже самое что и в хосте. Если нужно дать контейнеру доступ на чтение, то просто добавить к параметрам монтирования флаг ro и всё.
Одна из крутых вещей в LXC, хотя не нужная большинству, это поддержка вложенности. То есть вы можете запустить LXC внутри LXC без дополнительных затрат (overhead).
По умолчанию, вложенность заблокирована в Ubuntu. Так как в контейнере нужно разрешить монтирование cgroupfs, которая позволит улизнуть от любых ограничений cgroup, применяемых к данному контейнеру. То есть если вы недоверяете контейнерам, то лучше не использовать вложенность.
Для примера, включим возможность вложенности для контейнера p1. Для этого правим конфигурационный файл /var/lib/lxc/p1/config и добавляем:
lxc.aa_profile = lxc-container-default-with-nesting
После рестарта p1 нужно установить в нём lxc. Очень рекомендуется установить версию lxc такую же как и в хосте, но это не является обязательным.
Внутри контейнера командуем sudo lxc-create -t ubuntu -n p1
. Учитывая что до этого связывали кэш lxc /var/cache/lxc, всё должно произойти очень быстро. Внутри контейнера можно запустить вложенный контейнер как обычно.
Если на хостовой машине запустить команду sudo lxc-ls --fancy --nesting
, то можно наблюдать вложенность контейнеров.
NAME STATE IPV4 IPV6 AUTOSTART ------------------------------------------------------ p1 RUNNING 10.0.3.82, 10.0.4.1 - NO \_ p1 RUNNING 10.0.4.7 - NO p2 RUNNING 10.0.3.128 - NO
Нет лимитов на вложенность, но трудно будет кому-то объяснить зачем вы создали контейнер на 10ом уровне
В предыдущей статье LXC 1.0: Второй контейнер упоминалось про прокидывание устройств из хоста внутрь контейнера. Но на примере другого контейнера можно показать работу с сырым сетевым доступом. Данный контейнер создан Стефаном с целью иметь под рукой стандартного клиента для имитации работы в удалённой сети по VPN в изолированной среде, не затрагивая сеть хоста.
Стефан на своём ноутбуке-хосте поднял OpenVPN и получил tap0 (raw ethernet tap device).
Контейнер использует в своём конфиге следующие сетевые настройки:
lxc.network.type = phys
lxc.network.hwaddr = 00:16:3e:c6:0e:04
lxc.network.flags = up
lxc.network.link = tap0
lxc.network.name = eth0
Для тестов, Стефан запускает OpenVPN на своём хосте-ноутбуке и запускает контейнер, который тут же крадёт tap0 и использует его как eth0. Через DHCP контейнер получит IP и будет вести себя как будто он - удалённая физическая машина. Указан MAC адрес для удобства, чтобы не получать каждый раз случайный MAC.
Предыдущая статья LXC 1.0: Второй контейнер.
Следующая статья LXC 1.0: Более углублённое использование контейнера.
Дополнительные материалы:
Серия статей LXC 1.0. от Стефана Грабера.
LXC и Vagrant. 13 причин использовать Ubuntu Server. Часть 3.
Вход в систему Unity Greeter может аутентифицировать в системе, находящейся в LXC контейнере.