Когда мы говорим про контейнеры и виртуализацию на уровне ОС, ключевая технология, которая это обеспечивает - namespaces.
Это механизм ядра Linux, который изолирует процессы друг от друга и даёт им иллюзию, что они работают в отдельной системе.
По умолчанию все процессы видят одну и ту же систему: один список процессов, один hostname, одну файловую иерархию. Namespaces позволяют разрезать это пространство на отдельные «куски», и процесс внутри такого куска думает, что он единственный в системе.
Пример создания namespace:
Создать новый namespace можно утилитой unshare. Например, давайте изолируем hostname:
sudo unshare --uts /bin/bash
Теперь в новом шелле можно поменять имя хоста:
hostname container1
Если открыть вторую сессию и выполнить hostname, мы увидим старое имя. То есть разные процессы живут с разными настройками.
Пример изоляции процессов:
В обычной системе ps покажет все процессы, но если создать новый PID namespace:
sudo unshare --pid --fork --mount-proc /bin/bash
и выполнить там:
ps -ef
то видно будет только процессы внутри этого namespace. Для приложения это выглядит так, будто оно единственное в системе.
Namespaces бывают разных типов:
UTS - изоляция имени хоста и домена.
PID - изоляция процессов.
Mount - отдельная файловая иерархия.
Network - собственные сетевые интерфейсы и таблицы маршрутов.
IPC - изоляция межпроцессного взаимодействия.
User - собственные пользователи и идентификаторы.
Cgroup - изоляция и управление ресурсами (каждый процесс видит только свою часть иерархии cgroups).
Вывод:
На практике контейнеры в Docker или Podman используют комбинацию нескольких namespaces сразу. Поэтому внутри контейнера видно только свои процессы, сеть, файловую систему и т.д.
Главный плюс namespaces - это лёгкая изоляция без полноценной виртуальной машины. Но они не решают задачу безопасности полностью, поэтому для жёсткой изоляции применяют дополнительные механизмы, например cgroups и seccomp.
LinuxCamp | #utils #bymagadrovosex