不能理解docker的iptables规则

当使用docker时,我们从一个图像开始。 我用docker创build了一个容器。

docker run --name register -d -p 1180:5000 registry 

iptables规则可以通过运行iptables-save来列出:

 # Generated by iptables-save v1.4.21 on Mon Oct 16 14:01:03 2017 *nat :PREROUTING ACCEPT [129:14002] :INPUT ACCEPT [129:14002] :OUTPUT ACCEPT [25:1792] :POSTROUTING ACCEPT [25:1792] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 5000 -j MASQUERADE -A DOCKER -i docker0 -j RETURN -A DOCKER ! -i docker0 -p tcp -m tcp --dport 1180 -j DNAT --to-destination 172.17.0.2:5000 COMMIT # Completed on Mon Oct 16 14:01:03 2017 # Generated by iptables-save v1.4.21 on Mon Oct 16 14:01:03 2017 *filter :INPUT ACCEPT [2721358:1990060388] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [2726902:1992988803] :DOCKER - [0:0] :DOCKER-ISOLATION - [0:0] -A FORWARD -j DOCKER-ISOLATION -A FORWARD -o docker0 -j DOCKER -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i docker0 ! -o docker0 -j ACCEPT -A FORWARD -i docker0 -o docker0 -j ACCEPT -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 5000 -j ACCEPT -A DOCKER-ISOLATION -j RETURN COMMIT # Completed on Mon Oct 16 14:01:03 2017 

我不明白这个规则。

 -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 5000 -j MASQUERADE 

最好的猜测是,当iptables POSTROUTING表默认为拒绝任何不符合规则的数据包时,这个规则就是修复一个边界情况,这允许容器通过映射端口从容器到自身的连接。 在正常的操作中,规则不起作用。

我认为这是添加MASQ规则的拉取请求(#7003) ,但没有关于为什么添加的文档。 提交被标记为“为pkg / iptables创buildtesting” 。 这项工作通常围绕着发行具有默认DENY表的发行版修复Docker。

问题#12632中有一个build议,除非用户态端口映射代理closures,否则不会触及规则。

这在“将容器端口绑定到主机 ”

默认情况下,Docker容器可以连接到外部世界,但外部世界无法连接到容器。 由于Docker服务器启动时主机上的iptables伪装规则,每个传出连接似乎都来自主机自己的一个IP地址:

 $ sudo iptables -t nat -L -n ... Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 ... 

Docker服务器创build一个伪装规则,允许容器连接到外部世界的IP地址。

你可以在这个线程中看到当这些规则没有生成时会发生什么。 (他们需要恢复 )

您可以在“ 搭build自己的桥梁 ”中学习相同的选项。