Какие технологии используются при контейнеризации в Docker?

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

Ответ

Docker для изоляции и управления контейнерами использует низкоуровневые возможности ядра Linux:

  1. Namespaces (Пространства имён): Обеспечивают изоляцию. Каждый контейнер получает свои собственные изолированные экземпляры.

    • PID namespace: Изолирует дерево процессов.
    • Network namespace: Изолирует сетевые интерфейсы, таблицы маршрутизации, порты.
    • Mount namespace: Изолирует точки монтирования файловой системы.
    • IPC namespace: Изолирует межпроцессное взаимодействие (очереди сообщений, сегменты разделяемой памяти).
    • UTS namespace: Изолирует hostname и domain name.
    • User namespace: Изолирует UID/GID, позволяет отображать root внутри контейнера в непривилегированного пользователя на хосте.
  2. Control Groups (cgroups): Ограничивают и отслеживают использование ресурсов.

    • cpu, cpuacct: Ограничивают долю CPU и ведут учёт его использования.
    • memory: Ограничивают использование оперативной памяти и подкачки.
    • blkio: Контролируют операции ввода-вывода на блочных устройствах.
    • pids: Ограничивают количество процессов.
  3. Union File Systems (OverlayFS): Создают слоистые образы. Каждая инструкция в Dockerfile (FROM, RUN, COPY) создаёт новый слой. OverlayFS объединяет их в единое представление для контейнера, что обеспечивает эффективность хранения и быстроту развёртывания.

  4. Container Runtime (runc): Это легковесная утилита, которая непосредственно запускает контейнер, используя перечисленные выше технологии. Docker Engine (или containerd) вызывает runc для создания контейнера.

Пример проверки namespaces для запущенного контейнера:

# На хосте найти PID процесса в контейнере
ps aux | grep <процесс_в_контейнере>

# Посмотреть, в каких namespaces работает процесс
ls -la /proc/<PID>/ns/
# Вывод: cgroup ipc mnt net pid user uts
# Каждая ссылка ведёт на уникальный идентификатор namespace.