虚拟机里配置的DNS服务器,本质上是通过虚拟网络设备转发给虚拟机的网络配置参数,让虚拟机里的系统知道该找谁解析域名,但配置后不生效或覆盖是绝大多数人踩坑的真实原因。
很多人在虚拟机里折腾DNS,改了配置文件,重启网络服务,结果发现解析还是走老路子,这不是你运气差,而是因为虚拟机的DNS涉及宿主机虚拟网络设备、虚拟机内系统服务、DHCP下发的租约三层的配合,任何一个环节接管了配置,你手改的文件可能转眼就被覆盖。
先搞清楚DNS在虚拟机里是怎么流转的
虚拟机不是物理机,它没有自己的网卡硬件,所有网络流量都要经过宿主机虚拟出的网卡设备,在VirtualBox、VMware Workstation、KVM这些主流平台里,虚拟网卡有几种连接模式,DNS的传递路径也完全不同。
- NAT模式:宿主机充当路由器和DNS转发器,虚拟机的DNS请求先发给宿主机,再由宿主机转发到外网DNS,此时虚拟机的DNS服务器地址默认是宿主机虚拟网卡的IP(比如VirtualBox的10.0.2.2,VMware的192.168.x.1)。
- 桥接模式:虚拟机直接接入物理局域网,相当于局域网里的一台独立电脑,DNS设置为局域网路由下发的地址,流量不经过宿主机转发。
- 仅主机模式(Host-Only):虚拟机只能和宿主机通信,DNS解析通常需要配合宿主机上的DNS服务,否则虚拟机出不了外网。
行业共识认为,NAT模式下的DNS不生效问题最多,因为流量链路长,任何一个节点设置不当都会导致解析失败。
虚拟机dns配置不生效的原因排查
遇到配置后不生效,先别急着重装系统,按下面的顺序查一遍,这个问题的核心是搞清楚你的配置被谁覆盖了。
DHCP租约正在悄悄改写你的DNS
多数虚拟机默认开启DHCP获取IP地址,DHCP服务器除了分配IP,还会顺带下发DNS配置,你的/etc/resolv.conf或者Windows的网卡属性里,可能会在租约刷新时被自动重置。
- Linux环境执行
dhclient -v或者nmcli device show,能看到实际生效的DNS来源。 - Windows环境用
ipconfig /all查看DNS Server字段,对比你手动设置的值是否一致。 - 如果发现被覆盖,最简单的办法是关闭DHCP,改为静态IP配置,或者修改DHCP客户端配置,让它不请求DNS选项。
systemd-resolved在Linux虚拟机里的干扰
近年来Ubuntu、Debian等主流发行版默认启用systemd-resolved服务,它把/etc/resolv.conf变成了指向0.0.53的软链接,这意味着你直接编辑/etc/resolv.conf是无效的,真正生效的是/etc/systemd/resolved.conf里面的配置。
具体操作路径:
# 查看当前resolv.conf指向 ls -l /etc/resolv.conf # 如果指向systemd,编辑resolve配置文件 sudo vim /etc/systemd/resolved.conf # 取消DNS行注释并填写 DNS=223.5.5.5 FallbackDNS=119.29.29.29 # 重启服务 sudo systemctl restart systemd-resolved
验证是否生效,用resolvectl status查看当前DNS,比直接看cat /etc/resolv.conf更准确。
虚拟网络编辑器里的DNS设置被忽略
VMware Workstation有个很容易忽略的坑:虚拟网络编辑器中NAT设置面板里有一个”DNS服务器”输入框,这玩意会影响NAT模式的DNS转发行为,但VMware的NAT服务默认不开启DNS转发,你在虚拟机里配了DNS,如果虚拟机系统通过宿主机转发请求,宿主机又没做DNS中继,那解析自然失败。
VirtualBox的情况不太一样,它的NAT模式默认内置了DNS转发功能,且不允许用户手动改NAT内部的DNS地址,你在VirtualBox的NAT模式下手动指定虚拟机里的DNS为公共DNS,理论上虚拟机系统会直接向外发起DNS查询,表现上是可以用的,但流量实际上并不经过NAT转发,如果你的网络环境封了53端口外部流量,就得改用NAT模式的”名称服务器”选项。
linux虚拟机dns配置的实操路径
既然原理聊清楚了,直接给出一套能落地的步骤,以最常见的Ubuntu Server 22.04和CentOS Stream 9为例子,配合VirtualBox环境说明。
第一步:确定你想要的DNS是什么
先想清楚你的解析路径,个人测试环境建议直接用公共DNS,国内访问速度不错的组合是:
- 阿里DNS:223.5.5.5、223.6.6.6
- 腾讯DNS:119.29.29.29
- 114DNS:114.114.114.114
企业内网环境则需要配置公司内部DNS服务器地址,通常和AD域控绑定,解析内网域名和外部域名走的是不同转发策略。
第二步:修改对应系统的DNS配置文件
Ubuntu 18.04及更早版本,修改/etc/network/interfaces:
auto ens33 iface ens33 inet static address 192.168.56.101 netmask 255.255.255.0 gateway 192.168.56.1 dns-nameservers 223.5.5.5 119.29.29.29
Ubuntu 20.04及以后版本,用netplan工具:
sudo vim /etc/netplan/00-installer-config.yaml
network:
ethernets:
ens33:
dhcp4: no
addresses: [192.168.56.101/24]
routes:
- to: default
via: 192.168.56.1
nameservers:
addresses: [223.5.5.5, 119.29.29.29]
version: 2
应用配置:
sudo netplan apply
CentOS / RHEL系列,直接用nmcli命令最省事,比改配置文件更不容易出错:
nmcli con mod ens33 ipv4.dns "223.5.5.5 119.29.29.29" nmcli con mod ens33 ipv4.ignore-auto-dns yes nmcli con up ens33
第三步:重启网络服务让配置生效
改完配置不重启是不行的,不同的系统重启命令不一样,别记混:
# Ubuntu 18.04及以下 sudo systemctl restart networking # Ubuntu 20.04+ sudo netplan apply # CentOS / Rocky Linux sudo systemctl restart NetworkManager # 通用方案(如果上面都失效) sudo reboot
虚拟机dns怎么设置才不会被宿主机拖后腿
很多人在VMware里配置虚拟机DNS后正常,换到KVM环境就出问题,这不是配置命令的问题,而是虚拟化平台对DNS转发的处理机制不同。
KVM虚拟机走NAT网络的DNS特殊姿势
KVM默认的NAT网络(virbr0)用的是dnsmasq做DHCP和DNS转发,dnsmasq会读取宿主机的/etc/resolv.conf作为上游DNS,然后通过168.122.1这个地址给虚拟机提供解析服务。
虚拟机里的DNS设置为192.168.122.1,解析请求才会交给宿主机的dnsmasq处理,如果你在虚拟机里直接填写8.8.8.8,请求会绕过dnsmasq直连外网,取决于你的物理网络是否允许转发53端口流量。
dnsmasq的坑在于它对上游DNS的读取时机,如果你在宿主机换了DNS,必须重启libvirt服务或者dnsmasq进程,虚拟机里的配置不更新,重启命令是systemctl restart libvirtd,这不算什么冷门知识,但实际踩坑的人不少。
Windows虚拟机怎么配置DNS
Windows虚拟机的操作路径比Linux直观一些,但不代表不会出错:
- 打开控制面板 -> 网络和共享中心 -> 更改适配器设置
- 右键当前网卡 -> 属性 -> 双击”Internet协议版本4 (TCP/IPv4)”
- 选择”使用下面的DNS服务器地址”,填入你的DNS
- 确认”高级”选项卡里没有追加多余的DNS后缀
Windows一个隐藏坑是多个网卡同时启用时DNS解析顺序不确定,虚拟机里如果既有NAT网卡又有Host-Only网卡,Windows会按接口跃点数决定走哪个DNS,设置前需要检查路由表,用route print命令查看,确认默认路由指向了你期望的网卡。
配置后怎么测试DNS服务器是否真的生效
配置完不能只看cat /etc/resolv.conf显示的地址对不对,那只是配置文件,不是实际生效结果。
# 用dig命令查看实际查询路径(Linux) dig @223.5.5.5 www.example.com # 不指定DNS服务器,看系统默认从哪个服务器解析 dig www.example.com # Windows环境用nslookup nslookup www.example.com
输出结果里重点看SERVER:那一行,如果显示的是你配置的DNS地址,说明配置生效,如果显示的是127.0.0.53或者某个你不认识的IP,说明系统里还有其他东西在接管解析。
更进一步测试DNS服务器本身的可用性:
# 测试DNS响应延迟 dig @223.5.5.5 www.example.com | grep "Query time" # 测试TCP端口连通性(有些防火墙封UDP 53但不封TCP 53) nc -zv 223.5.5.5 53
Q&A:虚拟机DNS配置高频问题
问:虚拟机改了resolv.conf但一重启就变回原来的内容,怎么处理?
答:先查系统是否有dhclient、NetworkManager、systemd-resolved这些服务在运行,它们会在启动时重新生成resolv.conf,覆盖手动修改的内容,解决方法是在对应服务的配置文件里修改,而不是直接改resolv.conf这个被管理的文件,编辑完使用chattr +i /etc/resolv.conf锁定文件也是一种办法,但遇到NetworkManager的dhcp客户端时不一定有效。
问:虚拟机可以ping通IP地址但ping不通域名,是DNS配置的问题吗?
答:是的,这基本可以确认是DNS解析故障,先测试ping 223.5.5.5看网络连通性,如果通,再测试nslookup baidu.com看解析输出是否正常,常见原因是配置的DNS服务器地址不可达,或者防火墙屏蔽了53端口流量。
问:vmware虚拟机里桥接模式和NAT模式的DNS配置一样吗?
答:不一样,桥接模式要求虚拟机使用物理局域网里的DNS服务器地址,通常和宿主机获取的DNS相同,如果填了外部DNS可能被局域网防火墙拦截,NAT模式则建议填写虚拟网络编辑器里设置的NAT网段网关地址,由宿主机做DNS转发,直连外部DNS不一定能通。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/771686.html


