背景:

  之前做了一个项目,需要在容器内访问宿主机提供的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 引擎在网桥上有个网关IP,容器在连接的网桥上有个容器IP。

操作

第一步:自定义网桥并应用该自定义网桥

docker network create --gateway 172.16.1.1 --subnet 172.16.1.0/ app_bridge
docker run --network=app_bridge --name ......

# 以下截取自docker-compose.yml文件
......
networks:
default:
name: app_bridge
external: true

为啥不利用默认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网关,进而无法访问宿主机。

呀呀呀呀, 八成是公司机器的配置问题 ~。。~

追问公司运维同学,发现:

Chain INPUT (policy DROP)

以上INPUT链的缺省策略是丢弃:从容器内访问宿主机的INPUT链规则不匹配其中列出的任意一条,将被丢弃(缺省),所以我们从容器ping docker0网关会收不到结果。

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

运维方案:

①  使用 sudo service iptables stop 关闭iptables

②  将容器使用的源IP(网桥网段)加入INPUT链

sudo  iptables -I INPUT -s 172.17.0.0/16 -j ACCEPT

接受docker0子网段172.17.0.0/16 INPUT】  加入规则, 传送门

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

记一次linux Docker网络故障排除经历的更多相关文章

  1. 记一次诡异的网络故障排除 - tpc_tw_recycle参数引起的网络故障

    一.故障现象 我们团队访问腾讯云上部署的测试环境中的Web系统A时,偶尔会出现类似于网络闪断的情况,浏览器卡很久没有反应,最终报Connection Timeout. 不过奇怪的是,当团队中的某个人无 ...

  2. [转帖]记一次KUBERNETES/DOCKER网络排障

    记一次KUBERNETES/DOCKER网络排障 https://coolshell.cn/articles/18654.html 记得之前在一个公众号里面看过这个文章 讲的挺好的.. 物理机直接跑d ...

  3. 记一次KUBERNETES/DOCKER网络排障

    https://coolshell.cn/articles/18654.html 总结在前面: 1.kill -9杀死docker进程,系统一定是要遍历所有的docker子进程来一个一个发退出信号的, ...

  4. 一次误用CSRedisCore引发的redis故障排除经历

    前导 上次Redis MQ分布式改造完成之后, 编排的容器稳定运行了一个多月,昨天突然收到ETL端同事通知,没有采集到解析日志了. 赶紧进服务器看了一下,用于数据接收的receiver容器挂掉了, 尝 ...

  5. 《DevOps故障排除:Linux服务器运维最佳实践》读书笔记

    首先,这本书是Linux.CN赠送的,多谢啦~ http://linux.cn/thread-12733-1-1.html http://linux.cn/thread-12754-1-1.html ...

  6. linux系统——网络调试工具

    http://blog.csdn.net/chinalinuxzend/article/details/1799279 1.网络调试工具概说: 如 果我们把一台机器接入网络中,通过网络配置工具的配置这 ...

  7. traceroute排查网络故障 www.qq.com排查网络故障网络不通 先ping自己

    网络不通 先ping自己 在ping网关 再ping外网 再ping别人的ip 背景需求 Linux 因为其强大的网络处理能力,被广泛用于网关(实例链接)和服务器(实例链接).实际工作中,快速排查这些 ...

  8. 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除

    目录 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除 18.1 centos6系统启动过程及相关配置文件 18.1.1 centos6系统启动过程 18.1.2 centos6启 ...

  9. Linux系统之TroubleShooting(故障排除)(转)

    尽管Linux系统非常强大,稳定,但是我们在使用过程当中,如果人为操作不当,仍然会影响系统,甚至可能使得系统无法开机,无法运行服务等等各种问题.那么这篇博文就总结一下一些常见的故障排除方法,但是不可能 ...

随机推荐

  1. Linux配置使用SSH Key登录并禁用root密码登录

    Linux系统大多数都支持OpenSSH,生成公钥.私钥的最好用ssh-keygen命令,如果用putty自带的PUTTYGEN.EXE生成会不兼容OpenSSH,从而会导致登录时出现server r ...

  2. [python]多元赋值

    1. 简介 将多个变量同时赋值的方法,称为多元赋值. 2. 示例一: x, y, z = 1, 2, 'a string' print x, y, z 运行结果: 1 2 a string

  3. [python]错误检测及异常处理try-except

    1. 简介 要给代码添加错误检测及异常处理,只需要将其封装在try-except中. try:通常的代码 except:处理错误和异常的代码 2. 示例 import os try: path = ' ...

  4. 用webpack构建一个常规项目,好处和坏处分析

    最近项目改版,用webpack重新架构. 些许心得我会写几篇记录一下. 好处如下: 1.ES6语法用起来,babel-loader转义,各种新语法用起来. 2.import 语法写起来,webpack ...

  5. Java 中初始化 List 集合的 7 种方式

    1.常规方式 List<String> languages = new ArrayList<>(); languages.add("Java"); lang ...

  6. 每天学会一点点(map常量)

    map常用的声明方式(使用静态代码块): public final static Map map = new HashMap(); static { map.put("key1", ...

  7. JAVA集成JPush

    本篇集成为web项目手动集成JPush 一.获取AppKey.Master Secret https://docs.jiguang.cn 成为极光用户创建一个应用拿到(AppKey.Master Se ...

  8. 使用vitamio长时间播放崩溃的另类处理

    最近公司一个项目在公交站旁边弄一个 广告牌,上面是广告视频,下面是广告图片,都是无限轮播的.要求从早上6点到晚上11点不间断播放.剩余时间为关机状态. 图片部分还好说,就是viewpager弄一个无限 ...

  9. Vector和Arrarlist的异同;Hashtanle和HashMap的异同

    Vector和ArrayList的异同 实现原理相同,功能相同,可以互用 主要区别: Vector线程安全,ArrayList重速度,轻安全,线程非安全. 长度需要增长时,Vector默认增长一倍,A ...

  10. query 与 params 使用

    这个是路由: {     path:'/city/:city',     name:'City',     component:City   }   下面使用query和params分别传参 quer ...