// devops interview / containers

Вопросы на собеседовании: Контейнеры

Образы, runtime-изоляция, ресурсы, хранение и безопасная сборка контейнеров. Здесь — топ-12 по частоте на реальных собесах: у первых вопросов открыт полный разбор, у остальных — устный эталон. Весь банк темы (12 вопросов) с разборами — в приложении.

Открыть тему в приложении каждый день бесплатно: 3 эталона и 3 проверки арбитром

junior: база, с которой начинают

Чем образ отличается от контейнера и куда попадают файлы, которые процесс создаёт после запуска?

как ответить Образ — неизменяемый шаблон: конфигурация и набор content-addressed слоёв файловой системы. Контейнер — запущенный или остановленный экземпляр образа с собственным runtime-состоянием и верхним writable layer. Файлы в этом слое живут только вместе с контейнером; важные данные выносят в volume или внешнее хранилище.

разбор

Несколько контейнеров могут разделять read-only слои одного образа, но у каждого будет свой верхний слой изменений. Запись существующего файла обычно реализуется механизмом copy-on-write: изменение видно контейнеру, не меняя исходный image layer.

Из этого следуют практические свойства:

  • новый контейнер из того же digest начинает с исходного состояния образа;
  • удаление контейнера удаляет его writable layer, если данные не смонтированы отдельно;
  • docker commit технически может сделать новый образ из изменений, но это плохо воспроизводимый процесс доставки;
  • конфигурацию и бинарники лучше получать из декларативной сборки, а данные — из volume, БД или object storage.

Остановленный контейнер всё ещё имеет своё состояние, поэтому повторный start отличается от создания нового экземпляра. В production рассчитываю именно на заменяемость: контейнер можно удалить и воссоздать без ручного ремонта внутри. Логи также не стоит хранить только в writable layer без ограничений и внешнего сбора: они растут вместе с локальным storage и исчезают при очистке.

чтобы прозвучать сильнее Объясни различие между OCI manifest, config и filesystem layers, а также почему tag не идентифицирует неизменяемое содержимое. Свяжи copy-on-write с ценой интенсивной записи в верхний слой.

devops-containers-001 · junior · high

Почему COPY . . перед установкой зависимостей делает сборку медленной и как порядок инструкций влияет на build cache?

как ответить Изменение слоя инвалидирует зависящие от него последующие шаги. Если сначала скопировать весь репозиторий, любое изменение исходника заставит заново устанавливать зависимости. Обычно отдельно копирую lockfile и manifest, ставлю зависимости, а затем добавляю часто меняющийся код; лишнее исключаю через .dockerignore.

разбор

Кэш проверяет инструкцию и входы, от которых она зависит. После cache miss downstream-слои должны пересобираться, даже если их текст не менялся. Поэтому Dockerfile упорядочивают от стабильных дорогих шагов к часто меняющимся дешёвым.

Типовая схема такова:

  1. Выбрать явный базовый образ.
  2. Скопировать только manifest и lockfile.
  3. Установить зафиксированные зависимости.
  4. Скопировать исходники и собрать приложение.

COPY . . также зависит от build context. Если туда попали .git, локальные артефакты, логи или node_modules, они замедляют передачу builder и могут менять checksum без пользы. .dockerignore уменьшает и время, и риск случайно отправить секрет.

Кэш — ускорение, а не доказательство воспроизводимости. Плавающий пакетный индекс внутри старого RUN может остаться закэшированным; --no-cache пересобирает шаги, но сам по себе не подтягивает свежий base image. Для контролируемого результата фиксирую зависимости и отдельно решаю, когда обновлять базу и external cache.

чтобы прозвучать сильнее Расскажи о cache mounts для package manager и внешнем cache в CI. Раздели reproducible build и fast build: хороший кэш не исправляет плавающие версии или недетерминированный генератор.

devops-containers-002 · junior · high

База записала данные в /var/lib/app, контейнер пересоздали — данные исчезли. Чем volume отличается от bind mount и writable layer и что выберешь для production?

как ответить Writable layer принадлежит конкретному контейнеру и исчезает вместе с ним. Volume управляется runtime и живёт независимо от контейнера; bind mount напрямую показывает процессу выбранный путь хоста. Для production выбираю storage по требованиям к durability, backup и размещению, а не считаю любой volume автоматической защитой данных.

полный разбор и проверка ответа арбитром — в приложении devops-containers-003 · junior · high

Контейнер сразу завершается или постоянно перезапускается. Какие данные соберёшь до изменения image и команды запуска?

docker ps -a --no-trunc
docker inspect app
docker logs --timestamps app
docker events --since 10m

как ответить Сохраняю exit code, signal/OOM state, фактические Entrypoint и Cmd, mounts, environment и события runtime. Затем читаю stdout/stderr и проверяю тот же immutable image с диагностическим entrypoint, если это безопасно. Restart policy временно останавливаю или ограничиваю, чтобы цикл не стирал контекст и не нагружал зависимости.

полный разбор и проверка ответа арбитром — в приложении devops-containers-005 · junior · high

