Урок по треку Docker и Kubernetes 7 мин

Образы, слои и контейнеры за 7 минут

Что такое образ и контейнер, слои и кеш, теги и digest, реестры, namespaces и cgroups под капотом.

Первый вопрос любого собеса про Docker: «чем контейнер отличается от виртуальной машины и что такое образ». Ответ «контейнер это лёгкая виртуалка» неверен, и интервьюер это знает.

Контейнер это процесс

Контейнер не эмулирует железо и не запускает своё ядро. Это обычный процесс Linux на общем ядре хоста, которому ядро показывает ограниченный мир:

  • namespaces изолируют то, что процесс видит: pid (свои PID, процесс думает, что он PID 1), net (свои интерфейсы и порты), mnt (своя файловая система), uts (своё имя хоста), ipc, user (свои UID), cgroup.
  • cgroups ограничивают, сколько процесс потребляет: память, CPU, число процессов, ввод-вывод.
  • capabilities, seccomp, AppArmor/SELinux урезают права.

Отсюда следствия: контейнер стартует за доли секунды, но ядро общее. Linux-контейнер не запустится на ядре Windows напрямую (Docker Desktop на macOS и Windows поднимает маленькую Linux-ВМ). Уязвимость ядра опасна для всех контейнеров хоста.

Виртуальная машина эмулирует железо через гипервизор и запускает своё ядро: изоляция сильнее, накладные расходы и время старта больше.

Образ это слои

Образ это упакованная файловая система плюс метаданные (команда запуска, переменные, порты). Он состоит из слоёв: каждый слой хранит изменения относительно предыдущего (добавленные, изменённые, удалённые файлы). Слои неизменяемы и адресуются хешем содержимого (sha256:...).

Когда запускается контейнер, поверх слоёв образа кладётся тонкий записываемый слой. Это copy-on-write: при изменении файла из нижнего слоя он копируется наверх. Драйвер хранения по умолчанию в Linux это overlay2 (OverlayFS).

Следствия:

  • Десять контейнеров из одного образа делят его слои на диске и в page cache.
  • Удаление файла в верхнем слое не уменьшает образ: файл остаётся в нижнем, сверху появляется отметка об удалении (whiteout).
  • Данные, записанные в контейнер, пропадут вместе с ним. Для данных нужны тома.
docker history nginx:1.27        # слои и команды, которые их создали
docker image inspect nginx:1.27  # метаданные, список слоёв
docker system df                 # сколько занимают образы, контейнеры, тома, кеш

Тег и digest

nginx:1.27-alpine это тег, изменяемый указатель. Завтра под тем же тегом может лежать другой образ с патчами. latest это просто тег по умолчанию, а не «последняя версия».

Digest (nginx@sha256:3f1c...) это хеш манифеста, он неизменяем. Для воспроизводимых деплоев образы закрепляют по digest или хотя бы по точному тегу версии.

Полное имя образа: registry.example.com:5000/team/api:1.4.2. Без адреса реестра подразумевается Docker Hub (docker.io/library/nginx).

Мультиархитектурные образы

Один тег может указывать на индекс манифестов с вариантами под linux/amd64, linux/arm64 и другие. Docker сам скачает нужный. Если образ собран только под amd64, на ARM-сервере или Mac с Apple Silicon он упадёт с exec format error или пойдёт через медленную эмуляцию. Сборка под несколько платформ: docker buildx build --platform linux/amd64,linux/arm64.

Реестры

Docker Hub, GitHub Container Registry, GitLab Registry, облачные реестры, Harbor у себя. Команды: docker login, docker tag, docker push, docker pull. У Docker Hub есть лимиты на анонимные скачивания, поэтому в CI и кластерах ставят зеркало или прокси-кеш.

Стандарт OCI

Формат образов и рантайма описан стандартами OCI (Open Container Initiative). Поэтому образ, собранный Docker, запускают containerd и CRI-O в Kubernetes, а собирать можно не только Docker: Buildah, Kaniko, BuildKit. Под Docker тоже работает containerd, а сам процесс создаёт низкоуровневый рантайм runc.

Жизненный цикл контейнера

created → running → paused / exited → удалён. docker run = create + start. Остановленный контейнер с его записываемым слоем остаётся на диске, пока его не удалят (docker rm, флаг --rm удаляет сразу после выхода).

Частые ошибки

  • Называть контейнер лёгкой виртуальной машиной.
  • Деплоить :latest и удивляться, что на двух серверах разный код.
  • Хранить данные внутри контейнера без тома.
  • Удалять файлы в отдельной инструкции Dockerfile и ждать уменьшения образа.
  • Собрать образ на Mac M-серии и отправить на amd64-сервер без --platform.

Что спросят на собесе

  • Чем контейнер отличается от ВМ, какие механизмы ядра лежат в основе.
  • Что такое слой образа и как работает copy-on-write.
  • Тег против digest, почему latest опасен.
  • Где хранятся данные контейнера и что с ними будет после удаления.
  • Что такое OCI и как связаны Docker, containerd и runc.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.