记一次linux Docker网络故障排除经历

故事扮演 提交于 2019-11-30 19:17:58

背景:

  之前做了一个项目,需要在容器内访问宿主机提供的Redis 服务(这是一个比较常见的应用场景哈), 常规方案:

①   主机网络(docker run --network=host): 完全应用主机网络堆栈,在容器内localhost就是指向宿主机

②   网桥网络(docker run --network=bridge):  这也是docker容器默认的网络通信模式,容器内localhost 指向的是容器自身,不能使用 localhost 访问宿主机上localhost:6379承载的Redis服务 。

docker会默认建立docker0 网桥;

网桥有一个网关ip, 有一个子网段; 网桥内容器从子网段中确定容器ip( ip  addr eth0), 网桥内容器可通过 service name相互访问;

网桥内容器通过 docker0 Getway得以访问外网。 

我们不做骚操作,肯定还是沿用常见的②网桥模式,

第一步:自定义网桥:

docker network create --gateway 172.16.1.1 --subnet 172.16.1.0/24 app_bridge

 

 为啥不适用默认docker0网桥?

本文开头说了, docker0 是默认网桥,新建的容器默认都会加入这个网桥,所以我们需要建立一个专属于本程序的网桥app_bridge

第二步:为实现在容器内网桥模式访问 宿主机localhost:6379 的服务, 必须搭配docker 提供的 --add-host 选项(对应到docker-compose.yml这个配置是extra_host)。

docker run 的--add-host 选项能在 容器 /etc/hosts 文件增加行记录,便于我们使用该名称访问其他网络。

 docker run -it --add-host dockerhost:172.16.1.1 ubuntu cat /etc/hosts
172.17.0.22     09d03f76bf2c
fe00::0         ip6-localnet
ff00::0         ip6-mcastprefix
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
127.0.0.1       localhost
::1	            localhost ip6-localhost ip6-loopback
172.16.1.1      dockerhost

之后在程序的配置文件即可应用 dockerhost:6379 访问宿主机Redis服务。

------------------------------------------ 稍熟悉docker网络模型的朋友都能理所当然完全上述操作-----------------------------------------------------

 

这里我要提示一个状况:

  我在公司CentOS7机器上使用上述操作, 容器内一直无法连通宿主机(容器间还是能正常访问)。

       简化问题测试:新建容器,在容器内尝试ping docker0 网关, 哔了狗了4台公司机器都ping不同docker0网关,外网还是正常访问。

       那这个问题就成了: 使用默认的docker0网桥,容器内无法ping通docker0网关,进而无法访问宿主机。

  呀呀呀呀, 八成是公司机器的配置问题,好慌,我是一个linux 小白,我是一个linux 小白,我是一个linux 小白    ~。。~

  追问了公司运维,发现:

 

 Chain INPUT (policy DROP)

 INPUT链的默认策略是 丢弃,就是本机默认不接受任何连接,除非满足下面的INPUT 链策略。

这个策略的初衷是为了 服务器安全(尼玛, 导致容器访问宿主机的基础能力都没消失了!!!)。

运维方案:

  •   service iptables stop   关闭iptables

  •   把要使用的网桥网段加入 INPUT链

作为一个linux准小白,默默的 使用service iptables stop 关闭了公司设定的iptables.

 

OK, That‘s All, 以后若有朋友遇到 默认网桥容器内无法ping通网桥,无法访问宿主机,可参考本文排障。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!