2

У меня есть сервер (Ubuntu) с двумя общедоступными IP-адресами: первый динамический, а второй статический.

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

Сервер настроен таким образом, что статический IP-адрес находится в петлевом интерфейсе и настроен на

$ sudo vim /etc/network/interfaces.d/eip.cfg

auto lo:1
iface lo:1 inet static
    address <static_ip>/32

post-up ip route replace default via <dynamic_ip> src <static_ip>

После перезагрузки сети можно увидеть статический IP-адрес примерно так:

$ curl ipinfo.io/ip
<static_ip>

Следовательно, все работает хорошо, и можно свернуть другую конечную точку. Все хорошо.

ПРОБЛЕМА

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

Я уже тестировал использование --network=host и это хорошо работает, потому что это помещает контейнер в сеть хоста (где он работает).

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

Я понимаю, что Docker использует MASQUERADE и что можно отключить его и настроить iptables вручную в качестве опции. Тем не менее, мне интересно, какие другие варианты доступны и какой вариант можно было бы рекомендовать.

Я открыт для предложений - возможно, кто-то уже сделал это! Спасибо!

2 ответа2

0

Пакеты, сгенерированные в контейнере, пересылаются через интерфейс хостов Docker, а не генерируются хостом. Подсказка src добавленная к маршруту по умолчанию, не вступает в силу, поскольку пакеты уже имеют адрес источника. Я считаю, что iptables masq выбирает только исходный IP-адрес на основе исходящего интерфейса, поэтому я думаю, что вы застряли при вставке нового правила перед правилом MASQ по умолчанию (например, ответом serverfault).

iptables -t nat -I POSTROUTING -p all -s <docker_network>/24 \ 
  -j SNAT --to-source <static_ip>

Если вы не знакомы с тем, как докеры используют iptables, полное его отключение может вызвать больше проблем.

0

Самое простое решение - использовать параметр команды --outgoing-ip с командами docker run . В этом примере представлен контейнер с исходящим IPv4-адресом. Для IPv6 используйте --outgoing-ip6 .

Альтернативный метод - определить это в определении вашей сети и добавить некоторые правила iptables , у вас будет что-то вроде этого:

# docker network create <NETWORK NAME> --subnet=192.168.10.0/24 \ --gateway=192.168.10.1

# iptables -t nat -I POSTROUTING -s \ 192.168.10.0/24 -j SNAT --to-source OUTGOING_IP 

Докер будет иметь правила POSTROUTING.

Затем подключите ваши контейнеры к этой пользовательской сети, созданной. Весь трафик для этих контейнеров будет проходить через указанный IP-адрес.

# docker network connect <NETWORK-NAME> <CONTAINER>

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .