学习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 –...
总结起来,解决Mac下Docker无法`ping`通宿主机的问题,关键在于通过`docker-machine`和`virtualbox`创建一个新的虚拟机环境,并设置适当的路由规则,使得Docker容器和宿主机之间能建立网络通信。同时,了解Docker的...
问题起源 在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 ...可以确定的是容器与宿主机是有网络连接的, 因为可以在容器内部通过 172.17.0.1 Ping 通宿主机: root@930d07576eef:/# ping 172.17.0.1 P
比如npm install以及bundle install等操作,或者是作为中间层在应用中去获取api数据的过程经常会出现timeout等情况,所以开始探究docker的网络机制,以解决网络请求太慢的问题。 一、docker的网络模式 1、none 当...
Docker容器无法停止或杀死的问题通常发生在使用Docker管理容器时。容器一旦创建,应当可以随时被停止或删除,但某些情况下可能会出现异常行为,导致容器无法通过正常的docker stop或docker kill命令来停止。这种问题...
最近工作中部署一个项目,在项目内部需要访问外网。给某云上传文件,但是一直报unknown host,无法解析域名,然后找了好久原因,下面废话不多说,来一起看看详细的解决方法: 解决方法 Linux系统默认没有打开IP...
Docker 容器入门与实践期末考试总复习 在本节总结中,我们将详细介绍 Docker 容器技术的基本概念、优点、架构、Namespace 和 Cgroup 等关键技术点,并总结 Docker 容器技术在实际应用中的价值。 容器技术解决了...
以Docker和Kubernetes为重点,沿着“基本用法介绍”到“核心原理解读”到“高级实践技巧”的思路,一本书讲透当前主流的容器和容器云技术,有助于读者在实际场景中利用Docker容器和容器云解决问题并启发新的思考。...
在本篇文章里小编给大家分享的是关于解决docker容器无法ping外网的问题,有需要的朋友们可以参考下。
解决Windows10下无法对docker容器进行端口访问(端口映射的问题) 在Windows10系统服务器中安装了docker和docker-compose 并尝试在其中运行Nginx服务,映射也做好 问题:在主机的浏览器中,打开localhost:port无法...
这意味着如果宿主机上运行的服务没有绑定到与容器相同的网络接口,那么容器内应用是无法访问到宿主机上的服务的。在本例中,nginx运行在容器内,通过“localhost:1234”尝试访问宿主机上的API服务,显然导致了连接...
Docker 容器网络配置与 Tomcat 安装 在本文中,我们将详细介绍如何创建 Docker 容器,配置容器 IP 桥接网络,并在容器内安装 Tomcat 服务。 一、 Docker 概述 Docker 是一种轻量级的操作系统虚拟化解决方案,可以...
标题中的“在docker容器中调用和执行宿主机的docker操作”是指在Docker容器内部运行命令来控制宿主机上的Docker服务。这种技术被称为Docker-in-Docker(dind),它允许用户在隔离的环境中运行Docker命令,这对于自动...
再查看宿主机时间是正确,这样肯定是容器启动时未将时区与宿主机保持同步了,由于测试镜像是由dockfile直接构建,因此问题基本了定准在dockerfile文件上了。 打开dockerfile检查后发现确实确失与宿主机时区同步设置...
在讲解Docker高级实践技巧的同时,深入到源代码层次,为读者梳理出Docker容器技术和基于Docker的容器云技术(如Kubernetes)的实现方法和设计思路,帮助读者理解如何在实际场景中利用Docker解决问题并启发新的思考。...
kubectl exec进入到docker容器中进行查看时发现,文件在容器中也是中文文件名显示异常。查看docker容器编码格式:执行locale命令;可以看到当前编码格式为POSIX,而这种编码格式不支持中文 解决办法:locale -a查