В чем разница между сетевыми драйверами bridge и host в Docker?

«В чем разница между сетевыми драйверами bridge и host в Docker?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Bridge (bridge) — драйвер сети по умолчанию. Docker создает виртуальный сетевой мост docker0, и каждый контейнер получает виртуальный сетевой интерфейс (veth), подключенный к этому мосту. Контейнеры в одной bridge-сети могут общаться друг с другом по внутренним IP-адресам, но изолированы от внешнего мира и других сетей. Для доступа извне необходимо явно пробросить порты (-p или --publish).

Host (host) — контейнер использует сетевой стек хоста напрямую, без какой-либо изоляции. Контейнер «видит» все сетевые интерфейсы хоста и слушает порты напрямую на них. Проброс портов не требуется и не работает.

Сравнение:

Критерий Bridge (по умолчанию) Host
Изоляция Высокая. У каждого контейнера свой сетевой namespace. Отсутствует. Контейнер делит сетевой namespace с хостом.
Производительность Небольшие накладные расходы из-за NAT/маршрутизации через мост. Максимальная, так как сетевой трафик идет напрямую, минуя виртуализацию.
Безопасность Лучше. Порт контейнера не открыт на хосте, если не проброшен. Меньше. Любой порт, открытый в контейнере, сразу виден на хосте.
Порты Требуется проброс: -p 8080:80. Проброс не нужен. Контейнер, слушающий порт 80, будет доступен на host_ip:80.
Типичный use-case Микросервисные приложения, изолированные среды, большинство стандартных сценариев. Высокопроизводительные нагрузки (например, nginx для балансировки), когда нужен прямой доступ к сетевым интерфейсам (например, для Pcap).

Примеры команд:

# Запуск контейнера в bridge-сети (явное указание порта)
docker run -d --name web-app -p 8080:80 nginx:alpine
# Контейнер будет доступен по http://localhost:8080

# Запуск контейнера в host-сети
docker run -d --name nginx-host --network host nginx:alpine
# Nginx теперь слушает порт 80 непосредственно на сетевых интерфейсах хоста.
# Команда `-p` будет проигнорирована.

В своей практике я использую bridge для 95% задач, так как это обеспечивает хорошую изоляцию и предсказуемость. host сеть применяю осознанно для специфичных задач, например, для контейнеров-сборщиков метрик (Prometheus node-exporter), которым нужен прямой доступ к сетевым интерфейсам хоста для снятия показаний.