搞虚拟机最让人头疼的问题之一,就是网络。我刚开始用KVM那会儿,默认的网络配置是NAT,虚拟机虽然能上网,但是别人从外面连不进来,想开放一个服务还要在宿主机上做端口映射,机器一多,映射关系写在纸上的都有。后来把Bridge Networking这块研究明白,才觉得把KVM真正打通了。这篇文章就来完整复盘一遍“Create and Configure Bridge Networking For KVM in Linux”这件事:什么是Linux bridge、为什么需要它、怎么从零搭建、怎么让KVM虚拟机接入、出问题了怎么排查。不管你是刚接触KVM的新手,还是在帮公司搭虚拟化环境的老手,文章里的操作方法和思路都能直接用上。
1. 先搞清楚:桥接网络到底解决了什么问题
1.1 默认KVM的NAT网络,坑在哪里
装好KVM之后,libvirt默认会创建一张虚拟网卡叫virbr0,同时生成一个virtual network叫default,默认网段一般是192.168.122.0/24。虚拟机创建的时候,选“NAT”或者“Virtual network default”,拿到的就是从这张虚拟网络分配出来的IP。这套方案用的是Linux内核的iptables NAT功能:虚拟机出网的包,源地址会被伪装成宿主机的IP。
NAT方案最让人抓狂的地方,是被访问能力太弱。你在虚拟机里起了一个web服务,想给局域网同事试用,就得在宿主机上配端口转发,比如把宿主机的8080端口转发到虚拟机的80端口,而且每个要对外开放的服务都得单独转一次。虚拟机少的时候,记在文档里还能忍;虚拟机一多,经常是昨天还能访问的服务,今天不知道哪条iptables规则被覆盖了,排查到怀疑人生。
另外,NAT下的虚拟机没法直接和局域网里的物理机通信。虽然有些场景可以靠端口转发绕过去,但一旦涉及广播、组播、混杂模式这类应用——比如做软路由测试、抓广播包、跑集群的组播心跳——NAT基本上就废了。这也是为什么很多人在认真部署KVM之前,第一件事就是先把桥接网络搞定。
1.2 Linux bridge:把内核变成一台交换机
理解Linux bridge最直接的方式,就是把它看作一台虚拟交换机。你可以在任意一台Linux机器上,把内核里的一部分网络功能抽出来,当作一台二层交换机来用。物理网卡、虚拟机的虚拟网卡,都是这台交换机上的接入端口,它们处在同一个广播域里,直接通过ARP广播就能找到对方。
桥接之后,整个链路是这样一个结构:
text复制虚拟机(eth0) -> vnet0 -> br0 <- eth0 <- 局域网交换机 <- 其他机器
br0这个逻辑接口,承担了宿主机自己的网络身份,IP、MAC、路由表都在它上面。物理网卡eth0不再是独立的网络接口,它变成了br0的一个member端口,本身不配IP,只管收发二层帧。这个过程官方文档里叫enslave,把物理网卡拉进网桥做从属。
这个机制的好处主要有三个。第一,虚拟机可以获得局域网DHCP分配的IP,或者手动配置一个和宿主机同网段的IP,从外部网络看就是一台独立的物理机。第二,不需要端口转发,SSH、HTTP、数据库、SMB这些服务全都走正常流程,该通的协议都可以通。第三,二层畅通,广播包、组播包都能正常收发,很多依赖二层的服务终于能跑了。
1.3 什么时候用桥接,什么时候用NAT
我实际项目里的选择逻辑很简单,按下面这张表判断:
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 虚拟机只需要上外网、不需要被外部访问 | NAT | 配置最简单,隔离性最好 |
| 虚拟机要对外提供Web/SSH/API服务 | 桥接 | 免端口转发,直接局域网可达 |
| 多台宿主机做虚拟化集群 | 桥接 | 跨宿主机需要二层互通 |
| 内网已有DHCP/DNS/域控 | 桥接 | 虚拟机直接入网,纳入统一管理 |
| 学习练手、快速测试 | NAT | 不容易把宿主机网络搞挂 |
注意:桥接和NAT不是二选一。一台宿主机可以同时有br0(桥接)和virbr0(NAT)两个虚拟网络,不同虚拟机按业务需求接入不同的桥。网桥之间默认不互相转发,隔离上也比较放心。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动手前准备:环境检查与网络规划
2.1 检查内核模块和依赖工具
Linux bridge功能在内核里,绝大多数发行版默认已经加载,但为确保万无一失,先跑几个命令看一眼状态:
bash复制lsmod | grep bridge
lsmod | grep br_netfilter
ip link add test_bridge type bridge && ip link del test_bridge
第一条检查bridge模块,第二条检查br_netfilter,第三条是临时创建一个bridge再删掉,用来验证内核是否真正支持创建操作。
如果模块没加载,手动加载一下:
bash复制sudo modprobe bridge
sudo modprobe br_netfilter
br_netfilter这个模块很容易被忽视,它的作用是让iptables规则能作用于桥接流量。没有它,桥接流量默认绕过了iptables的FORWARD链,在某些版本和配置组合下,虚拟机之间连不上,或者宿主机上的Docker也会出问题。所以我的习惯是装完KVM后先把这两个模块都确认一遍。
2.2 安装网络管理工具
桥接管理工具的选择主要看发行版和个人习惯,我用的组合大概是这样的:
- Debian/Ubuntu经典方式:bridge-utils(提供brctl命令),配合ifupdown(/etc/network/interfaces)
- Ubuntu新版本:netplan.io,用YAML配置,内部调networkd或者NetworkManager
- CentOS/RHEL/Fed
