Контейнерная и гипервизорная виртуализация сильно упростили создание тестовых стендов и уже трудно представить как мы обходились без этого раньше. Расстраивает, что из-за высокой популярности инструментов коллеги начинают переусложняют вещи, которые можно было бы сделать проще. Если процессу нужно ограничить доступ к файловой системе, то вполне можно обойтись
chroot(8)
, если нужно изолировать сетевой стек или сделать ограничение по доступу к ресурсам системы, то обойтись
unshare(1)
. Это не намного сложнее, чем использовать тот же
docker
или
podman
, но нужно один раз разобраться в том, из чего построены контейнеры.
Базовых механизмов всего четыре:
- namespaces (пространства имён) используются для группировки объектов ядра в различные наборы, к которым могут обращаться определенные деревья процессов. Звучит немного сложно, поэтому сразу пример - пространства имен PID ограничивают представление списка процессов процессами в пространстве имен. Всего есть несколько видов пространства имен, см. ниже.
- capability используются для более тонкой настройки полномочий для процесса. Если вы использовали опцию
-cap-add
для
docker
, то это оно.
- cgroups это механизм установки ограничений на доступ процесса к ресурсам системы (память, процессор).
- setrlimit - ещё один механизм для ограничения доступа к ресурсам системы наряду с cgroups. Он старее, чем cgroups, но может делать то, что cgroups не позволяют.
Пространства имён бывают следующими:
-
mount namespace
- монтирование и размонтирование ФС не будет иметь никакого эффекта на ФС самой системы.
-
UTS namespace
- установка имени машины (hostname) или доменного имени не будет иметь никакого эффекта для основной ОС.
-
IPC namespace
- процесс будет иметь независимые от основной ОС объекты IPC: очереди сообщений, семафоры и разделяемую память.
-
network namespace
- процесс сможет иметь независимые от основной ОС стеки протоколов IPv4 и IPv6, таблицы маршрутизации и др.
-
PID namespace
- процесс будет иметь отдельное представление дерева процессов.
-
user namespace
- процесс с таким пространством имён будет иметь отдельный набор UID, GID. Например суперпользователь в этом пространстве имён не будет иметь ничего общего с суперпользователем из основной ОС.
Чтобы понять лучше эти механизмы можно воспользоваться двумя утилитами:
unshare
и
nsenter
. Первая позволить из командной строки создавать пространства имен для отдельных процессов, а вторая подключаться к уже созданным пространствам имён.
Когда прийдёт понимание этих механизмов, то при необходимости использования контейнерной виртуализации вы сами себя будете спрашивать: "- Мне действительно нужно использовать docker с его абстракциями в тысячи строк кода или можно обойтись более простыми средствами?".
Прекрасной иллюстрацией к сказанному будет статья, в которой автор описывает тестирование сетевого сервера
lldpd
с использованием pytest и сетевых пространств имён -
https://vincent.bernat.ch/en/blog/2016-testing-pytest-linux-namespaces.