使用 NetworkManager 创建桥接网卡并为 QEMU 模拟器提供网络

桥接器(network bridge),又称网桥,一种网络设备,负责网络桥接(network bridging)。桥接器将网络的多个网段在数据链路层(OSI模型第2层)连接起来(即桥接)。

网桥本质上就是一个二层(Layer 2)交换机的虚拟实现,根据 MAC 地址 来转发帧。它不会修改 IP 包,也不关心 IP 层的东西。

当你把多个网络接口(如物理网卡、虚拟 tap 接口等)“加入”到同一个 bridge 中时,它们就像都插在同一个交换机上

使用 NetworkManager 创建一个网桥

来自 Arch Linux Wiki 的 Warning:如果您在远程服务器上创建桥接,并计划将主网络接口添加到桥接中,请确保首先在桥接中添加主网络接口的 IP 地址,设置桥接,并设置一个备份默认路由,然后再将接口添加到桥接中。否则服务器将失去网络连接,您将无法通过 SSH 重新连接到它。

不想手动添加路由的笨方法:如果操作的是物理机,可以使用 USB 网卡或无线网卡连接到网络后通过新网卡的地址SSH连接,直接接显示器操作也行。如果操作的是云平台上的虚拟机,可以使用 noVNC 或者 SPICE 连接进控制台后进行操作。

本次演示使用双网口设备,管理口(不需要特别配置,可以是静态地址也可以是DHCP下发)和业务口(桥接)。

  1. 两个网口接入网线后检查连接状态,本次示例中 ens160 为管理口 ens224为业务口

    [icess@localhost ~]$ nmcli device status
    DEVICE  TYPE      STATE                   CONNECTION 
    ens160  ethernet  connected               ens160     
    ens224  ethernet  connected               ens224     
    lo      loopback  connected (externally)  lo
  2. 创建桥接网卡 br0 并设置IPv4 和 IPv6 地址获取方式设置为自动 (DHCP)

    [icess@localhost ~]$ sudo nmcli connection add type bridge ifname br0 con-name br0
       Connection 'br0' (5cb0cb5a-6f9a-4d00-8175-7b5be5f3b51c) successfully added.
       [icess@localhost ~]$ sudo nmcli connection modify br0 ipv4.method auto ipv6.method auto
  3. 将物理网卡 ens224 添加为 br0 网桥的从属接口

    [icess@localhost ~]$ sudo nmcli connection add type ethernet ifname ens224 con-name bridge-slave-ens224 master br0
    Connection 'bridge-slave-ens224' (2fea5b08-544d-447b-b5a4-d39722a15695) successfully added.
  4. 开启从属接口和桥接网卡

    [icess@localhost ~]$ sudo nmcli connection up bridge-slave-ens224
    Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5)
    [icess@localhost ~]$ sudo nmcli connection up br0
    Connection successfully activated (controller waiting for ports) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)
  5. 继续检查连接状态

    [icess@localhost ~]$ nmcli device status
    DEVICE  TYPE      STATE                                  CONNECTION          
    ens160  ethernet  connected                              ens160              
    ens224  ethernet  connected                              bridge-slave-ens224 
    br0     bridge    connecting (getting IP configuration)  br0                 
    lo      loopback  connected (externally)                 lo                 
    
    # 使用 watch 命令查看
    [icess@localhost ~]$ watch nmcli device status
    
    # br0 的连接状态变为connected
    [icess@localhost ~]$ nmcli device status
    DEVICE  TYPE      STATE                   CONNECTION          
    ens160  ethernet  connected               ens160              
    br0     bridge    connected               br0                 
    ens224  ethernet  connected               bridge-slave-ens224 
    lo      loopback  connected (externally)  lo                  
    
    # 此时br0已经获取到 ip 地址
    [icess@localhost ~]$ ip addr show br0
    4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether 00:0c:29:6b:10:28 brd ff:ff:ff:ff:ff:ff
        inet 192.168.42.129/24 brd 192.168.42.255 scope global dynamic noprefixroute br0
           valid_lft 1497sec preferred_lft 1497sec
        inet6 fe80::dc5e:8c1b:2fe6:c6cd/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever

在 Qemu/KVM 虚拟机中使用桥接网卡

qemu-system-* 命令启动虚拟机

测试中使用 cirros-0.6.2-x86_64-disk.img 镜像,指定网卡 Intel e1000 并配置 桥接网络到 br0

[icess@localhost ~]$sudo qemu-system-x86_64 -drive file=./cirros-0.6.2-x86_64-disk.img -netdev bridge,br=br0,id=mynet0 -device e1000,netdev=mynet0

libvirt xml配置

主要修改 interface 标签

<!-- 剩余配置 -->

<!-- 桥接网卡,mac地址随便填 -->
<interface type='bridge'>
  <mac address='52:54:00:aa:bb:cc'/>
  <source bridge='br0'/>
  <model type='pcnet'/>
</interface>

<!-- 剩余配置 -->