21

【已解决】记一次 docker 容器内能 ping 通 ip 但 ping 不通域名问题的排查经过

 2 years ago
source link: https://hellodk.cn/post/496
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文准备发在 v2ex 的但是编辑好了发布时提醒我
20210413211852.png

第一次见到这个提示…… 是我这两天讨论这个问题有点多?好吧 对不起 那我就发自己博客吧 这时候就发现拥有一个能自由自在不受别人约束的写东西的地方 还是针不戳的

前情提要:https://www.v2ex.com/t/769968

感谢大家关注这个问题,后面楼主还是不喜欢那个 sirpdboy 的固件,问题很多,比如 dockerd 开机无法实现自启。首先启动(/etc/init.d/dockerd start)都是有问题的,改了启动脚本之后启动可以了但是开机自启不会改了了(本人 shell 🥬🐓️),后面用 pip 安装 docker-compose 总是失败,于是又自己编译安装 python2.7 和 pip2,又遇到 openwrt 下坑爹的 openssl 库的问题。

后面放弃,转战一直用的这个固件。

今天终于发现了问题,并且来说说是怎么解决的

20210413204341.png

👆🏻将这个 wan_mode 改为 1

20210413204447.png

👆🏻修改 /etc/init.d/dockerd 启动脚本,如果是 1 的时候启动参数设置成 --iptables=true

20210413204557.png

👆🏻好家伙,/etc/init.d/dockerd restart 之后 iptables 终于出现了很多条 docker0 的相关的规则。iptables 四表五链这些还需要花时间学习……

可是依然不行,真是挫败感十足啊……

报错依然存在 搜了很多 在这里记录一下

  • bad address "baidu.com"
  • [resolver] read from DNS server failed, read udp 172.17.0.2:50108->180.76.76.76:53: read: connection refused (启用了dockerd 的 debug 模式观察到的 dockerd --debug)
  • nslookup: write to '8.8.8.8': Connection refuse
  • 其他不记得了

仔细看了 iptables 规则。感觉防火墙这边应该没有问题了,问题还是出在 dns 解析上。前情提要的文章中就提到了楼主在本地使用了 dnsmasq 作为本地局域网 dns 服务器,于是终于发现了问题。

20210413205733.png

找到 /etc/dnsmasq.conf 的 example ( https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example ) 然后对比我本地 我自己配置的。以前我在这篇文章里也提到了 dnsmasq 的一些玩法: https://hellodk.cn/post/124

试图在恩山找到答案,关于docker user-defined network(bridge模式)的 dns 解析问题

搜到了这两篇文章

https://www.right.com.cn/forum/thread-1905062-10-1.html 见141楼
"Docker Arm64 Openwrt-210311 斐讯N1/贝壳云等机器都可用 - 斐讯无线路由器以及其它斐迅网络设备 - 第10页 - 恩山无线论坛 - Powered by Discuz!"

https://www.right.com.cn/forum/thread-941106-1-1.html 见3楼
"【原创】docker运行OpenWRT借助vlan实现单臂全功能主路由,支持WiFi 与IPv6 PPPoE - 斐讯无线路由器以及其它斐迅网络设备 - 恩山无线论坛 - Powered by Discuz!"

20210413210156.png

👆🏻 docker 的 network,如果是 bridge 模式,会在宿主机生成一个虚拟网卡,这个虚拟网卡的ip地址也是使用这个network 的容器的默认网关。这个地址应该被添加到 /etc/dnsmasq.conf 的 listen-address 字段中

20210413210401.png

👆🏻将docker 的虚拟网卡的ip地址添加到 dnsmasq 的监听列表中然后重启 dnsmasq /etc/init.d/dnsmasq restart

docker 默认的 bridge network,docker daemon 在宿主机上生成的网卡名称是 docker0,而 user-defined network 一般是 br-xxxx 这样的网卡名称

telegram-cloud-photo-size-5-6316783809147808577-y.png

试了busybox alpine 等等镜像,都成功了。容器无论使用的是自建的 bridge 网络还是 docker 默认提供的 bridge 网络,只要把对应的网卡地址添加到 dnsmasq 的监听列表中即可,这下问题终于解决了!

总结:

  1. dockerd 启动时需要 iptables 为 true 的参数,docker daemon 会自动为防火墙添加上相关规则
  2. 宿主机的自建 dns 服务(dnsmasq)没有监听来自 docker 的网卡的查询请求,这一点一开始想到了,但的确没有“重视”,一开始就没有往这方面排查…… 吃一堑长一智吧
  1. docker 官方建议使用自定义的 基于 bridge 的网络 https://docs.docker.com/network/bridge/
  2. 恩山那两个帖子提供了关键的“灵感”,但是他那个监听 127.0.0.11 不适用我机器上的环境
  3. 本帖也是给自己做个备忘录,就直接发这儿了

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK