内容简介
Libvirt 是一个免费的开源软件,它提供 API 来管理虚拟机的各个方面。在 Linux 上,它通常与 KVM 和 Qemu 结合使用。其中,libvirt 用于创建和管理虚拟网络。使用 libvirt 时创建的默认网络称为“默认”,并使用 NAT(网络地址转换)和数据包转发将仿真系统与“外部”世界(主机系统和互联网)连接起来。在本教程中,我们将了解如何使用桥接网络创建不同的设置。
在本教程中,你将学习:
- 如何创建虚拟网桥
- 如何将物理接口添加到网桥
- 如何使网桥配置持久化
- 如何修改固件规则以允许流量流向虚拟机
- 如何创建新的虚拟网络并在虚拟机中使用它
使用的软件要求和约定
类别 | 要求、约定或使用的软件版本 |
---|---|
系统 | 分配独立 |
软件 | libvirt, iproute, brctl |
其他 | 创建和操作桥接口的管理权限 |
惯例 | # – 要求以 root 权限直接以 root 用户或使用 sudo 命令执行给定的 linux 命令, $ – 要求以普通非特权用户身份执行给定的 linux 命令 |
默认网络
当使用 libvirt 并且运行 libvirtd 守护进程时,会创建一个默认网络。我们可以使用 virsh 实用程序验证该网络是否存在,在大多数 Linux 发行版中,该实用程序通常都带有 libvirt-client 软件包。要调用该实用程序以便它显示所有可用的虚拟网络,我们应该包括 net-list
子命令:
$ sudo virsh net-list --all
在上面的示例中,我们使用了 --all
选项来确保非活动网络也包含在结果中,这通常应该对应于下面显示的网络:
复制Name State Autostart Persistent
--------------------------------------------
default active yes yes
要获取有关网络的详细信息并最终修改它,我们可以使用 edit
子命令调用 virsh,提供网络名称作为参数:
$ sudo virsh net-edit default
使用你常用的文本编辑器打开 xml 网络定义的临时文件:
复制 <name>default</name>
<uuid>168f6909-715c-4333-a34b-f74584d26328</uuid>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:48:3f:0c'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
如我们所见,默认网络基于 virbr0 虚拟网桥的使用,并使用基于 NAT 的连接将作为网络一部分的虚拟机连接到外部世界。我们可以使用 ip
命令验证网桥是否存在:
$ ip link show type bridge
在我们的例子中,上面的命令返回以下输出:
复制5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:48:3f:0c brd ff:ff:ff:ff:ff:ff
要显示属于网桥一部分的接口,我们可以使用 ip
命令并仅查询以 virbr0 网桥为主的接口:
$ ip link show master virbr0
运行命令结果:
复制6: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:48:3f:0c brd ff:ff:ff:ff:ff:ff
我们可以看到, 目前只有一个接口连接到网桥上, 即 virbr0-nic。virbr0-nic 接口是一个虚拟以太网接口: 它被自动创建并加入到网桥中, 其目的只是为网桥提供一个稳定的 MAC 地址 (本例中为 52:54:00:48:3f:0c) 。
当我们创建和启动虚拟机时,其他虚拟接口将被添加到网桥中。在本教程中,我创建并启动了一个 Debian (Buster) 虚拟机;如果我们重新启动上面用来显示网桥从属接口的命令,我们可以看到添加了一个新的接口,vnet0:
复制$ ip link show master virbr0
6: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:48:3f:0c brd ff:ff:ff:ff:ff:ff
7: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master virbr0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fe:54:00:e2:fe:7b brd ff:ff:ff:ff:ff:ff
任何物理接口都不应该添加到 virbr0 网桥,因为它使用 NAT 来提供连接。
为虚拟机使用桥接网络
在创建虚拟机时,默认网络提供了一种非常直接的方式来实现连接:一切都 "准备就绪",开箱即用。然而,有时候,我们想实现完全的桥接连接,即客户设备连接到主机局域网,而不使用NAT,我们应该创建一个新的网桥,共享主机的一个物理以太网接口。让我们来看看如何一步一步地做到这一点。
创建一个新网桥
要创建新网桥,我们仍然可以使用 ip 命令。假设我们要将这座桥命名为 br0;我们将运行以下命令:
$ sudo ip link add br0 type bridge
使用以下命令验证网桥是否已创建 :
复制$ sudo ip link show type bridge
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:48:3f:0c brd ff:ff:ff:ff:ff:ff
8: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 26:d2:80:7c:55:dd brd ff:ff:ff:ff:ff:ff
正如预期,新网桥 br0 已创建,现在包含在上面命令的输出中。现在新网桥已创建,我们可以继续并向其添加物理接口。
向网桥添加物理以太网接口
在这一步,我们将向网桥添加一个主机物理接口。注意,在这种情况下,你不能使用你的主以太网接口,因为一旦它被添加到网桥,你就会失去连接,因为它将失去它的 IP 地址。在这种情况下,我们将使用一个额外的接口,enp0s29u1u1:这是一个由连接在我的机器上的以太网转USB适配器提供的接口。
首先我们确保接口状态为 UP:
$ sudo ip link set enp0s29u1u1 up
将接口添加到网桥:
$ sudo ip link set enp0s29u1u1 master br0
验证接口是否已添加到网桥:
复制$ sudo ip link show master br0
3: enp0s29u1u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP mode DEFAULT group default qlen 1000
link/ether 18:a6:f7:0e:06:64 brd ff:ff:ff:ff:ff:ff
为网桥分配静态 IP 地址
此时我们可以为网桥分配一个静态IP地址。假设我们要使用 192.168.0.90/24;需要运行以下命令:
$ sudo ip address add dev br0 192.168.0.90/24
为验证地址是否已添加到界面:
复制$ ip addr show br0
9: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 26:d2:80:7c:55:dd brd ff:ff:ff:ff:ff:ff
inet 192.168.0.90/24 scope global br0
valid_lft forever preferred_lft forever
[...]
使配置持久化
我们的桥接配置已经准备好了,但是,就目前的情况来看,它在机器重启后将无法继续存在。为了使我们的配置持久化,我们必须编辑一些配置文件,这取决于我们使用的发行版。
Debian系列发行版
在 Debian 系列发行版中,我们必须确保安装了 bridge-utils 软件包:
$ sudo apt-get install bridge-utils
一旦软件包安装完毕,我们应该修改/etc/network/interfaces
文件的内容:
复制# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# Specify that the physical interface that should be connected to the bridge
# should be configured manually, to avoid conflicts with NetworkManager
iface enp0s29u1u1 inet manual
# The br0 bridge settings
auto br0
iface br0 inet static
bridge_ports enp0s29u1u1
address 192.168.0.90
broadcast 192.168.0.255
netmask 255.255.255.0
gateway 192.168.0.1
Red Hat 系列发行版
在 Red Hat 系列发行版上,包括 Fedora,我们必须在 /etc/sysconfig/network-scripts
目录下操作网络脚本。如果我们希望网桥不被 NetworkManager 管理,或者我们使用的是旧的发行版,其 NetworkManager 的旧版本不能够管理网络交换机,我们需要安装 network-scripts 包:
$ sudo dnf install network-scripts
一旦软件包安装完毕,我们需要创建配置br0桥的文件: /etc/sysconfig/network-scripts/ifcfg-br0
在该文件中,写入以下内容:
复制DEVICE=br0
TYPE=Bridge
BOOTPROTO=none
IPADDR=192.168.0.90
GATEWAY=192.168.0.1
NETMASK=255.255.255.0
ONBOOT=yes
DELAY=0
NM_CONTROLLED=0
然后,我们修改或创建用于配置我们将连接到网桥的物理接口的文件,在本例中为 /etc/sysconfig/network-scripts/ifcfg-enp0s29u1u1
:
复制TYPE=ethernet
BOOTPROTO=none
NAME=enp0s29u1u1
DEVICE=enp0s29u1u1
ONBOOT=yes
BRIDGE=br0
DELAY=0
NM_CONTROLLED=0
准备好配置后,我们可以启动网络服务,并在启动时启用它:
$ sudo systemctl enable --now network
为网桥禁用 netfilter
为了允许所有的流量被转发到网桥,并因此转发到连接到网桥的虚拟机上, 我们需要禁用 netfilter。这是必要的, 例如, 为了让连接到网桥的客户机能够进行 DNS 解析。要做到这一点, 我们可以在 /etc/sysctl.d
目录中创建一个扩展名为 .conf 的文件, 我们称之为 99-netfilter-bridge.conf。在这个文件中,我们写入以下内容:
复制net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
要加载文件中写入的设置,首先确保加载了 br_netfilter
模块:
$ sudo modprobe br_netfilter
为了在启动时自动加载模块,创建/etc/modules-load.d/br_netfilter.conf
文件:它应该只包含模块本身的名称:
br_netfilter
一旦模块加载完毕,为了加载我们存储在99-netfilter-bridge.conf文件中的设置,运行:
$ sudo sysctl -p /etc/sysctl.d/99-netfilter-bridge.conf
建立一个新的虚拟网
在这一点上,我们应该定义一个新的 "网络",供我们的虚拟机使用。我们用我们喜欢的编辑器打开一个文件,在里面粘贴以下内容,然后把它保存为bridged-network.xml:
复制<network>
<name>bridged-network</name>
<forward mode="bridge" />
<bridge name="br0" />
</network>
文件准备好后,我们将其位置作为参数传递给 net-define virsh
子命令:
$ sudo virsh net-define bridged-network.xml
激活新网络并使其自动启动:
复制$ sudo virsh net-start bridged-network
$ sudo virsh net-autostart bridged-network
运行virsh net-list
命令,再次验证网络是否已经激活:
复制$ sudo virsh net-list
Name State Autostart Persistent
----------------------------------------------------
bridged-network active yes yes
default active yes yes
使用--network
选项时按名称选择网络:
复制$ sudo virt-install \
--vcpus=1 \
--memory=1024 \
--cdrom=debian-10.8.0-amd64-DVD-1.iso \
--disk size=7 \
--os-variant=debian10 \
--network network=bridged-network
如果使用virt-manager图形界面,我们将能够在创建新虚拟机时选择网络:
结论
在本教程中,我们看到了如何在Linux上创建一个虚拟网桥,并将一个物理以太网接口连接到它,以创建一个新的 "网络",用于libvirt管理的虚拟机。当使用后者时,为了方便,提供了一个默认的网络:它通过使用NAT提供连接。使用这种配置的桥接网络时,可以提升性能,并使虚拟机成为主机的同一子网的一部分。
原文地址:https://linuxconfig.org/how-to-use-bridged-networking-with-libvirt-and-kvm
原文标题:《How to use bridged networking with libvirt and KVM》
原文作者:Egidio Docile
评论