Маршрутизация из контейнеров докеров с использованием другого физического сетевого интерфейса и шлюза по умолчанию

Исходная информация

У меня есть сервер с двумя сетевыми интерфейсами, на котором работает Docker. Докер, как и некоторые инструменты виртуализации, создает интерфейс моста Linux под названием docker0 . Этот интерфейс настроен по умолчанию с IP- 172.17.42.1 и все контейнеры Docker взаимодействуют с этим интерфейсом в качестве своего шлюза и назначаются IP-адресам в том же диапазоне /16 . Насколько я понимаю, весь сетевой трафик в / из контейнеров проходит через NAT, поэтому исходящий он поступает из 172.17.42.1 , а входящий отправляется на 172.17.42.1 .

Моя настройка выглядит так:

  +------------+ / | | | +-------------+ Gateway 1 +------- | | 10.1.1.1 | / +------+-------+ +------------+ | | eth0 | / | 10.1.1.2 | | | | | | DOCKER HOST | | | | | Internet | docker0 | | | (bridge) | | | 172.17.42.1 | | | | | | eth1 | | | 192.168.1.2 | \ +------+-------+ +------------+ | | | | \ +-------------+ Gateway 2 +------- | 192.168.1.1| | +------------+ 

Проблема

Я хочу маршрутизировать весь трафик из / в любые контейнеры Docker из второго интерфейса eth1 192.168.1.2 к шлюзу по умолчанию 192.168.1.1 , тогда как весь трафик с / на хост-машину выходит из интерфейса eth0 10.1.1.2 к Шлюз по умолчанию 10.1.1.1 . Я пробовал разные вещи до сих пор безрезультатно, но одна вещь, которая, по моему мнению, ближе всего подходит, – это использовать iproute2 следующим образом:

 # Create a new routing table just for docker echo "1 docker" >> /etc/iproute2/rt_tables # Add a rule stating any traffic from the docker0 bridge interface should use # the newly added docker routing table ip rule add from 172.17.42.1 table docker # Add a route to the newly added docker routing table that dictates all traffic # go out the 192.168.1.2 interface on eth1 ip route add default via 192.168.1.2 dev eth1 table docker # Flush the route cache ip route flush cache # Restart the Docker daemon so it uses the correct network settings # Note, I do this as I found Docker containers often won't be able # to connect out if any changes to the network are made while it's # running /etc/init.d/docker restart 

Когда я поднимаю контейнер, я не могу его отбросить, выполнив это. Я не уверен, что интерфейсы моста обрабатываются так же, как и физические интерфейсы для такого рода маршрутизации, и просто хотят проверить работоспособность, а также любые советы о том, как я мог бы выполнить эту, казалось бы, простую задачу.

3 Solutions collect form web for “Маршрутизация из контейнеров докеров с использованием другого физического сетевого интерфейса и шлюза по умолчанию”

Мы с другом столкнулись с этой точной проблемой, когда мы хотели, чтобы поддержка докеров поддерживала несколько сетевых интерфейсов, обслуживающих запросы. Мы специально работали с сервисом AWS EC2, где мы также добавляли / настраивали / воспитывали дополнительные интерфейсы. В этом проекте есть больше, чем нужно, поэтому я попытаюсь включить только то, что вам нужно здесь.

Во-первых, мы создали отдельную таблицу маршрутов для eth1 :

 ip route add default via 192.168.1.2 dev eth1 table 1001 

Затем мы настроили таблицу mangle, чтобы установить некоторые метки соединений, входящие в eth1 :

 iptables -t mangle -A PREROUTING -i eth1 -j MARK --set-xmark 0x1001/0xffffffff iptables -t mangle -A PREROUTING -i eth1 -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff 

Наконец, мы добавляем это правило для всех fwmark s для использования новой таблицы, которую мы создали.

 ip rule add from all fwmark 0x1001 lookup 1001 

В приведенной ниже команде iptables будет восстановлена ​​метка соединения, а затем разрешено правилу маршрутизации использовать правильную таблицу маршрутизации.

 iptables -w -t mangle -A PREROUTING -i docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff 

Я считаю, что это все, что нужно от нашего более сложного примера, где (как я уже сказал) наш проект включал / настраивал / воспитывал интерфейс eth1 во время загрузки.

Теперь этот пример не остановит соединения от eth0 от запросов на обслуживание до docker0 но я считаю, что вы могли бы добавить правило маршрутизации, чтобы предотвратить это.

Маскарад не из 172.17.42.1, а скорее

  -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE 

Это означает, что это правило не будет работать правильно.

 ip rule add from 172.17.42.1 table docker 

Попробуйте вместо этого

 ip rule add from 172.17.0.0/16 table docker 

Возможно, вам придется больше посмотреть на настройку iptables. Docker маскирует весь трафик, исходящий из подсети контейнера, скажем, 172.17.0.0/16, до 0.0.0.0. Если вы запустите iptables -L -n -t nat , вы можете увидеть цепочку POSTROUTING под nat-таблицей, которая делает это –

 Цепочка POSTROUTING (политика ACCEPT)
 Целевой целевой источник opt opt
 MASQUERADE all - 172.17.0.0/16 0.0.0.0/0

Теперь вы можете удалить это правило и заменить его правилом, которое маскирует весь трафик, происходящий из подсети контейнеров, на IP-192.168.1.2 второго интерфейса, поскольку это то, что вы хотите. Правило удаления будет, если предположить, что это первое правило в цепочке POSTROUTING –

 Iptables -t nat -D ПОСТРОЕНИЕ 1

Затем вы добавляете это настраиваемое правило –

 Iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT -to-source 192.168.1.2
  • Конфигурация сетевого шлюза не DHCP XP
  • Пакеты, не проходящие через шлюз Linux
  • Как отправить пакеты ответов в первоначальный сетевой адаптер в Windows 2008?
  • Предотвратить использование Windows Server 2012 с использованием DHCP-шлюза по умолчанию?
  • Multi Gateway и резервная routing на маршрутизаторе cisco
  • настройка шлюза по умолчанию на маршрутизаторе
  • Маршрутизация из контейнеров-dockerов с использованием другого физического сетевого interfaceа и шлюза по умолчанию
  • Как я могу контролировать интерless-трафик в своей локальной сети?
  • Предотвращать / дросселировать LAN-клиентов с использованием controllerа домена в качестве шлюза
  • VLAN и routing
  • Маршрутизация по связанным VLAN