Приложение в одном контейнере подключается к localhost:5432, но база работает в другом контейнере на том же хосте. Почему это не работает и как настроить связь без привязки к случайному IP?

как ответить У каждого контейнера свой network namespace, поэтому localhost указывает на него самого, а не на соседний контейнер и не на хост. Подключаю оба контейнера к общей пользовательской сети и обращаюсь к базе по стабильному service name и внутреннему порту. Публикация порта на хост нужна только тем клиентам, которые приходят извне этой сети.

полный разбор и проверка ответа арбитром — в приложении devops-containers-004 · junior · medium

middle: где отделяют уверенных

Почему shell-form ENTRYPOINT может ломать graceful shutdown контейнера и какие обязанности появляются у процесса с PID 1?

как ответить Shell-form запускает команду через shell, поэтому приложение может оказаться дочерним процессом и не получить stop signal. Предпочитаю exec-form, а wrapper завершает подготовку через exec "$@", чтобы приложение стало PID 1. Главный процесс должен корректно обрабатывать сигнал остановки и собирать потомков либо делегировать reaping минимальному init.

полный разбор и проверка ответа арбитром — в приложении devops-containers-006 · middle · high

Контейнер ограничили по CPU и памяти. Что произойдёт при превышении каждого ресурса и как отличить CPU throttling от cgroup OOM?

как ответить CPU quota обычно не убивает процесс, а throttling-ит cgroup, из-за чего растёт latency при низком среднем CPU хоста. Жёсткий memory limit может привести к reclaim и cgroup OOM, после чего один или несколько процессов будут убиты согласно политике. Сверяю runtime state, cgroup events и kernel log; один exit code не доказывает причину.

полный разбор и проверка ответа арбитром — в приложении devops-containers-007 · middle · medium

Production-образ огромный, долго отправляется в registry и содержит компилятор с исходниками. Как помогут build context, .dockerignore и multi-stage build?

как ответить Build context ограничивает файлы, доступные builder; .dockerignore не даёт отправлять ненужные каталоги и секреты. В multi-stage build компилятор и зависимости сборки остаются в builder stage, а в финальный stage копируется только runtime-артефакт. Это уменьшает размер и поверхность атаки, но не заменяет проверку содержимого и зависимостей результата.

полный разбор и проверка ответа арбитром — в приложении devops-containers-008 · middle · medium

Процесс имеет UID 0 внутри контейнера. Означает ли это root на хосте и чем здесь отличаются USER, user namespace remapping и rootless runtime?

как ответить UID 0 — root относительно user namespace процесса, но его полномочия дополнительно ограничены capabilities, namespaces и security policy. Без user namespace container UID 0 численно совпадает с host UID 0, хотя обычный контейнер не получает все host-права; с remapping он отображается в непривилегированный host UID. USER снижает права приложения внутри контейнера, а rootless runtime дополнительно запускает daemon и контейнеры без host root.

полный разбор и проверка ответа арбитром — в приложении devops-containers-009 · middle · medium

За счёт чего Linux-контейнер изолирует процессы и ресурсы и чем эта граница принципиально отличается от виртуальной машины?

как ответить mount, PID, network, UTS и IPC namespaces дают контейнеру отдельные представления файловой системы, PID, сети, hostname и IPC. User namespace может дополнительно отделить отображение UID/GID; без настройки runtime контейнер остаётся в initial user namespace. Cgroups учитывают и ограничивают ресурсы. Capabilities, seccomp и MAC-политики сужают разрешённые операции. Контейнеры при этом используют kernel хоста, тогда как VM обычно запускает отдельный guest kernel за гипервизором, поэтому модель изоляции и цена запуска различаются.

полный разбор и проверка ответа арбитром — в приложении devops-containers-010 · middle · medium

senior: глубина и продакшн

Один тег образа должен запускаться на amd64 и arm64, но часть узлов получает exec format error. Как устроен multi-platform OCI image и как сделаешь сборку и публикацию проверяемыми?

как ответить Multi-platform tag обычно указывает на OCI image index, где для каждой пары OS/architecture лежит отдельный manifest со своими config и layers. Runtime выбирает подходящий platform manifest. exec format error обычно означает, что внутри выбранного manifest оказался executable другой архитектуры либо stage собрали или скопировали для неверной target platform; отсутствие подходящего platform manifest должно обнаруживаться при выборе образа до запуска. Собираю платформы нативно либо контролируемой cross-build/QEMU-схемой, тестирую каждую и публикую общий index только после их успеха.

полный разбор и проверка ответа арбитром — в приложении devops-containers-011 · senior · low

В Dockerfile токен записали в файл в одном RUN, а следующим слоем удалили. Почему секрет всё равно считается скомпрометированным и как передавать build secrets правильно?

как ответить Удаление в новом слое скрывает путь в итоговом rootfs, но байты остаются в предыдущем immutable layer и могут попасть в cache или registry. ARG и ENV тоже не предназначены для секретов. Использую secret mount builder, который доступен только нужной инструкции и не сохраняется в слое, а затем проверяю, что команда не скопировала и не вывела значение.

полный разбор и проверка ответа арбитром — в приложении devops-containers-012 · senior · low

Соседние темы того же собеса