之前服务器都是直接配置LNMP环境,最近手头正好有一台须要从新配置,想尝试使用docker来配置多PHP版本环境。docker配置十分顺利,感谢有明大佬的小册,和DNMP项目。git
服务器配置好后,在几天的试用过程当中,发现以下两个问题:github
没法访问公网,没法获取真实IP,首先想到了防火墙的问题;关闭iptables,问题解决。但是iptables不能关呀,虽然说如今云服务器都有安全组过滤,但防火墙是最后一道防线,不能在云厂商的怀抱里裸奔啊……docker
查看了docker的网络部分,docker暴露容器端口是由docker-proxy来实现的,至于docker-proxy是什么略过不表。确定是iptables影响了docker-proxy致使数据包的源ip发生了改变,没法获取真实IP;没法访问公网,则是数据包找不到出口,被iptables拦截掉了,在内网转圈圈shell
假设个人公网IP为 117.25.140.71api
NGINX容器内网IP为 172.18.0.2安全
PHP容器内网IP为 172.18.0.3 172.19.0.3服务器
添加以下规则网络
-A PREROUTING -d 117.25.140.71 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.2:80
-A PREROUTING -d 117.25.140.71 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.18.0.2:443
复制代码
重启iptables 没法获取真实IP问题解决tcp
个人PHP容器访问公网,需求大抵是发送短信之类(无邮件发送),用的都是http协议,因此这里我没有选择所有转发,而是只转发目的端口为80和443的数据包spa
添加以下规则
-A POSTROUTING -s 172.19.0.3 -p tcp -m tcp --dport 80 -j SNAT --to 117.25.140.71
-A POSTROUTING -s 172.19.0.3 -p tcp -m tcp --dport 443 -j SNAT --to 117.25.140.71
复制代码
重启iptables发现仍然没法访问公网,是否是落下了什么。。 对了,既然http协议访问其余域名提供的api服务,怎么能少了DNS解析呢?添加DNS的支持(注意:DNS解析使用的是udp协议)
补充以下规则
-A POSTROUTING -s 172.19.0.3 -p udp -m udp --dport 53 -j SNAT --to 117.25.140.71
复制代码
重启iptables,大功告成!
最后总结几点: