Как работает сеть в Docker-контейнере?

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

Ответ

Сеть в Docker обеспечивает изоляцию и связность контейнеров. Ядро Linux предоставляет пространства имён (network namespaces), которые Docker использует для создания виртуальных сетевых стеков для каждого контейнера.

Основные компоненты:

  • docker0: Виртуальный мостовой интерфейс по умолчанию, создаваемый демоном Docker.
  • veth (Virtual Ethernet Pair): Пара виртуальных интерфейсов, соединяющая сетевой namespace контейнера с мостом docker0. Один конец (vethXXX) находится в namespace хоста, другой (обычно eth0) — внутри контейнера.
  • iptables/nftables: Docker автоматически настраивает правила NAT для исходящего трафика контейнеров и проброса портов (-p).

Типы сетей Docker, которые я настраиваю:

  1. bridge (стандартная): Изолированная внутренняя сеть. Контейнеры получают IP из подсети моста и могут общаться друг с другом по этим адресам.
    docker network create my-bridge-network
    docker run -d --name app --network my-bridge-network nginx
  2. host: Контейнер использует сетевой стек хоста напрямую, минуя изоляцию namespace. Полезно для высокопроизводительных сетевых задач.
    docker run --network host nginx # Контейнер будет слушать порт 80 прямо на сетевом интерфейсе хоста.
  3. none: У контейнера нет сетевых интерфейсов (кроме loopback). Используется для полностью изолированных workloads.
  4. overlay: Для связи контейнеров, развернутых на разных хостах Docker Swarm или в оркестраторах. Создает распределенную виртуальную сеть поверх физической.

Практический пример проброса портов:

docker run -d -p 8080:80 --name web nginx

Эта команда:

  1. Создает правило iptables DNAT, перенаправляющее трафик с host_ip:8080 на container_ip:80.
  2. Создает правило MASQUERADE для обратного трафика от контейнера.

DNS в контейнерах: По умолчанию контейнер наследует DNS-конфигурацию хоста (через /etc/resolv.conf). В пользовательских сетях Docker предоставляет встроенный DNS-сервер, разрешающий имена контейнеров по их имени (например, ping app из другого контейнера в той же сети my-bridge-network).