Компьютерные сети

Сети в Docker

Микросервис запущен, но как он найдёт базу данных? IP адреса меняются, контейнеры умирают и создаются заново. Нужна сеть, которая сама разберётся кто где - чтобы код не знал про IP, а просто говорил 'подключись к redis'.

  • **Docker Compose** - стандарт для локальной разработки. Поднял docker-compose up - все сервисы видят друг друга по именам
  • **Kubernetes** использует похожие концепции: overlay networks (CNI plugins), service discovery (CoreDNS), network policies
  • **Netflix** мигрировал на контейнеры и overlay networks - тысячи микросервисов находят друг друга без хардкода IP

Предварительные знания

  • NAT: One IP for Everyone
  • Subnets and Masks

Docker Networking: основы

**Docker Networking** - как контейнеры общаются друг с другом и внешним миром. Каждый контейнер получает свой network namespace - изолированный сетевой стек с собственными интерфейсами, routing table, iptables. Снаружи контейнер выглядит как отдельная машина.

**Network Namespace** - Linux kernel feature. Контейнер видит только свои интерфейсы, не хоста. `docker exec nginx ip addr` покажет другие интерфейсы чем `ip addr` на хосте. Изоляция на уровне ядра.

Когда использовать network mode 'host'?

Bridge Network

**Bridge Network** - виртуальный свитч внутри хоста. Контейнеры подключаются к docker0 bridge через veth pairs. Получают IP из приватной подсети (172.17.0.0/16). Между собой общаются напрямую, наружу - через NAT хоста.

**Port Publishing** (-p 8080:80) - iptables DNAT правило. Входящий трафик на хост:8080 перенаправляется на контейнер:80. `docker port nginx` покажет маппинг. Без -p контейнер недоступен снаружи.

Почему контейнер A на bridge может обратиться к B по IP, но не по имени?

Overlay Network

**Overlay Network** - виртуальная сеть поверх физической. Контейнеры на разных хостах получают IP из одной подсети и общаются напрямую. Под капотом - VXLAN туннели между хостами. Docker Swarm создаёт overlay автоматически.

**VXLAN (Virtual Extensible LAN)** - инкапсуляция L2 frame в UDP. VNI (VXLAN Network Identifier) = 24 бита = 16 миллионов изолированных сетей. Решает проблему VLAN limit (4096). Стандарт для cloud/container networking.

Какой overhead добавляет VXLAN к пакету?

Container DNS

**Container DNS** - embedded DNS server в Docker (127.0.0.11). Контейнеры резолвят имена друг друга через Docker daemon. На user-defined networks работает автоматически: имя контейнера = DNS имя. В Compose - имя сервиса.

**Service Discovery** - контейнеры находят друг друга по имени, не по IP. IP меняется при рестарте. Имя стабильно. В Docker Compose сервисы резолвятся по имени сервиса из docker-compose.yml.

Localhost (127.0.0.1) в контейнере указывает на хост

127.0.0.1 в контейнере - это сам контейнер, не хост

Контейнер имеет свой network namespace. Его localhost - он сам. Для обращения к хосту нужен host.docker.internal (Docker Desktop) или реальный IP хоста

Почему DNS лучше чем хардкодить IP адреса контейнеров?

Итоги

  • **Network drivers:** bridge (local, default), overlay (multi-host), host (no isolation), none (disabled)
  • **Bridge** = Linux bridge + veth pairs + NAT. Port publishing через iptables DNAT
  • **Overlay** = VXLAN туннели между хостами. Контейнеры на разных машинах в одной L2 сети
  • **DNS (127.0.0.11)** - service discovery по именам. User-defined networks only
  • **User-defined > default bridge:** DNS, изоляция, connect/disconnect на лету

Связанные темы

Container networking - применение классических концептов:

  • NAT — Bridge использует MASQUERADE и DNAT для port publishing
  • Subnets — Каждая Docker network - своя подсеть (172.17.0.0/16, 172.18.0.0/16...)
  • Kubernetes Networking — K8s строится поверх этих концепций + CNI plugins

Вопросы для размышления

  • Как бы вы отладили ситуацию, когда контейнер A не может подключиться к B?
  • Почему для production часто используют external networking (Calico, Cilium) вместо Docker overlay?
  • Как обеспечить network security между контейнерами? Как ограничить кто с кем может общаться?

Связанные уроки

  • os-19-containers
Сети в Docker

0

1

Войти