Какие namespace в Linux используются Docker для изоляции?

«Какие namespace в Linux используются Docker для изоляции?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Docker (и другие контейнерные runtime) использует Linux namespaces для обеспечения изоляции. Это фундаментальный механизм, а не специфичная фича Docker. Основные namespace:

  1. PID (Process ID) namespace: Изолирует дерево процессов. Процессы внутри контейнера не видят процессы на хосте или в других контейнерах. PID 1 внутри контейнера — это обычно его entrypoint.
  2. Network namespace: У контейнера свой собственный сетевой стек: сетевые интерфейсы, таблицы маршрутизации, правила iptables/firewalld. Docker создаёт виртуальные интерфейсы (veth pairs) для связи этого namespace с хостом или другими контейнерами.
  3. Mount (mnt) namespace: Изолированное дерево файловых систем. Позволяет контейнеру иметь собственные точки монтирования и корневую файловую систему (rootfs), не влияя на хост.
  4. UTS (UNIX Timesharing System) namespace: Изолирует hostname и domainname. Контейнер может иметь свой собственный hostname, отличный от хостового.
  5. IPC (Inter-Process Communication) namespace: Изолирует ресурсы для межпроцессного взаимодействия, такие как сегменты разделяемой памяти или очереди сообщений POSIX.
  6. User namespace: Позволяет мапить UID/GID пользователя внутри контейнера на другой UID/GID на хосте. Это критически важный namespace для безопасности, так как процесс, работающий от root (UID 0) внутри контейнера, может быть отображён на непривилегированного пользователя на хосте.

Проверка namespace для процесса контейнера:

# Найти PID основного процесса контейнера
docker inspect --format '{{.State.Pid}}' <container_id>

# Посмотреть, в каких namespace он находится
ls -la /proc/<PID>/ns/

Именно комбинация этих namespaces и cgroups (для ограничения ресурсов) создаёт то, что мы называем "контейнером".