第一时间捕获有价值的信号
本文深入解析 KVM 虚拟化中的四种网络模式,重点对比 NAT 与桥接模式。详细介绍如何在 Ubuntu 系统下配置 Linux 网桥,实现 KVM 虚拟机与外部网络的顺畅通信。
核心内容
本文将会讲述如何在 Ubuntu 16.04 LTS 系统下基于现有的以太网接口配置 Linux 网桥. 当我们在创建虚拟化环境(比如说LXC, KVM ,Xen等)的时候,都需要配置网桥,让宿主机里的虚拟机通过配好的网桥接口和外部通信。
Linux 网络端口命名规则
在进行虚拟网络探究之前,对网络硬件设备命名做一个简单的归纳,有助于后面理解,Linux 系统的网卡命名原来是 eth0,eth1 这样的形式,但是这个编号往往不一定能准确的对应网卡接口的物理顺序,为解决这类问题,dell 开发了 biosdevname 方案。 根据接口类型以两个字母开头:
- en 代表以太网
- eno1:代表由主板bios内置的网卡
- ens1:代表有主板bios内置的PCI-E网卡
- enp2s0: PCI-E独立网卡
- eth0:如果以上都不使用,则回到默认的网卡名
- wl 代表无线局域网( WLAN)
- ww 代表无线广域网( WWAN)
四种网络模式
- 隔离模式:虚拟机之间组建网络,该模式无法与宿主机通信,无法与其他网络通信,相当于虚拟机只是连接到一台交换机上。
- 路由模式:相当于虚拟机连接到一台路由器上,由路由器(物理网卡),统一转发,但是不会改变源地址。
- NAT 模式:在路由模式中,会出现虚拟机可以访问其他主机,但是其他主机的报文无法到达虚拟机,而 NAT 模式则将源地址转换为路由器(物理网卡)地址,这样其他主机也知道报文来自那个主机,在 docker 环境中经常被使用。
- 桥接模式:在宿主机中创建一张虚拟网卡作为宿主机的网卡,而物理网卡则作为交换机。
NAT模式
- 虚拟机启动后会生成一个 vnet0 网络设备,KVM 虚拟机启动后,vnet0 默认桥接到了 virbr0 上,关闭后消失。此时的 KVM 虚拟机出去的流量是桥接到 virbr0 上,然后经过宿主机的 iptables 的 nat,再经过 enp4s0 出去。这有网络瓶颈,因为依靠 iptables,如果把 iptables 关闭无法上网了,同时 ip 地址是地址池中分配的内网地址。查看:
iptables -t nat -vnL - KVM 虚拟机获取的地址来源于下面
ps aux | grep dns # DNS服务
cat /var/lib/libvirt/dnsmasq/default.conf # #DNS配置文件
- NAT 模式是 KVM 默认的网络模式, KVM 会创建一个名为 virbr0 的虚拟网桥,但是宿主机和虚拟机对于网桥来说不是平等的了,网桥会把虚拟机藏在背后,从外网访问不到虚拟机。

桥接模式
在桥接模式下,宿主机和虚拟机共享同一个物理网络设备,虚拟机中的网卡和物理机中的网卡是平行关系,所以虚拟机可以直接接入外部网络,虚拟机和宿主机有平级的 ip 。
原本宿主机是通过网卡 eth0 连接外部网络的,网桥模式会新创建一个网桥 br0,接管 eth0 来连接外部网络,然后将宿主机和虚拟机的网卡 eth0 都绑定到网桥上。
使用桥接模式需要进行以下操作:
- 创建虚拟网桥 br0
brctl addbr br0
ifconfig br0 up
- 编辑
/etc/network/interfaces,增加如下内容
auto br0
iface br0 inet dhcp # 网桥使用DHCP模式,从DHCP服务器获取IP
bridge_ports enp4s0 # 网卡名称,网桥创建前连接外部的网卡,可通过ifconfig命令查看,有IP地址的就是
bridge_stp on # 避免数据链路出现死循环
bridge_fd 0 # 将转发延迟设置为0
- 重启 networking 服务(如果是通过SSH连接到宿主机上的,这一步会导致网络中断,如果出现问题可能导致连不上宿主机,最好在宿主机上直接操作)
systemctl restart networking
- 修改 KVM 配置文件,对于既存的虚拟机,修改虚拟机的配置文件
virsh edit ubuntuvm1
<interface type='network'>
<mac address='52:54:00:83:f7:a0'/>
<source network='default'/>
...
</interface>
修改配置如下:
<interface type='bridge'>
<mac address='52:54:00:83:f7:a0'/>
<source bridge='br0'/>
...
</interface>
- 使用 ifconfig 命令查看 ip 是否从 enp4s0(网桥创建前的网卡)变到了 br0 上,如果没有变化则需要重启。如果宿主机 ip 已经成功变到网桥上,并且宿主机能正常上网而虚拟机获取不到 ip,可能是 ufw 没有允许 ip 转发导致的,编辑
/etc/default/ufw允许 ip 转发。
DEFAULT_FORWARD_POLICY="ACCEPT"
- 重启ufw服务让设置生效
systemctl restart ufw