Какие технологии лежат в основе работы Docker-контейнеров?

Ответ

Docker использует несколько ключевых технологий ядра Linux для обеспечения изоляции, управления ресурсами и эффективного хранения данных контейнеров:

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

    • PID (Process ID): Изоляция процессов.
    • NET (Network): Изоляция сетевых интерфейсов, IP-адресов, портов.
    • MNT (Mount): Изоляция файловой системы.
    • UTS (Unix Time-sharing System): Изоляция hostname и доменного имени.
    • IPC (Interprocess Communication): Изоляция межпроцессного взаимодействия.
    • USER (User ID): Изоляция пользовательских ID.
  2. Cgroups (Control Groups): Позволяют ограничивать, учитывать и изолировать использование ресурсов (CPU, память, дисковый I/O, сетевой I/O) для групп процессов. Это гарантирует, что один контейнер не сможет монополизировать все ресурсы хоста.

  3. Union File Systems (Объединяющие файловые системы): Такие как OverlayFS или AUFS, позволяют создавать слоистые файловые системы. Образы Docker состоят из множества слоев, каждый из которых представляет собой изменение относительно предыдущего. Это обеспечивает:

    • Эффективность хранения: Общие слои используются несколькими контейнерами.
    • Иммутабельность образов: Базовые слои образа доступны только для чтения.
    • CoW (Copy-on-Write): Изменения в контейнере записываются в новый, записываемый слой, не затрагивая базовый образ.
  4. Container Runtime (runc и containerd):

    • runc: Низкоуровневая утилита, реализующая спецификацию OCI (Open Container Initiative) для запуска контейнеров. Она непосредственно взаимодействует с Namespaces и Cgroups для создания и запуска изолированных процессов.
    • containerd: Высокоуровневый демон, который управляет жизненным циклом контейнеров (создание, запуск, остановка, удаление), управляет образами и хранилищем. Docker Engine использует containerd для выполнения этих задач.

Пример использования unshare для изоляции:

# Запуск bash в новом PID и Mount namespace
sudo unshare --pid --mount --fork bash

# Внутри нового bash: виден только текущий процесс
ps aux

# Попытка смонтировать что-либо не повлияет на хост-систему
mkdir /tmp/test_mnt
sudo mount -t tmpfs tmpfs /tmp/test_mnt
ls /tmp/test_mnt

Docker Engine объединяет эти компоненты, предоставляя удобный API и CLI для управления контейнерами, образами, сетями и томами, абстрагируя пользователя от низкоуровневых деталей.