Первый вопрос любого собеса про 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.