docker和iptabes这一对“连体婴儿”总是会给我们带来一些麻烦。
如果你有使用过docker的经验你会发现docker在启动的同时会在iptables中添加DOCKER链路,
而当你的docker启动一个容器时会在DOCKER链路中添加DANT规则。
1.这一对“孪生兄弟”在我们使用时的确是会带来很多问题,例如有些勇气可嘉的朋友总是喜欢重启防火墙,那么这时就会出现DOCKER链路丢失的情况,
DOCKER链路丢失,docker容器所依赖的DNAT规则就消失了,那么你会发现你的docker容器从主机外部访问不到了。
解决方法:针对这个问题,你可以重启docker服务,这样iptables中的DOCKER链路就会重新建立,并在会将DNAT规则添加进去,这样就恢复了访问,
但是这样有一个弊端就是你的其他正在提供服务会停止,所以在生产中要慎重操作。(所以防火墙不要随意重启)
2.细心的你会发现在同一个docker0子网下,你在docker0网段的一个容器中去通过宿主机的ip访问另外一个docker0网段的另外一个容器,你会发现你访问不了,这时就有点疑惑了,
因为这时的防火墙INPUT链路没有放行,所以导致服务无法正常访问。
比如:在docker0网段 有一台172.17.0.2的mysql 还有一台172.17.0.3的mysql
那么你在172.17.0.2的 mysql容器是可以访问172.17.0.3的mysql容器的,但是你使用宿主机的ip+容器映射出来的端口 去访问,那么你会发现是访问失败的,
因为这时的docker0网段是没有在防火墙放行的。
下面列一下docker容器在不同场景下被访问时数据包在防火墙中的过程:
1.容器出外网: PREROUTING链路----->FORWORD链路------->OUTPUT链路---------->POSTROUTING链路
2.宿主机访问127.0.0.1: OUTPUT链路--------->POSTROUTING链路 ------->PREROUTING链路--------->INPUT链路----->容器
3.访问宿主机的默认网卡地址:OUTPUT链路--------->DOCKER链路------->POSTROUTING链路----->容器
4.宿主机之外的主机访问容器: PREROUTING链路---------->DOCKER链路----->FORWORD链路----------->DOCKER链路-------->POSTROUTING链路------->容器
5.宿主机访问容器: OUTOUT链路------>POSTROUTING链路------->容器
6.容器访问宿主机端口:PREROUNTING链路---->DOCKER链路------->INPUT链路--->容器