当使用'–iptables = false'选项时,nginx的docker容器看不到客户端ip

我在Ubuntu 16.04上使用Docker 17.04.0-ce。

我在我的主机上运行了多个公开端口的容器,其中一些应该只能通过某些IP范围访问,而另一些容器(如监听端口80和443的nginx代理)应该可公开访问。

使用默认configuration, INPUT链的我的iptablesconfiguration被忽略,允许从任何地方访问具有绑定端口的所有容器。 所以我了解到,我必须为--iptables=false提供--iptables=false选项,这很好。

虽然我现在可以使用iptables控制对不同端口的访问,但是我的nginx容器不再能够看到连接客户端的ip地址,而只能获得docker0网桥的IP地址(在我的情况下为172.17.41.1 )。

有没有办法允许nginx容器看到连接客户端IP而不再失去对iptables的控制权?

附注:我不想把所有容器放在主机networking上( --net=host )。

这取决于您的IPTABLES设置。 听起来好像你在转发时伪装,像这样:

 iptables -t nat -A POSTROUTING --out-interface docker0 -j MASQUERADE 

如果你想让客户端看到原来的IP,你必须禁用伪装,并使用NAT和PREROUTING。 这里有很多的手册。

只要确保你的容器使用你的主机作为默认路由,否则你最终将无法回答,因为你的回应不是来自正确的IP。

要说更多,你需要发布你的iptablesconfiguration…

我能够看到连接客户端ip从我的容器使用 – --net=host

  1. 使用--iptables=false ,所以--iptables=false不会搞乱主机的iptablesconfiguration。
  2. 在Docker主机上启用ip转发: echo 1>/proc/sys/net/ipv4/ip_forward
  3. --net=host告诉Docker跳过将容器放置在单独的networking堆栈中。 本质上,这个select告诉Docker不要容器的容器联网! docker run -d -p 80:80 --net=host -name some-container your-image

https://docs.docker.com/v1.5/articles/networking/#the-world

–net = host – 告诉Docker跳过将容器放置在单独的networking堆栈中。 本质上,这个select告诉Docker不要容器的容器联网! 尽pipe容器进程仍然限于自己的文件系统和进程列表以及资源限制,但是一个快速的ip addr命令将向您显示,在networking方面,它们活在Docker主机主机的“外部”,并且完全访问其networking接口。 请注意,这不会让容器重新configuration主机networking堆栈 – 这将需要–privileged = true – 但它确实让容器进程像任何其他根进程一样打开低编号的端口。 它还允许容器访问D-bus等本地networking服务。 这可能导致容器中的进程能够执行意想不到的事情,如重新启动计算机。 您应谨慎使用此选项。

默认情况下,Docker使用用户级代理( docker-proxy )来公开端口。

尝试禁用它:

 --userland-proxy=false