学习docker,用公司分配的两台虚拟机创建nginx镜像,结果无法联通外网,查了好几天也无法定位问题所在。最后误打误撞修改了容器的默认网段,结果可以联网了。估计是默认网段172.17.0.0与公司的其他网段冲突的原因。记录一下学到的技巧。
首先需要明确docker的网桥模式,网桥工作在二层(OSI堆栈),是通用网络设备的一种,可以设置IP地址。有了IP地址,Linux便可通过路由表或IP表,在网络层定位网桥,这就相当于有了一个虚拟网卡,即docker0。docker0默认的地址划分:IP(127.17.42.1/16),在启动容器时,docker会在宿主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备,容器启动时,Docker引擎将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在宿主机中,以veth***这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看,从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
1. 首先检查宿主机的网络配置
1)检查网桥brctl show
bridge name bridge id STP enabled interfaces docker0 8000.f229f45b3df2 no vethaef304e
2) 检查ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast state UP group default qlen 1000 link/ether fa:16:3e:5d:75:0a brd ff:ff:ff:ff:ff:ff inet 10.164.99.214/20 brd 10.164.111.255 scope global dynamic eth0 valid_lft 69570sec preferred_lft 69570sec inet6 fe80::f816:3eff:fe5d:750a/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether fa:16:3e:45:a9:5e brd ff:ff:ff:ff:ff:ff inet 10.122.76.71/24 brd 10.122.76.255 scope global dynamic eth1 valid_lft 65709sec preferred_lft 65709sec inet6 fe80::f816:3eff:fe45:a95e/64 scope link valid_lft forever preferred_lft forever 128: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether f2:29:f4:5b:3d:f2 brd ff:ff:ff:ff:ff:ff inet 172.17.10.1/24 brd 172.17.10.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::e03c:c3ff:fe90:1cee/64 scope link valid_lft forever preferred_lft forever 130: vethaef304e@if129: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether f2:29:f4:5b:3d:f2 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::f029:f4ff:fe5b:3df2/64 scope link valid_lft forever preferred_lft forever
可以看到docker创建的虚拟网卡docker0的网段为172.17.10.1/24
3)查看路由:
****** 10.160.146.0/23 via 10.122.72.1 dev eth1 ****** 172.16.0.0/12 via 10.122.72.1 dev eth1 172.17.0.0/20 via 10.122.72.1 dev eth1 172.17.10.0/24 dev docker0 proto kernel scope link src 172.17.10.1
即172.17.10.0/24网段的包均通过docker0网桥来转发.
2. 再来查看容器的ip
1) 创建一个bash容器: docker run -it --rm bash:4.4
2) 查看容器ip: ip a
bash-4.4# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 129: eth0@if130: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:0a:02 brd ff:ff:ff:ff:ff:ff inet 172.17.10.2/24 brd 172.17.10.255 scope global eth0 valid_lft forever preferred_lft forever
可以看到虚拟网卡eth0的ip为172.17.10.2
3) 查看容器内的路由: ip route
bash-4.4# ip route default via 172.17.10.1 dev eth0 172.17.10.0/24 dev eth0 scope link src 172.17.10.2
由此可知172.17.10.0网段的包均走容器内的eth0,默认网关为172.17.10.1
4) 如果容器中无法ping通外网,首先查看能否ping通网关。如果网关都无法ping通,说明网桥或网段有问题。这里就可以用tcpdump来查看。比如监控上面第一步的网桥接口tcpdump -i vethaef304e -nn,正常的网络包应答如下:bash-4.4# ping -c 1 8.8.8.8
root@XXXXX:~# tcpdump -i vethaef304e -nn tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on vethaef304e, link-type EN10MB (Ethernet), capture size 262144 bytes 17:17:16.282976 IP 172.17.10.2 > 8.8.8.8: ICMP echo request, id 2304, seq 0, length 64 17:17:16.325812 IP 8.8.8.8 > 172.17.10.2: ICMP echo reply, id 2304, seq 0, length 64 17:17:21.297595 ARP, Request who-has 172.17.10.1 tell 172.17.10.2, length 28 17:17:21.297656 ARP, Reply 172.17.10.1 is-at f2:29:f4:5b:3d:f2, length 28
异常时就只有request who-has包,没有reply
3. 问题解决
查看网桥,路由和ip均没发现问题,试试修改docker0的默认网段,居然成功了,步骤如下:
1) 删除原有配置
service docker stop ip link set dev docker0 down brctl delbr docker0 iptables -t nat -F POSTROUTING2) 创建新的网桥
相关推荐
最近在工作时遇到一个问题,docker容器无法访问宿主机的redis,telent6379端口不通。 经排查发现,该服务器启用了防火墙,防火墙把6379的端口的访问授权给docker0网卡访问即可。 操作如下: firewall-cmd –...
抛弃docker for mac自带的linux虚拟机(尽管轻量,但其与OSX通信采用socket文件的方式),使用docker-machine 安装virtualbox。virtualbox创建后,会添加一个虚拟网卡,可以通过ifconfig命令查看。我们实现的方式,...
问题起源 在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 ...可以确定的是容器与宿主机是有网络连接的, 因为可以在容器内部通过 172.17.0.1 Ping 通宿主机: root@930d07576eef:/# ping 172.17.0.1 P
详细介绍Docker容器内部端口映射到外部宿主机端口的方法小结
以Docker和Kubernetes为重点,沿着“基本用法介绍”到“核心原理解读”到“高级实践技巧”的思路,一本书讲透当前主流的容器和容器云技术,有助于读者在实际场景中利用Docker容器和容器云解决问题并启发新的思考。...
比如npm install以及bundle install等操作,或者是作为中间层在应用中去获取api数据的过程经常会出现timeout等情况,所以开始探究docker的网络机制,以解决网络请求太慢的问题。 一、docker的网络模式 1、none 当...
解决Windows10下无法对docker容器进行端口访问(端口映射的问题) 在Windows10系统服务器中安装了docker和docker-compose 并尝试在其中运行Nginx服务,映射也做好 问题:在主机的浏览器中,打开localhost:port无法...
② 网桥网络(docker run --network=bridge): 这也是docker容器默认的网络通信模式,容器内localhost 指向的是容器自身,不能使用 localhost 访问宿主机上localhost:6379承载的Redis服务 。 docker会默认建立...
再查看宿主机时间是正确,这样肯定是容器启动时未将时区与宿主机保持同步了,由于测试镜像是由dockfile直接构建,因此问题基本了定准在dockerfile文件上了。 打开dockerfile检查后发现确实确失与宿主机时区同步设置...
在讲解Docker高级实践技巧的同时,深入到源代码层次,为读者梳理出Docker容器技术和基于Docker的容器云技术(如Kubernetes)的实现方法和设计思路,帮助读者理解如何在实际场景中利用Docker解决问题并启发新的思考。...
实现跨宿主机多docker容器间数据共享
docker容器与容器云的文档,有助于理解docker的知识。
docker容器时间和宿主机实际时间不一致的解决
docker容器内安装软件时很慢的解决办法,用网易加速和阿里云加速提升软件安装的速度,安装ps,vi,telnet,netstat等命令,亲测!
主要介绍了Docker容器访问宿主机网络的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
promethues(普罗米修斯)监控docker容器——详细文档,超详细文档总结
至于为什么要在docker中操作宿主机的docker,优点不言而喻,你既可以将你的具体需求容器化部署,又不用直接在宿主机上安装(假设我们没有办法在docker中操作宿主机的docker,那么我们只能将这样的软件程序直接安装到...
Docker 容器与容器云(第2版) PDF版本,带电子目录,结构清晰