Главная/Docker internals/Обзор

Раздел 17. Docker internals

Раздел закрывает вопросы, которые в остальном курсе принимались как данность. Что именно происходит между нажатием Enter и запуском процесса. Почему в цепочке четыре компонента, а не один. Как устроен OCI bundle. Где физически лежит файловая система container и как она собирается из слоёв. Как выглядят cgroup v2 изнутри и почему интерфейс изменился по сравнению с v1.

Материал не нужен для повседневной работы — до момента, когда что-то ломается нестандартно. Тогда он оказывается единственным способом понять происходящее. Раздел также готовит к переходу на другие инструменты: containerd, Podman, Kubernetes используют те же механизмы.

Цели обучения

После раздела учащийся сможет:

  • обратиться к Docker Engine API напрямую через Unix socket и разобрать ответ;
  • объяснить разделение ответственности между dockerd, containerd, shim и runc;
  • объяснить, зачем нужен shim и что произойдёт с containers при перезапуске daemon;
  • описать структуру OCI bundle и содержимое config.json;
  • показать все namespaces процесса и войти в выбранные через nsenter;
  • читать и изменять cgroup-параметры напрямую через файловую систему;
  • объяснить устройство OverlayFS: lowerdir, upperdir, workdir, merged;
  • найти файловую систему запущенного container на host и объяснить её структуру;
  • объяснить полный жизненный цикл процесса container от API-запроса до exit.

Предварительные знания

Материалы

  1. Engine API и Unix socket
    Архитектура daemon–client. Docker Engine API: версионирование, эндпоинты, формат ответов. Обращение через curl --unix-socket. Что делает CLI при каждой команде. Просмотр потока событий через API. Практическое применение: скрипты без установки Docker CLI. Последствия для безопасности.

  2. containerd, shim и runc
    Зачем цепочка из четырёх компонентов. Роль containerd как менеджера жизненного цикла. Shim: почему он существует, как удерживает stdio и exit code, что происходит при перезапуске dockerd. runc как исполнитель OCI Runtime Specification. OCI bundle: rootfs и config.json. Просмотр реальной конфигурации запущенного container.

  3. Namespaces: углублённо
    Все восемь типов namespaces с механизмом каждого. Системные вызовы clone, unshare, setns. Файлы в /proc/<pid>/ns/. Вход в namespace через nsenter с разными комбинациями флагов. Ручное создание изолированного окружения без Docker. User namespaces и отображение UID.

  4. Cgroups v2
    Отличия v2 от v1: единая иерархия, модель контроллеров. Структура /sys/fs/cgroup. Контроллеры memory, cpu, io, pids: файлы интерфейса и их семантика. Где находится cgroup конкретного container. Чтение статистики: memory.current, memory.max, memory.events, cpu.stat. Диагностика throttling и OOM.

  5. OverlayFS
    Механизм объединения слоёв: lowerdir, upperdir, workdir, merged. Ручная сборка overlay-монтирования командой mount. Copy-up при записи и его стоимость. Whiteout-файлы для удаления. Где на диске лежат слои образа и writable layer container. Различия при использовании containerd image store.

  6. Практические задания
    Лабораторные задания раздела с проверкой результата.

Рекомендуемый порядок чтения

Последовательный: 01 → 02 → 03 → 04 → 05 → exercises.

Уроки независимы друг от друга — можно читать выборочно по интересу. Урок 04 наиболее применим на практике: он напрямую нужен для диагностики проблем с ресурсами.

Практические задания

ЗаданиеТип
1Получить список containers через API с помощью curl --unix-socketобяз.
2Проследить дерево процессов от dockerd до приложения и объяснить роль каждого узлаобяз.
3Найти PID процесса container на host и показать его namespacesобяз.
4Найти cgroup запущенного container и прочитать его лимиты и текущее потреблениеобяз.
5Найти на host merged-каталог файловой системы container и увидеть в нём файлы приложенияобяз.
6Собрать overlay-монтирование вручную командой mount и проверить его поведениедоп.
7Создать изолированное окружение через unshare без участия Dockerдоп.
8Перезапустить dockerd и показать, что запущенные containers продолжают работать; объяснить механизмдоп.
9Изучить config.json OCI bundle запущенного container и найти в нём capabilities и seccomp-профиль
10Container показывает throttling CPU без видимой нагрузки. Найти причину через cgroup-статистикудиаг.

Полные формулировки — в exercises.md.

Критерии завершения раздела

Раздел пройден, когда учащийся может без подсказок:

  1. Описать полный путь от docker run до запущенного процесса с указанием всех компонентов.
  2. Объяснить, почему перезапуск dockerd не убивает работающие containers.
  3. Войти в mount namespace container и увидеть его файловую систему изнутри.
  4. Прочитать лимит и текущее потребление памяти container напрямую из /sys/fs/cgroup.
  5. Объяснить, что происходит при записи в файл, унаследованный из нижнего слоя.
  6. Найти на host каталог, содержащий изменённые файлы конкретного container.

Проверьте себя: Quiz 17.

Что дальше

Мы разобрали, как Docker работает изнутри. Следующий раздел отвечает на вопрос, который возникает после этого у каждого: а зачем тогда Kubernetes.

Навигация

Диаграмма: архитектура Docker

← Предыдущий раздел: CI/CD
Вернуться к главному оглавлению
Следующий раздел: Docker и Kubernetes →

Markdown на GitHub ↗