Глава 9

Docker в
рабочих средах

Книга
Docker: Up & Running

Shipping Reliable Containers in Production (O'Reilly Media)

Практическое руководство по созданию, запуску и масштабированию надежных контейнеров в продакшене. Книга охватывает весь спектр работы с Docker — от базовых команд до оркестрации, сетевых настроек и безопасности.

Программа вечера

Подготовка к развертыванию Пройдено
Docker в рабочих средах
Спикер: Помазков Антон
Docker в конвейере DevOps
Спикер: Никифоров Артём

Смена парадигмы

Переход на Docker — это не просто смена инструмента упаковки, а пересмотр всей архитектуры развертывания.

На уровне инфраструктуры происходит четкое разделение ответственности между самим приложением, платформой оркестрации и движком контейнеризации.

Приложение
Платформа
Kubernetes, Docker Swarm, Mesos
Обнаружение сервисов
Планирование
Мониторинг
Docker Engine
Журналирование
Поставка
Упаковка
Конфигурация
Сети
Ограничение ресурсов
Управление заданиями
Приложение
Обнаружение сервисов
Планирование
Мониторинг
Журналирование
Поставка
Упаковка
Конфигурация
Сети
Ограничение ресурсов
Управление заданиями

Управление заданиями

Это основа — запуск, остановка, перезапуск процессов.

Устаревший компонент

Обычно эту задачу выполняет операционная система или одна из систем инициализации Linux: systemd, System V init, runit, BSD rc и т. д.

systemd commands
# Запуск сервиса
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

Docker Engine унифицирует управление жизненным циклом контейнеров командами start/stop/kill.

docker commands
# Запуск контейнера
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 commands
# Посмотреть текущие лимиты
ulimit -a

# Ограничить количество открытых файловых дескрипторов (soft limit)
ulimit -n 1024

# Ограничить максимальный размер RSS-памяти (в KB)
ulimit -m 512000  # ~500 MB

# Запуск приложения с этими лимитами
./myapp
Docker Engine

Docker использует механизм ядра Linux cgroups v1/v2 под капотом для жёсткой изоляции ресурсов. Каждый контейнер получает свою «квоту».

docker run resource limits
# Ограничение 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 основных типов сетей для изоляции и связи.

Bridge (Мост)

Это стандартный тип сети, который создается автоматически при установке Docker (интерфейс `docker0`). Позволяет контейнерам на одном хосте общаться между собой.

bridge network commands
# Создание пользовательской 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
Host (Хост)

Контейнер не получает свой собственный сетевой стек. Он использует сеть хост-машины напрямую (порты открываются прямо на интерфейсах хоста).

host network commands
# Запуск контейнера с сетевым стеком хоста
docker run -d --name web-host --network host nginx:latest
Overlay (Наложение)

Создает распределенную виртуальную сеть между несколькими Docker-хостами. Применяется для связывания контейнеров в кластере (Docker Swarm).

overlay network commands
# Создание overlay-сети для кластера Swarm
docker network create --driver overlay --attachable my-overlay-net
Macvlan

Позволяет назначать контейнерам реальные MAC-адреса, делая их видимыми в локальной физической сети как отдельные аппаратные устройства.

macvlan network commands
# Создание macvlan-сети, привязанной к физическому интерфейсу eth0
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 my-macvlan-net
None (Сетевая изоляция)

У контейнера вообще нет сетевого интерфейса (кроме loopback-петли). Обеспечивает полную изоляцию от локальной сети и интернета.

none network commands
# Запуск изолированного контейнера без внешней сети
docker run -d --name isolated-runner --network none alpine:latest
Приложение
Обнаружение сервисов
Планирование
Мониторинг
Журналирование
Поставка
Упаковка
Конфигурация
Сети
Ограничение ресурсов
Управление заданиями

Конфигурация

Каждому приложению необходим доступ к своим настройкам для гибкой работы в различных окружениях без пересборки.

Нижний уровень

На нижнем уровне определяется, как должна быть настроена среда Linux вокруг приложения. В Docker для этого используется Dockerfile, который описывает сборку базового образа.

Dockerfile
# Базовый образ Linux с установленным Node.js
FROM node:18-alpine

# Настройка рабочей директории в контейнере
WORKDIR /app

# Копирование исходного кода
COPY . .

# Установка зависимостей и сборка приложения
RUN npm ci --only=production

# Команда запуска процесса внутри контейнера
CMD ["node", "index.js"]
Конфигурация приложения

По умолчанию в Docker для этого предназначены переменные среды (environment variables).

Bash
# Запуск контейнера с передачей переменных окружения через флаг -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).

Bash
# Архивирование исходного кода
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

Упаковка

Теперь это единый артефакт Docker image (OCI-образ), содержащий приложение и всё его системное окружение.

Поставка

Осуществляется через реестр (registry): публичный, облачный или частный. Реестры — Harbor, AWS ECR, GCR, Docker Hub.

Bash
# Сборка 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.

Bash
# Поиск ошибок в лог-файле приложения вручную
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
}
Docker

Разработчику больше не нужно прописывать пути к файлам логов. Приложение внутри контейнера просто отправляет логи в стандартные потоки вывода (по умолчанию используется драйвер json-file (или local)):

stdout Стандартный вывод для обычных логов
stderr Вывод для сообщений об ошибках
Bash
# Просмотр логов контейнера в реальном времени
docker logs -f my-web-app

# Вывести последние 100 строк логов с метками времени
docker logs --tail 100 -t my-web-app
Уровень Платформы

Задача платформы — не просто собрать логи, а централизовать их. Собрать данные из сотен контейнеров с разных серверов в единую базу данных для быстрого анализа и визуализации.

Сборщики

Следят за логами контейнеров на нодах и пересылают их дальше.

Хранение

Обеспечивают долгосрочное хранение логов, их индексацию и быстрый поиск по запросам.

Просмотр

Интерфейсы для удобной визуализации логов, построения дашбордов и поиска аномалий.

Приложение
Обнаружение сервисов
Планирование
Мониторинг
Журналирование
Поставка
Упаковка
Конфигурация
Сети
Ограничение ресурсов
Управление заданиями

Мониторинг

Мониторинг — это непрерывный процесс отслеживания работоспособности, производительности и состояния приложений и инфраструктуры.

Docker

В чистом Docker всё завязано на инструкцию HEALTHCHECK. Она пишется либо в Dockerfile (на этапе сборки образа), либо описывается in docker-compose.yml (на этапе запуска).

Вариант А: Через Dockerfile

Dockerfile
FROM nginx:alpine

# Проверяем раз в 30 секунд, доступна ли главная страница.
# Если за 3 секунды ответа нет — это провал.
HEALTHCHECK --interval=30s --timeout=3s --retries=3   CMD curl -f http://localhost/ || exit 1

Вариант Б: Через docker-compose.yml

YAML
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

Сам чистый Docker (если не брать в расчет устаревший Swarm) не имеет полноценного динамического Service Discovery для больших систем. Это задача платформы.

Оркестраторы

Платформы автоматизировали этот процесс на 100%. Оркестратор сам следит за тем, где запущен контейнер, и обновляет сетевые маршруты.

CoreDNS

Стандартное решение обнаружения сервисов по доменным именам внутри Kubernetes.

Consul

Внешний Service Discovery, Service Mesh и распределенное хранилище конфигураций.

etcd

Высокодоступное KV-хранилище, используемое Kubernetes для обнаружения сервисов.

Приложение
Обнаружение сервисов
Планирование
Мониторинг
Журналирование
Поставка
Упаковка
Конфигурация
Сети
Ограничение ресурсов
Управление заданиями

Эволюция инфраструктуры

1 CRAWL (Ползи)

Docker & Docker Compose

MVP, небольшие проекты, пет-проекты, один-два веб-сервиса.

!

Docker Compose можно и нужно использовать в продакшене на начальном этапе. Это экономит месяцы работы.

2 WALK (Иди)

Serverless-контейнеры

Проект вырос, пользователей больше, но команды DevOps-инженеров еще нет.

!

Промежуточный шаг в 2026 году, избавляющий от управления серверами. Вы отдаете контейнер в облако, оно само масштабирует его от 0 до максимума.

3 RUN (Беги)

Оркестрация (Kubernetes)

Сложная микросервисная архитектура, высокие нагрузки, распределенные команды.

!

Полная автоматизация, отказоустойчивость, управление сотнями контейнеров. В 2026 году порог входа снизился благодаря готовым Managed Kubernetes решениям.

Что далее

Подготовка к развертыванию Пройдено
Docker в рабочих средах Пройдено
Спикер: Помазков Антон
Docker в конвейере DevOps
Спикер: Никифоров Артём