Магия сетей в Docker Compose: От изоляции до взаимодействия

Магия сетей в Docker Compose: От изоляции до взаимодействия

Docker Compose превращает управление многоконтейнерными приложениями из головной боли в элегантный танец. Но настоящая магия начинается, когда вы понимаете, как тонко настраивать сети между контейнерами. Это не просто соединение A с B — это создание целых экосистем, где сервисы общаются, изолируются и масштабируются по вашим правилам.

Сети по умолчанию: Что происходит под капотом?

Когда вы запускаете docker-compose up, Compose автоматически создаёт для вашего проекта одну сеть. Все сервисы из вашего файла docker-compose.yml подключаются к ней. Это удобно, но ограниченно. Каждый контейнер получает внутренний DNS-имя, равное имени сервиса, что позволяет обращаться к соседнему контейнеру просто по имени (например, db из контейнера app).

Важно: Имя сети по умолчанию формируется на основе имени папки проекта. Это может привести к конфликтам. Всегда явно задавайте имена сетей в продакшене.

Явное определение сетей: Полный контроль

Мощь Compose раскрывается в секции networks. Вы можете определить несколько сетей с разными характеристиками и подключать к ним сервисы выборочно.

Базовый пример с двумя сетями

version: '3.8'
services:
  frontend:
    image: nginx:alpine
    networks:
      - front-tier
      - back-tier

  backend:
    image: my-app:latest
    networks:
      - back-tier

  database:
    image: postgres:15
    networks:
      - back-tier
      - admin-tier

  adminer:
    image: adminer
    networks:
      - admin-tier

networks:
  front-tier:
    driver: bridge
  back-tier:
    driver: bridge
  admin-tier:
    driver: bridge

Здесь создаётся архитектура: фронтенд доступен извне и видит бэкенд; бэкенд и база данных общаются в закрытой сети; а инструмент администрирования (Adminer) изолирован в отдельной сети с доступом только к БД.

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

  • bridge (по умолчанию): Частные внутренние сети хоста. Идеально для коммуникации между контейнерами на одной машине.
  • host: Убирает сетевую изоляцию. Контейнер использует сетевой стек хоста. Максимальная производительность, но нулевая изоляция.
  • overlay: Позволяет контейнерам на разных Docker-хостах (в Swarm) общаться как в одной сети. Основа для кластеров.
  • macvlan: Назначает контейнеру реальный MAC-адрес, делая его видимым в физической сети как отдельное устройство.
  • none: Полное отключение сети.

Драйвер host не работает на Docker Desktop для Windows/macOS. Используйте его только на Linux-хостах.

Продвинутые настройки: IP-адреса, aliases и подключение внешних сетей

Вы можете фиксировать IP-адреса в подсети, что полезно для устаревших приложений:

networks:
  mynet:
    driver: bridge
    ipam:
      config:
        - subnet: \"172.28.0.0/16\"

services:
  app:
    networks:
      mynet:
        ipv4_address: 172.28.1.5

Aliases (псевдонимы) позволяют давать сервису дополнительные DNS-имена в сети. А подключение к существующим внешним сетям (external: true) — ключ к интеграции с контейнерами, созданными вне Compose.

Порты и безопасность: Что открывать миру?

Секция ports мапит порты контейнера на порты хоста. Но лучшая практика — открывать порты только для внутреннего взаимодействия, а наружу выводить через reverse proxy (nginx, Traefik).

services:
  app:
    build: .
    # Не публикуем порт наружу, только в сеть Compose
    expose:
      - \"3000\"
  nginx:
    image: nginx
    ports:
      - \"80:80\" # Только прокси доступен извне
    depends_on:
      - app

FAQ: Часто задаваемые вопросы

Как контейнеры находят друг друга по имени?

Docker Compose автоматически настраивает встроенный DNS-сервер. Каждый сервис доступен по своему имени (как в файле docker-compose.yml) и по псевдониму сети, если он задан.

Можно ли подключить контейнер к сети после создания?

Да, с помощью команд docker network connect и disconnect. Но в Compose это проще сделать через изменение конфигурации и перезапуск.

Как обеспечить безопасность сетей?

  1. Используйте отдельные сети для разных уровней приложения (frontend, backend, db).
  2. Минимизируйте использование ports, применяйте expose для внутренних портов.
  3. Рассмотрите возможность использования драйвера overlay с зашифрованным трафиком в Swarm.
  4. Никогда не используйте сеть host для контейнеров с данными или критичной логикой.

Почему контейнеры в одной сети не пингуются?

Проверьте: 1) Указаны ли оба сервиса в одной сети в конфиге? 2) Не блокирует ли межсетевой экран внутри контейнера соединения? 3) Запущены ли контейнеры? Используйте docker-compose exec service-name ping other-service для диагностики.

Как удалить неиспользуемые сети Compose?

Команда docker-compose down --remove-orphans удалит контейнеры и сети, созданные последним запуском up. Для полной очистки: docker network prune (будьте осторожны!).