← Назад к вопросам

В чём разница между bridge-network и host-network?

1.7 Middle🔥 121 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между bridge-network и host-network в Docker

Выбор сетевого драйвера в Docker критичен для производительности, безопасности и доступности контейнеров. Bridge и host — два основных подхода с принципиально разными характеристиками.

Bridge Network (мостовая сеть)

Bridge — это приватная виртуальная сеть, которая создаётся для контейнеров. Контейнеры в bridge сети не имеют прямого доступа к портам хоста.

# Создание bridge сети (создаётся по умолчанию как "bridge")
docker network create my-bridge --driver bridge

# Запуск контейнера в bridge сети
docker run -d --name web --network my-bridge -p 8000:8000 python-app

# Контейнеры в одной bridge сети видят друг друга по имени
docker run -d --name db --network my-bridge postgres

# Из контейнера web:
# Может достучаться до db как: psql -h db
# (DNS автоматически резолвит имя контейнера в IP)

Как это работает:

Хост (например, 192.168.1.100)
│
├─ Bridge Network (172.17.0.0/16)
│  │
│  ├─ Container 1 (172.17.0.2:8000)
│  │  Доступ: localhost:8000 → 172.17.0.2:8000 (через port mapping)
│  │
│  └─ Container 2 (172.17.0.3:5432)
│     Доступ: только для других контейнеров в bridge
│
├─ Localhost (127.0.0.1)
│  └─ Доступен только Container 1 через -p 8000:8000
│
└─ Другие сети
   └─ Контейнеры здесь не видят контейнеры в bridge

Характеристики Bridge:

  • Изоляция — контейнеры изолированы от хоста и друг от друга (разные сети)
  • DNS — контейнеры видят друг друга по имени (в одной сети)
  • Port mapping — требуется явно проксировать порты (-p 8000:8000)
  • Производительность — небольшой оверхед NAT трансляции
  • Сложность — нужно управлять портами, если много контейнеров
# docker-compose.yml с bridge (по умолчанию)
version: "3.9"
services:
  web:
    image: python-app
    ports:
      - "8000:8000"  # Host port : Container port
    depends_on:
      - db
  
  db:
    image: postgres
    ports:
      - "5432:5432"  # Также проксируется если нужен доступ с хоста

# Из контейнера web:
# - Может достучаться к db по: postgresql://db:5432
# - С хоста: postgresql://localhost:5432

Host Network

Host — это прямой доступ к сетевому стеку хоста. Контейнер делит сетевое пространство имён с хостом и имеет те же IP и порты.

# Запуск контейнера в host сети
docker run -d --name web --network host python-app

# Контейнер слушает прямо на портах хоста
# Если приложение слушает 0.0.0.0:8000, оно доступно на хосте:8000
# НЕ НУЖНО -p 8000:8000

# Из хоста:
# curl localhost:8000

# Контейнер видит все порты и IP адреса хоста
# netstat покажет процессы хоста

Как это работает:

Хост (192.168.1.100)
│
├─ eth0 (192.168.1.100)
├─ lo (127.0.0.1)
│
└─ Container 1 (разделяет сетевой стек)
   ├─ Видит 192.168.1.100
   ├─ Видит 127.0.0.1
   └─ Слушает порты напрямую
      (если слушает :8000, доступен на host:8000)

Характеристики Host:

  • Никакой изоляции — контейнер видит все сетевые интерфейсы хоста
  • Максимальная производительность — нет NAT оверхеда
  • Простота — порты видны сразу, не нужно -p
  • Уязвимость — контейнер может слушать любой порт хоста
  • Конфликты портов — два контейнера не могут слушать один порт
# docker-compose.yml с host сетью
version: "3.9"
services:
  web:
    image: python-app
    network_mode: "host"
    # НЕ используем ports: - контейнер сам слушает на портах хоста
  
  db:
    image: postgres
    network_mode: "host"
    # ПРОБЛЕМА: если оба контейнера пытаются слушать :5432
    # То второй упадёт с ошибкой "port already in use"

Сравнение

