如何在多宿主主机上进行配置,以便自定义网络上的 Docker 容器使用特定的外部 IP 进行出站流量?

如何在多宿主主机上进行配置,以便自定义网络上的 Docker 容器使用特定的外部 IP 进行出站流量?

我有一台具有两个公共 IP 的服务器(Ubuntu):第一个是动态的,第二个是静态的。

服务器上运行的软件连接到公共互联网端点,该端点位于用于将 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。但是,我想知道还有哪些其他可用选项以及可以推荐的选项是什么。

我愿意听取建议 - 也许有人已经这样做了!谢谢!

答案1

容器中生成的数据包是通过 Docker 主机接口转发的,而不是由主机生成的。src添加到默认路由的提示不起作用,因为数据包已经有源地址。我相信 iptables masq 仅根据出站接口选择源 IP 地址,所以我认为你只能在默认 MASQ 规则之前插入一条新规则(就像 serverfault 的答案)。

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

除非您熟悉 Dockers 对 iptables 的使用,否则完全关闭它可能会导致更多问题。

答案2

最简单的解决方案是使用--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 

Docker 将有POSTROUTING 规则。

然后将容器连接到这个创建的自定义网络。这些容器的所有流量都将通过指定的 IP 地址。

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

相关内容