解决Docker容器内无法解析DNS的问题

问题描述

  最近Docker上重装Nexus3,一直报错 UnknownHostException: rhc.sonatype.com (在另一个场景中报 NoRouteToHostException: No route to host )

  于是在docker中启动了一个centos镜像用于测试 ping www.baidu.com.
  几乎试遍了能找到的所有方法,包括“修改DNS”,“修改Docker配置”,“关闭防火墙”,“禁用virbr0网络连接”等,全部无效。 无意中发现直接ping ip地址居然可以ping通,确定问题发生在DNS解析上,并猜测多半还是跟防火墙有关。于是改用关键字docker dns 防火墙进行搜索。于是找到了如下方法。

  • 注:Docker 容器默认网络模式为bridge

解决方案

  • 注:以下指令均在宿主Linux系统中运行,而非容器中
  1. 方法1. 关闭防火墙(不推荐)
      关闭防火墙后需重启docker,否则会报错
    systemctl stop firewalld
    systemctl restart docker
  2. 方法2. 宿主机防火墙开启伪装IP功能
    // https://www.cnblogs.com/architectforest/p/12389218.html
    firewall-cmd --zone=public --add-masquerade --permanent
    firewall-cmd --reload
    systemctl restart firewalld
    systemctl restart docker
      还看到另一个方法,未测试有效性,先放在这里
    // https://blog.csdn.net/mostone/article/details/105815866
    // 将网络接口 docker0 加入 trusted zone
    firewall-cmd --permanent --zone=trusted --add-interface=docker0
    
    firewall-cmd --permanent --zone=trusted --change-interface=br-d2aa50162455
  3. 方法3. 通过host模式启动容器
      这是最简单的方法,容器启动即可直接访问外网,但是无法指定容器对外暴漏的端口,将使用默认端口。
    docker run -it --net=host centos

补充

  1. 今天部署docker又发现一个网络的问题,程序中给出的错误是
    java.net.NoRouteToHostException: Host is unreachable (Host unreachable)
      在docker容器内ping宿主ip,可以ping通。 wget读取宿主8080端口(有效的)失败,提示
    wget: can't connect to remote host : Host is unreachable
      又尝试wget读取baidu.com成功。所有十有八九问题又出在宿主防火墙上了。 解决方法:
    firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.20.0.0/16 accept' --permanent
    firewall-cmd --reload
    systemctl restart firewalld
    // 验证规则是否添加成功
    firewall-cmd --list-all
      address对应docker容器的ip网段,如果没有添加–permanent防火墙重启后会失效(被坑了好几次)
  2. VMware和Docker容器无法ping通宿主(win10)
      方法1、宿主关闭防火墙
      方法2、宿主打开防火墙高级设置(或直接搜索“高级安全 Windows Defender 防火墙”)-入站规则 启用规则“文件和打印机共享(回显请求 - ICMPv4-In)”