Docker容器端口映射后Hadoop突然无法连接
Docker容器端口映射后Hadoop突然无法连接
一、背景
一般需要对外提供服务的Docker容器,我们在启动时后使用-p命令将对外访问端口暴露给外部,故在创建容器是,我们将Hadoop的端口隐射出来供外部访问:
1 |
|
但最近碰到一个非常奇怪的情况:在一个CentOS 7测试环境里部署有Docker Hadoop,并对外暴露了端口。启动容器后一段时间内都是可以正常工作的,但在不定时间间隔后,Hadoop的web端就访问不了:
原本以为是我们的Hadoop服务没有正常启动,但是Jps查看时,却发现正常:
至于这个问题,只有手动重启出问题的Docker,然后在重启Hadoop服务后,外部才可以重新访问,但只要再过一段时间又会出现这样的问题。
二、问题排查
情况一:开着防火墙但没有开放端口
CentOS 7自带并启用了防火墙FirewallD,我们可以通过下面的命令检查FirewallD的状态:
1 |
|
如果输出的是“not running”则FirewallD没有在运行,且所有的防护策略都没有启动,那么可以排除防火墙阻断连接的情况了。
如果输出的是“running”,表示当前FirewallD正在运行,需要再输入下面的命令查看现在开放了哪些端口和服务:
1 |
|
可以看到当前防火墙只开放了ssh服务(22/tcp)和dhcpv6-client服务,并没有打开Docker容器映射的Hadoop端口。
解决方案有两种:
1.关闭FirewallD服务:
如果您不需要防火墙,那直接关掉FirewallD服务就好了
1 |
|
但是在部署Hadoop服务之前,就已经将firewalld服务禁用了,故此问题的根源不在这
2.添加策略对外打开指定的端口:
比如我们现在要打开对外9870/tcp端口,可以使用下面的命令:
1 |
|
如果只是临时打开端口,去掉第一行命令中的“–permanent”参数,那么当再次重启FirewallD服务时,本策略将失效。 此命令不建议执行,毕竟Hadoop服务端口那么多…
情况二:没有启用IP_FORWARD
因为一直没法定位出问题的所在,所以不能正常访问HadoopWeb端时,手动登陆宿主机重启Docker,再重启 Hadoop服务。
在有一次登录到宿主服务器上准备重启Docker daemon服务前,我突然想起之前在用Docker的时候还碰到过另一个问题:如果宿主机没有启用IP_FORWARD功能,那Docker容器在启动时会输出一条警告消息:
1 |
|
会不会是因为宿主机的IP_FORWARD功能没有启用所以才引起的这个故障呢?
1 |
|
因为,我这里是设置过的,原本的结果为:net.ipv4.ip_forward = 0,表示当前系统的IP_FORWARD功能处于停用状态!
可是问题来了,当时启动容器的时候都是好的啊,什么都没有输出,怎么用着用着IP_FORWARD功能就被禁用了呢?
Docker daemon服务在启动的时候会自动设置iptables设置,难不成它还会检查IP_FORWARD设置,并帮我临时启用吗?
带着这个假设,我手动重启了一下Docker Hadoop服务
1 |
|
果然,Docker 服务在启动过程中会检查系统的IP_FORWARD配置项,如果当前系统的IP_FORWARD功能处于停用状态,会帮我们临时启用IP_FORWARD功能,然而临时启用的IP_FORWARD功能会因为其他各种各样的原因失效…
问题找到,至于修复方案倒非常简单,只要一行命令就可以了:
1 |
|
执行完成后,重启服务器或使用下面的命令从文件中加载配置:
1 |
|
就OK了。Hadoop正常访问咯!
三、小结
Docker 服务在启动的时候会帮帮我们调整很多的配置项,比如这次出事儿的IP_FORWARD配置。
Docker 启用IP_FORWARD功能是因为Docker容器默认的网络模式(bridge/网桥模式)会给每个容器分配一个私有IP,如果容器需要和外部通信,就需要使用到NAT。NAT需要IP_FORWARD功能支持,否则无法使用。这也解释了为什么会出现在IP_FORWARD功能停用的情况下,使用bridge模式的容器内外均无法访问的情况。
只是在Linux下,出于安全考虑,默认是停用IP_FORWARD功能的,Docker 服务在启动时会检查IP_FORWARD功能是否已经启用,如果没有启用的话,Docker 会悄无声息的临时启用此功能,然而临时启用的IP_FORWARD功能并不能持久化,会因为其他命令的干扰导致失效。
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!