linux系统中docker服务和普通服务对外访问端口不通的问题

  前一段时间,在一个新的centos 7.4 服务器上运行项目,共有四个项目,因为特殊原因,两个是通过docker 运行,另外两个是通过nginxtomcat 运行。
  当运行起来以后,发现docker 运行的那两个可以正常在外网访问,而另外两个不是docker 的死活访问不到。
  我的排除问题的方法如下:

1、检查项目是否运行:

查看了tomcat是否运行:
输入如下命令:

ps -aux|grep tomcat

  的确tomcat运行正常,看过日志,运行也没有问题
查看了nginx 映射的另一个项目,端口仍存在,我后来直接输入了ss -tnl 命令:
结果如下:
在这里插入图片描述
  奇怪了,端口也是正常运行的,为什么偏偏docker的能对外访问,那两个不行呢。

那现在的情况如下图:

运行环境外网端口内网端口
docker服务7001(正常访问)10001(正常)
docker服务7002(正常访问)10002(正常)
nginx服务7003(访问失败)10003(正常)
tomcat服务7004(访问失败)10004(正常)

在这里插入图片描述

2、确认内网访问:

  难道是另外两个外网端口忘记开了?我赶紧试一下这两个不通的项目是否可以内网访问:
分别用了如下命令:

curl -i http://localhost:10003

和:

wget http://localhost:10003

  10004 也如上试过了,内网没问题,因此我判断端口没开,赶紧把铁锅甩了出去。
在这里插入图片描述

3、再次排查

  第二天,服务器提供方更狠,直接说内网telnet我的那俩端口访问不到,但是我内网是可以的,真的太奇怪了。
  整个过程我都没有想过防火墙的问题。为什么呢?
因为首先这是个新服务器,并没有设置过端口的规则,docker 的服务是可以的,另外两个不可以,那问题应该不是防火墙的问题(后来发现是自己想的太少了。。)
  后来我们架构师说,你把那两个通的项目先关掉,用那俩不通的项目先试试这两个通的端口,试试能不能外网访问?
在这里插入图片描述
  这想法我怎么没想到,哈哈,我赶紧试试,发现,的确也不能访问,那这样就赖不上人家了,只能自己再看了。

4、最终问题原因

  在最后,我先关掉了一下防火墙,因为centos 7 默认安装的防火墙是firewall ,所以我先将防火墙关掉:

关掉firewall 防火墙

systemctl stop firewalld.service 关闭防火墙

   然后访问了下项目,才发现,项目都通了,竟然都可以正常访问。
在这里插入图片描述

  为什么docker 的可以,其他的竟然不可以,防火墙是肯定没有设置过,为什么呢?难道是docker 在安装的时候,自动设置了?

5、安装iptables

  既然找到了问题,以前没有设置过firewall ,我想直接重新安装iptables 的了。

首先关闭firewall开机启动

systemctl disable firewalld.service 

确认防火墙是否关掉
  关闭后显示notrunning即表示已关闭

firewall-cmd --state 

安装iptables

yum install iptables 
yum install iptables-services

  如果yum 命令不可用,可以参照另一篇文章,linux命令—使用yum命令时出错,Could not retrieve mirrorlist

启动iptables

service iptables start  或者 systemctl start iptables

设置开机启动iptables

systemctl enable iptables.service

编辑防火墙文件,输入如下命令:

vim /etc/sysconfig/iptables

在其中开启了我的那四个端口:

# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10001 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10002 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10003 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 10004 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

  即如上,我开启了我的 80、10001、10002、10003、10004 端口。
设置完之后,重启iptables

service iptables restart

这样就可以正常访问项目了。

  虽然最后解决了问题,但是我还是没搞明白,为什么docker 运行的项目是可以访问,其他的不行呢?期望大神解惑~

2021年3月2号补充

一位大佬解惑,如下:

  docker 容器创建时,如果你指定了容器映射的宿主机端口,docker 会自动在 iptables 的规则链中加上自己容器对外提供服务所需的规则链,所以 docker 容器跑的服务可以访问到。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