Связи и тома: выстраиваем устойчивую инфраструктуру с Docker
Если вы уже понимаете, что Docker позволяет запускать приложение в контейнере, следующий шаг — научиться управлять этими контейнерами гибко: подключать сети, монтировать тома, управлять ресурсами.
В этой статье вы найдёте разбор теста среднего уровня. Мы пройдёмся по каждому вопросу, объясняя, зачем всё это нужно и как это применить в реальных задачах.
Эти навыки особенно ценны для тех, кто участвует в настройке среды разработки, работает в QA, DevOps или на позиции младшего системного администратора.
Вопрос 1
Вы запускаете контейнер с помощью команды docker run -it ubuntu --rm, но команда завершается с ошибкой, и контейнер не создаётся. В чём причина ошибки при запуске?
Обоснование:
В Docker CLI очень важно порядок аргументов:
- Все флаги (-it, --rm, -v, --name) должны располагаться перед именем образа.
- После имени образа (ubuntu) может идти только команда, которая выполняется внутри контейнера.
- В команде docker run -it ubuntu --rm — --rm указан после образа, что вызывает синтаксическую ошибку. Docker CLI интерпретирует это как команду внутри контейнера, а не как флаг Docker.
Выбранный ответ: Флаг --rm указан после имени образа, поэтому Docker CLI считает его невалидным
Вопрос 2
Почему объединение всех команд установки и удаления временных файлов в рамках одной инструкции RUN решает сразу три проблемы: рост размера образа, медленная сборка и наличие временных файлов внутри образа?
Правильный ответ: Все изменения выполняются в одном слое, временные файлы удаляются до фиксации слоя, что уменьшает размер и ускоряет сборку
- Docker создает отдельный слой для каждой инструкции в Dockerfile.
- Если вы выполняете apt-get update, apt-get install, а затем rm -rf /var/lib/apt/lists/* в разных RUN, то слои с временными файлами всё равно сохраняются в итоговом образе.
- Объединение этих шагов в один RUN (например, через &&) позволяет:
1. удалить мусор до фиксации слоя;
2. уменьшить итоговый размер образа;
3. ускорить сборку, избегая лишнего кэширования и хранения.
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
Выбранный ответ: Все изменения выполняются в одном слое, временные файлы удаляются до фиксации слоя, что уменьшает размер и ускоряет сборку
Вопрос 3
Веб-приложение не может подключиться к базе данных сразу после docker-compose up, хотя оба контейнера стартуют. В depends_on — не указан. В логах ошибки подключения. Почему возникает ошибка?
- В docker-compose директива depends_on не гарантирует, что сервис действительно "готов" (например, база данных завершила инициализацию).
- Она лишь определяет порядок запуска контейнеров, но не учитывает задержку готовности (например, инициализация PostgreSQL может занять 2-5 секунд).
- Поэтому веб-приложение может пытаться подключиться до того, как база начнёт слушать порт, что приводит к ошибке соединения.
1. скрипта ожидания (wait-for-it.sh, dockerize, bash loop);
2. использовать healthcheck + логику ожидания;
3. применять retry-логику на уровне кода.
Выбранный ответ: Веб-приложение пытается подключиться к базе данных еще до ее полной готовности
Вопрос 4
Какое сетевое решение в Docker удовлетворит сразу трём требованиям:
A. Масштабируемость без сложной перенастройки сети
B. Минимум изменений в настройках хоста
C. Высокая производительность внутри группы контейнеров
2. Позволяет контейнерам общаться по имени;
3. Идеальна для микросервисов на одном узле, не требует конфигурации хоста;
4. Изолирует от других контейнеров и внешней сети;
5. Позволяет масштабировать контейнеры с docker-compose up --scale.
1. host — лишает изоляции, портов, масштабирования.
2. overlay — нужен Swarm/Kubernetes, сложнее, для распределённых систем.
3. macvlan — сложен в настройке и требует прав на уровне хоста.
4. none — отключает сеть, не позволяет взаимодействие между контейнерами.
Выбранный ответ: Создать пользовательскую сеть типа bridge и подключить к ней все контейнеры приложения
Вопрос 5
Контейнер web-app перегружает CPU. Нужно:
1. Узнать, какие процессы создают нагрузку
2. Получить метрики CPU, памяти, сети
3. Скопировать файл /var/log/app.log на хост
Условие: без интерактивного входа (docker exec -it запрещён).
- docker top <container> — покажет список активных процессов в контейнере (аналог ps aux), без входа в него.
- docker stats — предоставляет живую статистику по CPU, памяти, сети.
- docker cp <container>:/path /host/path — позволяет извлечь файлы из контейнера без его остановки.
- Этот вариант соответствует всем условиям: без exec, без остановки, полный сбор информации.
Выбранный ответ: Использовать docker top для процессов, docker stats для метрик и docker cp для копирования файлов
Вопрос 6
Нужно развернуть локальный Docker Registry для тестового окружения, с выполнением условий:
- Публикация порта 5000 (-p 127.0.0.1:5000:5000) обеспечивает доступ только с локального хоста, т.е. исключает внешний доступ.
- Фаервол (например, iptables, ufw или настройки облачного хоста) дополнительно ограничивает внешние подключения.
- Это решение позволяет:
1. Запустить registry на нужном порту
2. Защитить от внешнего доступа
3. Контролировать загрузку и выгрузку образов
Остальные варианты либо не ограничивают внешние подключения, либо игнорируют порт 5000, либо предлагают небезопасные (--insecure-registry) или чрезмерно сложные решения (NAT).
Выбранный ответ: Ограничить внешний доступ к Registry через правила фаервола и настроить запуск контейнера с публикацией порта 5000
Вопрос 7
Контейнер backend-api, использующий данные из оперативной памяти, завис. Требуется:
1. Временно приостановить выполнение для дампа
2. Затем продолжить работу без потери данных
3. При критической ошибке — аварийно завершить
- docker pause — замораживает все процессы внутри контейнера (через cgroups, без выгрузки из памяти), что идеально для дампа состояния.
- docker unpause — возобновляет выполнение без потери текущего состояния.
- docker kill — позволяет немедленно завершить контейнер, в отличие от stop, который отправляет SIGTERM и ждёт.
- Это — единственная комбинация, которая покрывает все три условия корректно.
Остальные варианты либо не работают без остановки (stop теряет контекст), либо описывают избыточные подходы (wait, restart=always), либо менее гибкие (docker-compose pause лишь обёртка).
Выбранный ответ: Приостановить через docker pause, возобновить через docker unpause, завершить через docker kill
Вопрос 8
Как организовать резервное копирование данных из Docker-контейнера, использующего именованный том?
- Это — стандартная практика для резервного копирования содержимого volume, не затрагивая основной контейнер:
1. Создаётся временный контейнер с примонтированным именованным томом.
2. Внутри контейнера выполняется tar архивация содержимого тома.
3. С помощью docker cp архив копируется на хост.
docker run --rm -v my_volume:/data -v $(pwd):/backup busybox sh -c "tar czf /backup/backup.tar.gz -C /data ."
- docker save и load — работают с образами, не с томами.
- docker volume inspect — не предоставляет прямого доступа к данным.
- docker exec требует наличие работающего контейнера с подключённым томом, что не всегда надёжно.
- Удаление контейнера перед бэкапом — рискованно и ненужно.
Выбранный ответ: Создать контейнер с подключённым томом. Выполнить tar-архивацию содержимого тома внутри контейнера. Скопировать архив на хост
Вопрос 9
Как обеспечить регулярное резервное копирование данных из контейнера с MySQL с минимальной нагрузкой на базу и сохранением резервных копий вне контейнера?
- Именованный том позволяет разделять хранилище между контейнерами, не дублируя данные.
- Основной контейнер с MySQL продолжает работать с минимальной нагрузкой.
- Резервное копирование выполняется через отдельный контейнер, который имеет доступ к тому (например, с помощью --volumes-from или -v mydata:/var/lib/mysql), и может отдать данные во внешний NAS, S3 и т.п.
- Это безопасный и изолированный способ, не нарушающий работу основной базы.
- --volumes-from при старте базы — устаревший и менее гибкий способ.
- Копирование через основной контейнер — создаёт дополнительную нагрузку на саму БД.
- rsync с cron внутри контейнера — лишняя сложность и неуниверсально.
- bind mount временных директорий — не даёт регулярности и надёжности.
Выбранный ответ: Создать именованный Docker-том, подключить его к контейнеру и выполнять резервное копирование через отдельный контейнер с доступом к тому
Вопрос 10
Какой open-source инструмент подходит для автоматического сбора метрик и имеет удобный и полный интерфейс для анализа?
Prometheus — это основной open-source инструмент для сбора, хранения и анализа метрик, особенно в Kubernetes и Docker-средах.
1. сам опрашивает (pull-модель) источники данных;
2. поддерживает язык запросов PromQL для аналитики;
3. имеет встроенный веб-интерфейс, хотя часто его визуализация дополняется Grafana.
1. Telegraf — агент сбора метрик, но не хранит и не визуализирует их сам.
2. Logstash — работает с логами, а не метриками.
3. Grafana — интерфейс визуализации, но не собирает метрики сам.
4. Elasticsearch — полнотекстовый движок, не специализируется на метриках.
Вопрос 11
Один контейнер потребляет много ресурсов, периодически даёт ошибки записи в БД, но не перезапускается. Другие контейнеры и база данных работают нормально. В чём причина?
1. рост потребления CPU и памяти,
2. логические ошибки и задержки в работе,
3. отсутствие перезапуска контейнера,
всё это указывает на неправильную работу самого приложения, а именно — утечку памяти.
1. приложение начинает потреблять больше ресурсов,
2. страдает производительность,
3. возникают таймауты, ошибки и отказ при доступе к БД.
- Проблемы сети/версий БД/ограничений ресурсов затрагивали бы всю систему или инициировали бы перезапуск.
- Docker Daemon и конфликты версий менее вероятны — остальные контейнеры работают стабильно.
Выбранный ответ: Утечка памяти в приложении внутри контейнера приводит к увеличению потребления ресурсов, задержкам и ошибкам записи в базу данных
Вопрос 12
Какое основное преимущество даёт автоматизация тестирования в Docker-контейнере в Jenkins по сравнению с ручной настройкой окружения на каждой машине?
1. изолированное тестовое окружение, не мешающее основной системе и другим пайплайнам;
2. предсказуемость результатов тестов, независимо от конфигурации хоста;
3. воспроизводимость: контейнер можно запустить где угодно с тем же окружением.
В Jenkins это особенно важно — можно запускать любые тесты в стандартной, “чистой” среде без риска повлиять на основную систему Jenkins и другие сборки.
- уменьшает объём тестов — некорректно;
- устраняет необходимость проверки кода — неверно;
- упрощает агрегацию — частная функция, не основное преимущество;
- подтягивать образы — да, но это не основное отличие от ручной настройки.
Выбранный ответ: Docker позволяет создать изолированное окружение для тестов без влияния на основную систему Jenkins
После этого теста вы сможете не просто запускать контейнеры, а строить работающие инфраструктуры: соединять сервисы, работать с томами, следить за метриками.
Эти умения помогут вам стать надёжным членом команды и подготовят к более серьёзным задачам — таким как CI/CD или настройка отказоустойчивости в контейнерных средах.