Ответ
Изоляция контейнеров Docker обеспечивается комбинацией низкоуровневых возможностей ядра Linux, которые ограничивают и виртуализируют представление процессов о системе.
Ключевые механизмы:
-
Linux Namespaces: Создают изолированное окружение для каждого контейнера.
- PID namespace: Изолирует дерево процессов. Процессы в контейнере видят только свои PID, начиная с 1.
- Network namespace: У контейнера свой сетевой стек (интерфейсы, таблицы маршрутизации, iptables правила).
- Mount namespace: Собственное дерево файловой системы.
- UTS namespace: Изолирует hostname и domainname.
- IPC namespace: Изолирует механизмы межпроцессного взаимодействия (очереди сообщений, shared memory).
- User namespace: Позволяет мапить UID/GID внутри контейнера на другие UID/GID на хосте (повышает безопасность).
-
Control Groups (cgroups): Ограничивают и учитывают использование ресурсов.
- Ограничивают потребление CPU, памяти, дискового I/O, сети.
- Пример:
docker run -m 512m --cpus="1.5"ограничивает контейнер 512 МБ RAM и 1.5 ядрами CPU.
-
Union File Systems (OverlayFS): Обеспечивают эффективное наслоение образов (read-only layers) и записи контейнера (read-write layer), экономя дисковое пространство.
-
Дополнительные механизмы безопасности: Seccomp (фильтрация системных вызовов), SELinux/AppArmor (мандатный контроль доступа).
Практическая проверка изоляции:
# Найти PID первого процесса в контейнере (на хосте)
CONTAINER_PID=$(docker inspect --format '{{.State.Pid}}' nginx-container)
# Посмотреть namespaces контейнера
sudo ls -la /proc/$CONTAINER_PID/ns/
# Проверить cgroup лимиты контейнера
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes
Важное замечание: Контейнеры разделяют ядро хостовой ОС, что отличает их от полной виртуализации (KVM). Для workloads, требующих повышенной изоляции (мультитенантные среды), мы используем дополнительные решения: gVisor (прослойка-рантайм на Go) или Kata Containers (легкие VM).