ПараметрBridgeHost
Изоляция сетиВысокаяНет
Видимость портовЧерез -pПрямая
ПроизводительностьХорошаяОтличная
DNS между контейнерамиРаботаетНе нужен
Конфликты портовМаловероятныВероятны
БезопасностьВышеНиже
Использование в продакшенеСтандартРедко
Сложность настройкиСредняяНизкая

Примеры использования

Bridge сеть (РЕКОМЕНДУЕТСЯ):

# Типичное приложение: FastAPI + PostgreSQL
docker network create app-network

# База данных
docker run -d \
  --name postgres \
  --network app-network \
  -e POSTGRES_PASSWORD=secret \
  postgres:15

# Приложение
docker run -d \
  --name api \
  --network app-network \
  -p 8000:8000 \
  -e DATABASE_URL=postgresql://postgres:secret@postgres:5432/mydb \
  myapp:latest

# С хоста: curl localhost:8000
# Из контейнера api: подключается к postgres через DNS имя
# settings.py в приложении
import os

# В контейнере
DATABASE_URL = os.getenv(
    "DATABASE_URL",
    "postgresql://postgres:secret@postgres:5432/mydb"
)
# "postgres" резолвится в IP контейнера postgres в той же bridge сети

Host сеть (редко, специфичные случаи):

# Высоконагруженный сервер, где каждая микросекунда важна
# Мониторинг системы (Prometheus, которому нужны метрики хоста)
# Специальные сетевые приложения

docker run -d \
  --name prometheus \
  --network host \
  -v /etc/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

# Prometheus слушает на :9090 хоста напрямую
# curl localhost:9090

Проблемы и решения

Проблема 1: "Cannot access container from host in bridge network"

# НЕПРАВИЛЬНО
docker run --name db -d postgres
# С хоста: psql -h postgres -U postgres  # ERROR: не разрешается

# ПРАВИЛЬНО
docker run --name db -d -p 5432:5432 postgres
# С хоста: psql -h localhost -U postgres  # OK

# ИЛИ используй имя контейнера только внутри других контейнеров
docker run --name web --link db web-app
# Из web контейнера: psql -h db  # OK

Проблема 2: "Port already in use" с host сетью

# В host сети два контейнера не могут слушать один порт
docker run --network host -d app1
docker run --network host -d app2
# ОШИБКА если оба пытаются слушать :8000

# РЕШЕНИЕ: разные порты
docker run --network host -p 8000:8000 -d app1  # port 8000
docker run --network host -p 8001:8000 -d app2  # port 8001

Проблема 3: Разные DNS имена в bridge и host

# Bridge сеть
docker run --name db --network my-net -d postgres
docker run --name app --network my-net -d myapp
# Из app: "db" резолвится в IP контейнера

# Host сеть
docker run --name db --network host -d postgres
docker run --name app --network host -d myapp
# Из app: "db" не имеет смысла (нет контейнерной сети)
# Нужно использовать localhost, 127.0.0.1 или IP хоста

Performance comparison

# Бенчмарк: Host vs Bridge
# Задача: 10000 запросов между контейнерами

import time
import asyncio
import httpx

async def benchmark():
    async with httpx.AsyncClient() as client:
        start = time.time()
        for _ in range(10000):
            response = await client.get("http://target:8000/ping")
        elapsed = time.time() - start
        return elapsed

# Bridge network: ~5.2 секунды
# Host network: ~4.8 секунды
# Разница: ~8% (из-за NAT трансляции)

# В реальных приложениях разница часто незначительна
# потому что остаток времени уходит на обработку логики

docker-compose с разными сетями

version: "3.9"
services:
  # Bridge сеть (по умолчанию)
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
  
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: secret
  
  # Специальный сервис на host сети (редко)
  monitor:
    image: prom/prometheus
    network_mode: "host"
    # ВАЖНО: этот контейнер разделяет сеть с хостом

# По умолчанию web и db в одной bridge сети
# и видят друг друга по имени

Итог

Bridge network — стандарт для большинства приложений. Обеспечивает изоляцию, автоматический DNS между контейнерами и легко управляется. Host network — нишевый выбор для специфичных случаев (максимальная производительность, мониторинг системы). В production используй bridge, если нет очень веских причин иначе. Bridge обеспечивает лучший баланс между производительностью, безопасностью и удобством управления.

В чём разница между bridge-network и host-network? | PrepBro