为什么我在Docker桥接网络中将网关IP作为源地址?

我本来是在做一些Docker桥梁网络的组合,并且注意到,代替白名单的本地IP,请求总是从网关IP发送。

为了以最小的努力重现,我使用了两个Python容器来运行HTTP服务器和客户端:

docker run -it --rm python:alpine sh

在服务器端:

 python -m http.server 

在客户端:

 wget 172.17.0.3:8000 

预期的输出是请求来自容器IP:

 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 172.17.0.2 - - [time] "GET / HTTP/1.1" 200 - 

实际输出,请求来自桥接网关IP:

 Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 172.17.0.1 - - [time] "GET / HTTP/1.1" 200 - 

但是,当我在笔记本上运行相同的测试时,我得到了预期的行为(容器IP)。 这个问题似乎只发生在我的服务器上。

什么会导致这样的行为? 是某种sysctl或iptables的问题?

我找到了原因,这是一个古老的iptables-save条目。 很难注意到, iptables -nvL默认不显示NAT规则。

/etc/iptables/rules.v4删除它们之后,一切按预期工作。