
У нас есть настройка, в которой есть контейнер docker, которому нужно общаться с устройствами в VPN (openvpn) через ipv6. Это делается путем построения моста между сетями docker и интерфейсом tap0 на хосте.
Конечные устройства отправляют сообщение в контейнер docker и ожидают получить обратно сообщение с подтверждением. Однако они находятся в разных подсетях, причем контейнер и хост находятся в подсети, bbbb::/64
а устройства — в abcd::/64
(для наглядности). На ней находится шлюз, bbbb::abcd:2
который направляет трафик из одной подсети в другую, и у хоста docker есть конфигурация шлюза для этого.
Для ясности:
bbbb::4001 <--> bbbb::2105 <--> bbbb::abcd:2 <--> abcd::/64
Где bbbb::4001
— адрес контейнера; bbbb::2105
— адрес хоста; bbbb::abcd2
— адрес шлюзового устройства; abcd::/64
— подсеть, в которой находятся конечные устройства.
Используя tshark
хост и шлюз, мы наблюдаем следующее:
- Хост может напрямую взаимодействовать с конечными устройствами в подсети abcd (проверено с помощью traceroute, видны пакеты на хосте и шлюзе);
- Контейнер Docker может взаимодействовать со шлюзом (проверено с помощью ping, видны пакеты на хосте и шлюзе);
- контейнер докеране могнапрямую общаться с конечными устройствами в подсети abcd: мы могли видеть пакеты на хосте, так же, как мы видели их для связи хоста, но мы не видели, чтобы что-либо приходило на шлюз.
Мы пробовали изменить iptables
правила, чтобы разрешить пересылку пакетов (например, установить политику цепочки по умолчанию FORWARD
на ACCEPT
), но безрезультатно.
Мы не знаем, где искать эту проблему, потому что, похоже, пакеты из контейнера Docker, предназначенные для подсети, в которой он не находится, теряются.где-тона хосте, ИЛИ, возможно, отправляются не туда, но мы видим их на br0
интерфейсе хоста, они просто никогда не достигают шлюза. Когда контейнер docker пытается общаться с вещами в той же подсети, что и он, тогда это работает.
С чего начать поиски?
решение1
Проблема была связана с сетевым взаимодействием docker. У нас была настройка сети docker для использования сетевого моста для подключения к VPN. Этот мост был настроен (через /etc/network/interfaces.d/br0.cfg
) с адресом шлюза bbbb::2105
, а сеть docker была создана после интерфейса моста. Когда была создана сеть docker, адрес шлюза не был указан, и docker по умолчанию использовал bbbb::1
в качестве адреса шлюза , который он принудительно br0
использовал. Этот адрес совпадает с адресом VPN-сервера. В результате пакеты фактически не отбрасывались на хосте, а вместо этого перенаправлялись на tap
интерфейс VPN-сервера, а на VPN-сервере не были настроены таблицы маршрутизации таким образом, чтобы он знал, что делать с этими пакетами, поэтому они фактически помещались в черную дыру, как только достигали VPN-сервера.
Это стало ясно, когда мы использовали tshark для мониторинга tap
интерфейса VPN-сервера, а также tap
интерфейсов на шлюзах и машине хоста docker. Затем мы попытались пинговать конечное устройство изнутри контейнера docker и увидели пакеты на хосте docker и сервере VPN, но не на шлюзах. Если мы попытались сделать то же самое на хосте docker, мы увидели пакеты на хосте docker и шлюзах, но не на сервере VPN, тем самым продемонстрировав, что контейнеры docker были настроены на отправку трафика на сервер VPN, а не на сетевые интерфейсы хоста.
Проблема была устранена путем введения --gateway
опции в создание сети Docker.
Нерешенной частью этого являетсяпочемувсе внезапно начало вести себя таким образом, учитывая, что настройка работала с 2016 года и внезапно перестала работать в один прекрасный день в июне 2022 года.