Взаимодействие Docker с iptables

🐳 Введение

Docker использует iptables для управления сетевыми соединениями контейнеров. При запуске Docker автоматически создает свои правила в iptables, обеспечивая маршрутизацию, NAT и межконтейнерное взаимодействие. Это позволяет контейнерам обмениваться данными и взаимодействовать с внешней сетью.

🐳 Как Docker создает сети?

Docker использует три основных сетевых режима:

  1. bridge (по умолчанию) – стандартная сеть, создаваемая через docker0, с NAT.
  2. host – контейнер использует сетевой стек хоста, без iptables.
  3. none – контейнер без сети.

При использовании bridge-сети (docker0):

  • Создается виртуальный интерфейс docker0.
  • В iptables добавляются правила, разрешающие маршрутизацию трафика между контейнерами и внешней сетью.
  • Docker применяет SNAT/MASQUERADE для выхода контейнеров в интернет.

🐳 Какие правила Docker добавляет в iptables?

Docker автоматически добавляет правила в несколько цепочек iptables:

  1. Форвардинг контейнеров (CHAIN: FORWARD)

    iptables -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    iptables -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
    iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT
    
    • Разрешает входящий и исходящий трафик для контейнеров.
    • Позволяет контейнерам взаимодействовать друг с другом.
  2. NAT (CHAIN: POSTROUTING)

    iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    
    • Подменяет исходящий IP контейнеров на IP хоста (MASQUERADE).
    • Контейнеры могут выходить в интернет.
  3. Проброс портов контейнеров (CHAIN: DOCKER)

    iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
    
    • Перенаправляет входящий трафик с хост:8080 на контейнер:80.
  4. Изоляция контейнеров (CHAIN: DOCKER-ISOLATION-STAGE-1)

    iptables -A DOCKER-ISOLATION-STAGE-1 -i br-123abc -o br-456def -j DROP
    
    • Запрещает контейнерам из разных сетей взаимодействовать.

🐳 Что произойдет, если вручную изменить правила iptables?

1. Если удалить правила Docker

Если очистить iptables (iptables -F), контейнеры потеряют доступ к сети.
Для восстановления нужно перезапустить Docker, чтобы он пересоздал правила:

systemctl restart docker

2. Если отключить iptables в Docker

Добавив в /etc/docker/daemon.json:

{
  "iptables": false
}

после перезапуска Docker перестанет управлять iptables, но контейнеры потеряют доступ к сети.
Придется вручную добавлять правила NAT и FORWARD.

3. Если добавить кастомные правила

Дополнительные правила можно добавить через цепочку DOCKER-USER, чтобы Docker их не удалял:

iptables -I DOCKER-USER -s 192.168.1.0/24 -j ACCEPT
iptables -I DOCKER-USER -s 0.0.0.0/0 -j DROP

Эти правила сохранятся даже после перезапуска контейнеров.

🐳 Как правильно управлять iptables при работе с Docker?

  1. Используйте DOCKER-USER, если хотите кастомные правила.
  2. Не отключайте iptables в Docker без необходимости.
  3. Если вручную изменили iptables и контейнеры потеряли доступ, перезапустите Docker.
  4. Чтобы сохранить правила без Docker:
    iptables-save | grep -v 'DOCKER' > /etc/iptables/rules.v4
    
  5. Чтобы iptables загружались при старте:
    systemctl enable netfilter-persistent
    

🐳 Заключение

Docker тесно интегрируется с iptables для управления сетевыми подключениями. Понимание, как он добавляет правила, помогает избежать сетевых проблем при настройке. При необходимости кастомных правил используйте цепочку DOCKER-USER, чтобы Docker их не перезаписывал.