iptables && docker网络模式

251 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

现象

在公司部署某新的重构项目时按照原有部署文档部署时,我们将 mysql,engine等容器的端口使用bridge模式映射到宿主机上。

docker run --name mysql --restart always -p 3306:3306 --log-opt max-size=500m
-v $PWD/mysql/datadir:/var/lib/mysql      
-v $PWD/mysql/logs:/log 
-e MYSQL_ROOT_PASSWORD=XXXXXX
-e MYSQL_DATABASE=ctu
-e MYSQL_USER=ctu 
-e MYSQL_PASSWORD=XXXXXX           
-d xxx.xxx.top/basic/mysql:5.7.22-dx  
--character-set-server=utf8mb4 
--collation-server=utf8mb4_unicode_ci  

docker run --restart always --name engine -p 7090:7090 --log-opt max-size=500m 
-v $PWD/logs/xxx:/home/admin/logs --log-opt max-size=1000m      
-v $PWD/web/xxx/application.properties:/home/admin/application.properties            
-d xxx.xxx-xxx.top/xxx/xxx-xxx:feature_xxx

这样,外部就能通过访问宿主机的对应端口直接访问容器内提供的服务。

然而在项目启动后,发现console项目启动失败,日志打印无法连接到mysql数据库。

首先考虑应用容器网络问题,进入容器内,ping宿主机IP进行测试

结果没有问题,容器到宿主机的网络可达。

接下来查看mysql容器提供的服务是否有问题,由于容器内软件条件不够。本地尝试连接数据库。

数据库服务正常可用。外部可进行访问。

至此暂无其他思路。

临时解决方案

在看完之前项目提供的完整的部署文档后,发现在文档最后有这么一段


常见问题

-- 在redis容器中, 命令redis-trib.rb create 出现无法创建集群的问题

 Creating cluster
[ERR] Sorry, can't connect to node XXXX:port

原因: 防火墙中未开放端口, 通过iptables 或者 firewall-cmd 开放, 建议此种情况下建议关闭防火墙, 然后应用启动参数使用--net host 去掉-p映射
$ sudo service iptables stop(iptables) 或  $ sudo service firewalld stop (firewalld)

当然也可以开放所有端口, 这样可以使用-p参数

firewall-cmd --permanent --zone=public --add-port=80-65535/tcp
firewall-cmd --permanent --zone=public --add-port=80-65535/udp
firewall-cmd --reload

iptables -I INPUT -p tcp --dport 80:65535 -j ACCEPT
iptables -I INPUT -p udp --dport 80:65535 -j ACCEPT
service iptables save
service iptables restart

常见异常No route to host, 也是防火墙引起的, 原因与处理方法同上


根源问题还是出在了防火墙上,开放端口后容器间可正常进行服务访问。但是这种做法对外暴露了过多的端口,几乎所有的中间件,内部服务端口全部对外网开放,于系统而言不是一个安全的做法。

思考

  1.  iptables和docker的机制是如何导致在防护墙未开放端口的情况下,外部连接可直接访问服务,而宿主机中的其他容器无法访问
  2.  如何更好的利用docker的网络模式部署一个安全的集群(只对外网开发服务需要的端口,可结合nginx使用