Как docker0 bridge работает внутри хоста?

#networking #docker #bridge

#сеть #docker #мост

Вопрос:

Я пытаюсь понять, как работает мостовой интерфейс docker0.

  • Когда запускается демон docker, он создает мостовое устройство docker0;
  • При запуске контейнера он создает интерфейс vthn и привязывается к docker0

допустим, мы отправляем команду ping из контейнера на внешний хост

 [root@f505f022eb5b app]# ping 130.49.40.130
PING 130.49.40.130 (130.49.40.130) 56(84) bytes of data.
64 bytes from 130.49.40.130: icmp_seq=1 ttl=52 time=11.9 ms
  

итак, в настоящее время мой хост eth0 получает этот ответный запрос, но как этот пакет пересылается в контейнер? Есть несколько вопросов, которые нужно задать

  • eth0 и docker0 не соединены мостом, почему docker0 получает пакеты от eth0?
  • даже если docker0 получил пакеты, как он работает внутри, отправляя пакеты на vth0? поддерживает ли он некоторые карты внутри, чтобы он мог конвертировать пакеты между разными MAC-адресами?
  • как здесь связаны iptables?

Приветствия.

Комментарии:

1. woosley.github.io/2017/07/25/…

Ответ №1:

Docker не делает здесь ничего особенного волшебного, и ваш вопрос на самом деле не зависит от docker / связан с ним.

docker0 это просто сетевой мост. Как только этот мост будет создан (при запуске службы docker), вы можете предположить, что новая машина (в данном случае в форме VM / docker) присоединилась к вашей сети.

При пинге контейнера docker с хоста или наоборот вы в основном пингуете другую машину внутри своей сети.

Что касается docker, если вы не создали новый сетевой интерфейс (в чем я сомневаюсь, поскольку вы пингуете eth0 ), вы в основном пингуете сами.

Если вы запустите контейнер как:

docker run -i -t --rm -p 10.0.0.99:80:8080 ubuntu:16.04

Вы говорите docker создать правило NAT в iptables для пересылки любых пакетов, отправляемых 10.0.0.99:80 в ваш контейнер docker на порту 8080 .

Когда вы запускаете контейнер как:

docker run -i -t --rm -p --net=host ubuntu:16.04

Тогда вы говорите, что контейнер docker должен иметь тот же сетевой стек, что и хост, чтобы все пакеты, отправляемые на хост, также поступали в ваш контейнер docker через docker0 мост.

Комментарии:

1. да, мой вопрос на самом деле не в этом docker. Я все еще пытаюсь выяснить, что произошло, когда контейнер docker пингует внешний хост. На стороне контейнера, если пакет хочет выйти и вернуться обратно, как он проходит интерфейс хоста и преобразуется внутри контейнера docker?

Ответ №2:

Чтобы ответить на ваш вопрос, как контейнер выполняет пинг внешнего хоста, это также достигается с помощью NAT.

Если вы перечисляете свои правила Iptables / NAT с помощью: sudo iptables -t nat -L

Скорее всего, вы увидите что-то похожее на приведенное ниже (подсеть docker может отличаться)

 Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        anywhere
  

По сути, это означает, что NAT передает любые исходящие пакеты, исходящие из подсети docker. Таким образом, исходящие пакеты будут казаться исходящими с хост-компьютера docker. Когда возвращаются пакеты ping, таблица NAT будет использоваться для определения того, что хост docker действительно отправил запрос, и пакет пересылается на docker veth.