时间:2021-05-02
背景:
之前做了一个项目,需要在容器内访问宿主机提供的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得以访问外网。
不做骚操作,沿用常见的②网桥模式:
第一步:自定义网桥并应用该自定义网桥
? 1 docker network create --gateway 172.16.1.1 --subnet 172.16.1.0/24 app_bridge ? 1 2 3 4 5 6 7 8 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)。
? 1 2 3 4 5 6 7 8 9 10 11 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网关会卡住收不到结果。
除非满足列出的input链规则,否则缺省的策略就是丢弃。
后面还有转发和output链缺省是 接受
这个策略的初衷是 服务器安全(尼玛, 导致容器访问宿主机的基础能力都没有了!!!)。
运维方案:
① 使用 sudo service iptables stop 关闭iptables
② 把要使用的网桥网段加入 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通网桥网关,进而无法访问宿主机,可参考本文排障。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对服务器之家的支持。
原文链接:https://www.cnblogs.com/JulianHuang/p/11636825.html
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
最近在工作时遇到一个问题,docker容器无法访问宿主机的redis,telent6379端口不通。经排查发现,该服务器启用了防火墙,防火墙把6379的端口的访
docker默认使用bridge模式,通过网桥连接到宿主机,而容器内部的ip则从网桥所在的ip段取未用的ip。这样做一个不方便的地方在于容器内部的ip不是固定的
如何解决ECS云主机无法访问其他内网主机和内网应用ECS主机无法访问其他内网主机,如下图所示:也无法访问其他内网应用服务,如RDS,如下图所示:其他网络正常,n
一直以为docker是没有ip地址的,其实docker的网络模板有点类似我们平常使用虚拟机的host-only模式,容器和宿主机组成一个独立的局域网,宿主机的i
docker部署redis首先在linux中安装上Docker,然后启动Docker服务Centos7中启动Dockersystemctlstartdocker