Docker в
рабочих средах
Shipping Reliable Containers in Production (O'Reilly Media)
Практическое руководство по созданию, запуску и масштабированию надежных контейнеров в продакшене. Книга охватывает весь спектр работы с Docker — от базовых команд до оркестрации, сетевых настроек и безопасности.
Программа вечера
Смена парадигмы
Переход на Docker — это не просто смена инструмента упаковки, а пересмотр всей архитектуры развертывания.
На уровне инфраструктуры происходит четкое разделение ответственности между самим приложением, платформой оркестрации и движком контейнеризации.
Управление заданиями
Это основа — запуск, остановка, перезапуск процессов.
Обычно эту задачу выполняет операционная система или одна из систем инициализации Linux: systemd, System V init, runit, BSD rc и т. д.
# Запуск сервиса sudo systemctl start nginx # Остановка sudo systemctl stop nginx # Перезапуск (stop + start) sudo systemctl restart nginx # Перезагрузка конфигурации без остановки (graceful reload) sudo systemctl reload nginx # Включение автозапуска при загрузке sudo systemctl enable nginx # Отключение автозапуска sudo systemctl disable nginx # Проверка статуса systemctl status nginx # Просмотр логов journalctl -u nginx -f
Docker Engine унифицирует управление жизненным циклом контейнеров командами start/stop/kill.
# Запуск контейнера docker run -d --name myapp -p 8080:80 myimage:latest # Остановка (graceful shutdown: SIGTERM → wait → SIGKILL) docker stop myapp # Принудительная остановка (SIGKILL сразу) docker kill myapp # Перезапуск docker restart myapp # Пауза (freeze процессов через cgroups) docker pause myapp # Возобновление docker unpause myapp # Удаление контейнера docker rm myapp # Просмотр логов docker logs -f myapp # Выполнение команды внутри running-контейнера docker exec -it myapp bash
Ограничение ресурсов
Контроль потребления памяти, CPU и процессов.
В традиционной среде ресурсы ограничивали через утилиту ulimit.
# Посмотреть текущие лимиты ulimit -a # Ограничить количество открытых файловых дескрипторов (soft limit) ulimit -n 1024 # Ограничить максимальный размер RSS-памяти (в KB) ulimit -m 512000 # ~500 MB # Запуск приложения с этими лимитами ./myapp
Docker использует механизм ядра Linux cgroups v1/v2 под капотом для жёсткой изоляции ресурсов. Каждый контейнер получает свою «квоту».
# Ограничение CPU: 1.5 ядра (150% одного ядра) # Ограничение памяти: 512 MB # Swap: отключён (memory + swap = 512 MB) docker run -d \ --name myapp \ --cpus=1.5 \ --memory=512m \ --memory-swap=512m \ --pids-limit=100 \ myimage:latest # Относительные доли CPU (если несколько контейнеров конкурируют) docker run -d \ --name app-high-priority \ --cpu-shares=1024 \ myimage:high docker run -d \ --name app-low-priority \ --cpu-shares=512 \ myimage:low
Сети
- 1. Динамический проброс портов через переменные окружения.
- 2. Избегайте протоколов со случайными портами (например, FTP или RTSP). Вместо них используйте HTTP/3 или gRPC с фиксированными портами.
- 3. Используйте встроенный DNS-сервер Docker для связи между контейнерами вместо хардкода IP-адресов.
- 4. Выберите один вид сети для продакшена (обычно пользовательский Bridge или Overlay) и работайте только с ним.
Движок Docker предоставляет 5 основных типов сетей для изоляции и связи.
Это стандартный тип сети, который создается автоматически при установке Docker (интерфейс `docker0`). Позволяет контейнерам на одном хосте общаться между собой.
# Создание пользовательской bridge-сети docker network create --driver bridge my-bridge-net # Запуск контейнера в созданной сети с пробросом портов docker run -d --name web --network my-bridge-net -p 8080:80 nginx:latest # Подключение запущенного контейнера к сети docker network connect my-bridge-net my-existing-app
Контейнер не получает свой собственный сетевой стек. Он использует сеть хост-машины напрямую (порты открываются прямо на интерфейсах хоста).
# Запуск контейнера с сетевым стеком хоста
docker run -d --name web-host --network host nginx:latest
Создает распределенную виртуальную сеть между несколькими Docker-хостами. Применяется для связывания контейнеров в кластере (Docker Swarm).
# Создание overlay-сети для кластера Swarm
docker network create --driver overlay --attachable my-overlay-net
Позволяет назначать контейнерам реальные MAC-адреса, делая их видимыми в локальной физической сети как отдельные аппаратные устройства.
# Создание macvlan-сети, привязанной к физическому интерфейсу eth0
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 my-macvlan-net
У контейнера вообще нет сетевого интерфейса (кроме loopback-петли). Обеспечивает полную изоляцию от локальной сети и интернета.
# Запуск изолированного контейнера без внешней сети
docker run -d --name isolated-runner --network none alpine:latest
Конфигурация
Каждому приложению необходим доступ к своим настройкам для гибкой работы в различных окружениях без пересборки.
На нижнем уровне определяется, как должна быть настроена среда Linux вокруг приложения. В Docker для этого используется Dockerfile, который описывает сборку базового образа.
# Базовый образ Linux с установленным Node.js FROM node:18-alpine # Настройка рабочей директории в контейнере WORKDIR /app # Копирование исходного кода COPY . . # Установка зависимостей и сборка приложения RUN npm ci --only=production # Команда запуска процесса внутри контейнера CMD ["node", "index.js"]
По умолчанию в Docker для этого предназначены переменные среды (environment variables).
# Запуск контейнера с передачей переменных окружения через флаг -e docker run -d \ --name web-app \ -e PORT=8080 \ -e DB_HOST=db.local \ -e NODE_ENV=production \ -p 8080:8080 \ myapp:latest
Упаковка и поставка
Стандартизация процессов сборки приложения и его доставки до конечного окружения.
В традиционных системах пришлось бы создавать отдельные инструменты развертывания и надеяться, что их можно стандартизировать, чтобы применять для нескольких приложений (tar, scp, git clone).
# Архивирование исходного кода tar -czf app.tar.gz ./src package.json # Копирование на удаленный сервер scp app.tar.gz user@server:/var/www/myapp/ # Удаленная распаковка и перезапуск службы ssh user@server 'cd /var/www/myapp && tar -xzf app.tar.gz && npm ci && systemctl restart myapp'
Упаковка
Теперь это единый артефакт Docker image (OCI-образ), содержащий приложение и всё его системное окружение.
Поставка
Осуществляется через реестр (registry): публичный, облачный или частный. Реестры — Harbor, AWS ECR, GCR, Docker Hub.
# Сборка OCI-образа docker build -t myregistry.com/myapp:v1.0 . # Поставка образа в реестр (Harbor, Docker Hub и др.) docker push myregistry.com/myapp:v1.0
Журналирование
Журналирование — это систематическая запись событий, ошибок и состояния приложения в процессе его работы для последующего мониторинга, отладки и анализа.
До появления контейнеризации приложения были неразрывно связаны с операционной системой и сервером. Разработчикам приходилось вручную настраивать пути записи файлов логов. Инструменты: Syslog (rsyslog, syslog-ng), Logrotate, Grep, Awk, Sed, Tail.
# Поиск ошибок в лог-файле приложения вручную tail -f /var/log/myapp/app.log | grep --color=auto "ERROR" # Пример конфигурационного файла logrotate (/etc/logrotate.d/myapp) /var/log/myapp/*.log { daily rotate 7 compress delaycompress missingok notifempty }
Разработчику больше не нужно прописывать пути к файлам логов. Приложение внутри контейнера просто отправляет логи в стандартные потоки вывода (по умолчанию используется драйвер json-file (или local)):
# Просмотр логов контейнера в реальном времени docker logs -f my-web-app # Вывести последние 100 строк логов с метками времени docker logs --tail 100 -t my-web-app
Задача платформы — не просто собрать логи, а централизовать их. Собрать данные из сотен контейнеров с разных серверов в единую базу данных для быстрого анализа и визуализации.
Следят за логами контейнеров на нодах и пересылают их дальше.
Обеспечивают долгосрочное хранение логов, их индексацию и быстрый поиск по запросам.
Мониторинг
Мониторинг — это непрерывный процесс отслеживания работоспособности, производительности и состояния приложений и инфраструктуры.
В чистом Docker всё завязано на инструкцию HEALTHCHECK. Она пишется либо в Dockerfile (на этапе сборки образа), либо описывается in docker-compose.yml (на этапе запуска).
Вариант А: Через Dockerfile
FROM nginx:alpine # Проверяем раз в 30 секунд, доступна ли главная страница. # Если за 3 секунды ответа нет — это провал. HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD curl -f http://localhost/ || exit 1
Вариант Б: Через docker-compose.yml
version: '3.8' services: web-app: image: my-node-app:latest healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"] interval: 10s timeout: 5s retries: 3 start_period: 20s # Даем 20 секунд на запуск
Docker CLI:
• docker ps — показывает статус (healthy) или (unhealthy) прямо в списке контейнеров.
• docker inspect <id> — позволяет увидеть историю последних проверок и логи ошибок, из-за которых упал хелсчек.
В современных продакшн-средах (кластерах Kubernetes) локального хелсчека Docker недостаточно. Для полноценного наблюдения за системой мы используем специализированные компоненты:
Системы сбора и хранения временных рядов (показателей RAM, CPU, RPS и т.д.).
Графическая панель для отображения метрик и построения наглядных дашбордов.
Модуль, который отправляет алерты (в Slack, Telegram, PagerDuty), если показатели выходят за рамки нормы.
Планирование и оркестрация
Оркестрация контейнеров управляет жизненным циклом приложений в кластере: планирует запуск контейнеров на подходящих серверах (нодах), следит за их состоянием, перезапускает при сбоях и балансирует нагрузку.
Обнаружение сервисов
Обнаружение сервисов (Service Discovery) — это процесс автоматического определения сетевых адресов (IP и портов) динамически запускаемых контейнеров.
Все серверы имеют постоянные, жестко прописанные IP-адреса. Связи между ними настраиваются вручную в конфигурационных файлах приложений.
Сам чистый Docker (если не брать в расчет устаревший Swarm) не имеет полноценного динамического Service Discovery для больших систем. Это задача платформы.
Платформы автоматизировали этот процесс на 100%. Оркестратор сам следит за тем, где запущен контейнер, и обновляет сетевые маршруты.
Эволюция инфраструктуры
Docker & Docker Compose
MVP, небольшие проекты, пет-проекты, один-два веб-сервиса.
Docker Compose можно и нужно использовать в продакшене на начальном этапе. Это экономит месяцы работы.
Serverless-контейнеры
Проект вырос, пользователей больше, но команды DevOps-инженеров еще нет.
Промежуточный шаг в 2026 году, избавляющий от управления серверами. Вы отдаете контейнер в облако, оно само масштабирует его от 0 до максимума.
Оркестрация (Kubernetes)
Сложная микросервисная архитектура, высокие нагрузки, распределенные команды.
Полная автоматизация, отказоустойчивость, управление сотнями контейнеров. В 2026 году порог входа снизился благодаря готовым Managed Kubernetes решениям.