
Docker-контейнеры и образы: что происходит на самом деле
Разбираем без лишних упрощений, чем образ отличается от контейнера, какие ресурсы изолирует Linux и почему контейнер не заменяет виртуальную машину.
Содержание
Контейнер — не маленький сервер внутри сервера. Это обычный процесс или группа процессов Linux, для которых ядро создаёт отдельное представление файловой системы, сети, идентификаторов процессов и других ресурсов. Образ предоставляет начальный набор файлов, а параметры запуска задают окружение контейнера.
Чем образ отличается от контейнера
Образ — неизменяемый пакет файлов и настроек. Контейнер — запущенный экземпляр этого образа с процессами, сетевыми подключениями и отдельным записываемым слоем. Несколько контейнеров на Linux-хосте используют одно ядро, поэтому граница изоляции отличается от виртуальной машины и требует аккуратной настройки прав.
Из каких частей складывается работа Docker
| Часть | Что это | Что с ней происходит |
|---|---|---|
| Dockerfile | Текстовое описание сборки | Хранится рядом с кодом и проходит review |
| Образ | Неизменяемые слои и метаданные | Скачивается из registry или создаётся build |
| Контейнер | Процессы, настройки запуска и записываемый слой | Запускается, останавливается и удаляется |
| Volume | Отдельно управляемые постоянные данные | Может пережить удаление контейнера |
Команда docker run при необходимости скачивает образ, создаёт контейнер и запускает его основной процесс. Повторный docker run не «включает тот же Docker»: он создаёт новый контейнер. Для остановленного экземпляра используется docker start.
Как образ становится контейнером
Образ состоит из слоёв файловой системы и конфигурации: команды запуска, рабочего каталога, переменных окружения и других метаданных. Слои доступны контейнеру для чтения. Сверху Docker добавляет записываемый слой, куда попадают изменения, сделанные во время работы.
Это легко увидеть на временном примере:
docker run --name layer-demo alpine:3.22 sh -c 'echo runtime > /created.txt'
docker container diff layer-demo
docker rm layer-demo
Файл /created.txt появился только в конкретном контейнере. После docker rm его слой исчез. Сам образ alpine:3.22 не изменился, поэтому следующий контейнер начнёт с прежнего состояния.
Не используйте docker commit как основной способ разработки образов. Последовательность изменений в таком результате трудно проверить и воспроизвести. Описывайте её в Dockerfile и собирайте новый образ.
Что изолирует Linux
В основе контейнеров лежат механизмы ядра Linux. Пространство имён, или namespace, определяет, какие процессы, сетевые интерфейсы и точки подключения видит программа. Контрольная группа, или cgroup, считает потребление процессора и памяти и позволяет поставить предел. Capabilities делят полномочия системного пользователя root на отдельные разрешения: например, менять владельца файла или настраивать сеть.
Проверьте PID основного процесса:
docker run -d --name process-demo alpine:3.22 sleep 300
docker inspect --format '{{.State.Pid}}' process-demo
docker top process-demo
ps -ef | grep '[s]leep 300'
Процесс виден хосту, хотя внутри контейнера получает собственный номер. Это полезная модель для диагностики: контейнер не скрывает нагрузку от ядра и системных инструментов.
После проверки удалите пример:
docker rm -f process-demo
Чем контейнер отличается от виртуальной машины
Виртуальная машина эмулирует оборудование и запускает гостевое ядро. Контейнер использует ядро хоста. Поэтому контейнер обычно стартует быстрее и требует меньше служебных ресурсов, но зависит от совместимости с ядром и не даёт такой же границы изоляции.
Практические следствия:
- Linux-контейнер не содержит собственное Linux-ядро;
- обновление ядра выполняется на хосте;
- уязвимость ядра может затронуть границу контейнеров;
- Windows- и Linux-контейнеры требуют соответствующей среды выполнения;
- контейнеры и виртуальные машины часто используются вместе: VPS предоставляет VM, а приложения внутри неё запускаются контейнерами.
Основной процесс определяет жизнь контейнера
Контейнер работает, пока жив его основной процесс. Если веб-приложение завершилось с ошибкой, контейнер останавливается, даже если его файловая система цела. Не запускайте внутри одинокого контейнера полноценную имитацию сервера с десятком несвязанных служб без необходимости.
Состояние и код завершения доступны через inspect:
docker inspect --format 'status={{.State.Status}} exit={{.State.ExitCode}}' layer-demo
Удалённый ранее layer-demo нужно создать снова либо подставить имя существующего контейнера. Ошибка No such object означает отсутствие объекта, а не поломку Docker Engine.
Где должны жить данные
Записываемый слой удобен для временных файлов, но плох как единственное место базы данных, загрузок или конфигурации, которую нельзя потерять. Обновление приложения обычно означает создание нового контейнера из нового образа. Если данные остаются внутри старого экземпляра, безопасная замена становится невозможной.
Разделяйте:
- образ — код и неизменяемые runtime-зависимости;
- переменные и secrets — конфигурация запуска;
- volume или внешнее хранилище — постоянные данные;
- stdout/stderr или система журналирования — события приложения.
Где изоляцию легко ослабить
Особенно внимательно относитесь к параметрам:
--privileged;- mount корня хоста или чувствительных каталогов;
- доступ к
/var/run/docker.sock; --network host;- лишние capabilities;
- запуск приложения от root без необходимости.
Доступ к Docker socket фактически позволяет управлять daemon и получать полномочия уровня хоста. Нельзя считать такого пользователя или контейнер ограниченным только потому, что команда выполняется через Docker.
Практическая проверка понимания
Для любого сервиса ответьте на четыре вопроса: из какого образа он создаётся, какой процесс является основным, где находятся постоянные данные и какие ресурсы хоста ему открыты. Если хотя бы один ответ неизвестен, удаление или обновление контейнера пока нельзя считать безопасным.
Перед практикой подготовьте Ubuntu и обычного администратора, затем установите Engine по проверенной процедуре. Работа с ключами и переменными окружения отдельно разобрана в руководстве по секретам.
Источники
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Контейнер Docker — это облегчённая виртуальная машина?
Нет. Виртуальная машина запускает собственную гостевую операционную систему и ядро, а Linux-контейнер остаётся набором процессов на ядре хоста с изолированными представлениями ресурсов.
Сохранятся ли файлы после удаления контейнера?
Изменения в записываемом слое контейнера удаляются вместе с ним. Постоянные данные нужно заранее вынести в именованный volume, bind mount или внешнее хранилище.
Означает ли изоляция контейнера полную безопасность?
Нет. Контейнеры делят ядро хоста, а опасные capabilities, privileged-режим, доступ к Docker socket и лишние mounts существенно ослабляют границу изоляции.


