Docker踩坑:Docker容器端口不受防火墙限制
讲故事
最近在自己的小服务器上部署了一些项目,都是使用nginx+域名进行反向代理,只开放了80和443端口一直使用正常。直到前几天为朋友开发了一个小项目需要部署到服务器上,本地调用接口时,发现使用IP+端口调用模式也可以调用。
这就奇怪了,明明防火墙并没有进行开放,但是却可以访问接口。

这就搞得我一头雾水,赶紧想问问ChatGPT,结果openai的账号被封了,简直是雪上加霜,于是乎使用谷歌百度大法,开查。
第一次解决
最终,发现了docker默认启动时,会修改iptables,添加进去一些规则,因为添加的规则是基于iptables的,而firewall也是基于iptables的,导致在firewall中发现端口并没有开放。这真是大坑啊,如果在生产环境端口都是开放出去的,可能会出大事。
找到了原因,那么答案也就不远了,大多数答案都是最简单的,直接修改/etc/docker/daemon.json,加入iptables: false即可。
# 编辑daemon.json文件
vim /etc/docker/daemon.json
# 加入下面的内容
"iptables": false
# Ctrl+C
# wq保存退出
# 重启docker
service docker restart
再次访问端口,已经无法访问了,总算万事大吉,顺便把ChatGPT的账号和API KEY也更换了。
第二次解决
可过了没多久,发现ChatGPT-NextWeb项目没法用了,一直显示错误,EAI_AGAIN,这又是怎么一回事呢,一查发现是DNS无法解析,之前都好好的,怎么突然无法解析了呢,我猜测是docker容器无法访问网络了。
结果一试果然如此,原来之前设置的iptables: false会使docker不将规则写入iptables,进出流量都给封住了。
这可不行,赶紧再查其他解决方法,网上有两种解决方法:
- 自己写入
iptables规则 - 在启动容器时将宿主机端口加上
127.0.0.1这样只有本机可以访问或使用host模式
第一种方式我进行了尝试,但是并没有效果,也是我着急,没有时间仔细研究iptables,导致无法成功。
iptables太麻烦了,使用host模式肯定是不行的,还是加127.0.0.1比较简单一些。
于是,我将docker的daemon.json文件修改回去,之后将所有项目的docker-compose文件种端口映射都加入了127.0.0.1。
version: '3.3'
services:
service_name:
image: image_name/image_name
container_name: container_name
restart: unless-stopped
ports:
- '127.0.0.1:50000:5000'
重新启动docker和容器。
service docker restart
总算是大功告成,两全其美,搞定了这个问题,所以记录一下防止下次再遇到。