Docker内QEMU模拟树莓派系统无法连接互联网的解决方法
问题核心逻辑
现在整个环境是两层嵌套的NAT网络结构,不通的根本原因不在Docker层:
- 外层是Docker容器本身:用默认bridge网络拿到172.17.0.2的地址,本身已经能正常访问外网
- 内层是跑在容器里的QEMU模拟器:启动时默认用了用户态SLIRP虚拟网络,给模拟的Raspbian分配了10.0.2.15的地址,本来这个网络栈是借QEMU进程的网络权限出网的,上不了网基本都是配置疏漏,和Docker网络权限没关系
排查修复步骤
1. 先配置模拟Raspbian内部的网络参数
登录到QEMU里的Raspbian系统,先做基础配置校验:
- 检查默认路由:SLIRP虚拟网络的固定网关是
10.0.2.2,执行ip route show看有没有默认路由条目,如果缺失就手动添加:sudo ip route add default via 10.0.2.2 dev eth0 - 检查DNS配置:SLIRP默认提供的虚拟DNS是
10.0.2.3,查看/etc/resolv.conf的配置是否正确,如果不对就手动写入配置:nameserver 10.0.2.3
- 连通性验证:配置完先ping虚拟网关
10.0.2.2,再ping虚拟DNS10.0.2.3,能通的话再试ping公网IP比如8.8.8.8
这里要留意:很多人配置到这步发现能ping通公网IP,但打不开网页,就是因为SLIRP的内置DNS转发没启用,这时候不用折腾QEMU参数,直接把Raspbian里的DNS换成公共DNS地址比如8.8.8.8、114.114.114.114就行,只要IP层通了,DNS用公网地址完全不影响上网效果
2. 校验QEMU的启动网络参数
如果上面的配置做完还是无法出网,大概率是QEMU启动时的网络参数没配置完整:
- 回到Docker容器的根环境,查看当前QEMU进程的启动命令,找网卡相关的配置段
- 默认不完整的参数一般是
-netdev user,id=n0,需要补全为显式指定网段、DNS的完整配置,类似:
原理是QEMU的用户态网络栈会把模拟系统发出的所有数据包,通过QEMU进程本身转发出去——因为QEMU进程跑在已经能上外网的Docker容器里,只要QEMU能正常往外发包,模拟的Raspbian自然就能连通外网。-netdev user,id=n0,net=10.0.2.0/24,dns=10.0.2.3
关于之前执行docker network connect报错的说明
你之前执行docker network connect multi-host-network <容器ID>时报错网络不存在,属于预期内的结果,不是操作权限问题:
- 你可以先执行
docker network ls查看当前所有已创建的Docker网络,就能发现multi-host-network根本不存在 - 而且这个操作本身也解决不了当前问题:当前的网络故障是QEMU和Docker容器之间的内层链路问题,Docker容器本身的网络是正常的,就算把容器连到任何Docker网络上,只要QEMU内部配置不对,模拟系统还是上不了网
- 只有后续你需要把多个模拟树莓派跨节点组网时,才需要创建对应的自定义Docker网络,单节点出网场景完全不需要调整Docker本身的网络配置
内容的提问来源于stack exchange,提问作者Jatin Sharma
相关产品推荐
相关产品推荐

