kvm默认的default网络是nat模式,由virbr0虚拟网桥(ip 192.168.122.1/24)联合dnsmasq和iptables snat规则实现,不绑定物理网卡,仅需virsh net-start default即可让虚拟机共享宿主机上网。

直接说结论:KVM 默认的 default 网络就是 NAT 模式,只要不手动删、不改配置、虚拟机启动时指定它,就能共享宿主机上网——不需要额外建桥、不用动物理网卡 IP。
为什么 virbr0 就是 NAT,不是桥接
libvirt 安装后自动创建 default 网络,对应虚拟网桥 virbr0,IP 是 192.168.122.1/24。它不是传统意义的 Linux 网桥(不绑定物理口),而是配合 dnsmasq + iptables SNAT 实现的用户态 NAT 网关。
- 查证方式:
brctl show输出里virbr0下没有ens33这类物理接口名 - 它的流量路径是:虚拟机 →
vnet0→virbr0→iptables -t nat -A POSTROUTING→ 宿主机物理出口 - 误把它当桥接加物理口(
brctl addif virbr0 ens33)会报Device or resource busy,甚至导致宿主机 SSH 断连
virsh net-start default 启不起来怎么办
常见原因是 dnsmasq 冲突或 iptables 规则残留。不要直接 systemctl restart libvirtd,先定位:
- 检查服务状态:
systemctl status libvirtd和systemctl status dnsmasq - 看日志:
journalctl -u libvirtd -n 50 --no-pager | grep -i "nat\|dnsmasq\|virbr0" - 手动启网:
virsh net-start default,失败时通常提示端口被占(比如另一个 dnsmasq 在跑) - 临时释放:
sudo pkill dnsmasq && sudo systemctl restart libvirtd
虚拟机启动时怎么指定用 NAT 网络
关键在 XML 配置里的 <interface></interface> 段,必须显式引用 default 网络名,不能只写 bridge='virbr0'(那是桥接写法):
<interface type="network"><source network="default"></source><model type="virtio"></model></interface>
- 如果用
virt-install创建:加参数--network network=default - 如果用
virsh edit vmname修改:确认<source network="default"></source>存在且没被注释 - 改完别忘了
virsh define /path/to/xml或重启虚拟机,否则不生效
能上网但 ping 不通宿主机?重点查防火墙和 ARP
默认情况下,virbr0 上的虚拟机可以访问外网、也能 ping 宿主机 IP(如 192.168.122.1),但如果宿主机 ping 虚拟机不通,大概率是这两个点:
- 宿主机防火墙拦截了入向 ICMP:
sudo iptables -L INPUT -n | grep 192.168.122,若看到 DROP 规则,临时放开:sudo iptables -I INPUT 1 -s 192.168.122.0/24 -j ACCEPT - 虚拟机没发过包,宿主机 ARP 表里没有它的 MAC:
arp -n | grep 192.168.122,可让虚拟机先ping一下宿主机,再试反向 - 注意:宿主机上
firewalld若启用,virbr0默认属于trustedzone,但某些发行版(如 RHEL 9+)可能默认禁用该 zone 的 ICMP,需手动加规则
真正容易被忽略的是:NAT 模式下,虚拟机对外暴露的是宿主机 IP,所以从外网无法直连虚拟机——这不是配置错误,是 NAT 本身的设计限制。要外网访问,得在宿主机上配端口转发(iptables -t nat -A PREROUTING)或换桥接模式。











