KVM 网络基础

KVM(Kernel-based Virtual Machine)网络是指在 KVM 虚拟化环境中,为虚拟机提供的网络连接和通信机制。通过 KVM 网络,虚拟机可以与其他虚拟机、宿主机以及外部网络进行通信。

网络类型描述优点缺点适用场景
NAT 网络虚拟机通过宿主机的网络接口与外部通信,IP 地址被隐藏。配置简单,适合需要外部通信的虚拟机。虚拟机间通信需额外配置,网络性能可能受限。适合不需外部访问但需访问外网的虚拟机。
桥接网络虚拟机直接连接物理网络接口,拥有独立 IP 地址,可直接与其他设备通信。与物理网络无缝集成,适合需外部访问的虚拟机。配置较复杂,需适当配置物理网络接口。适合需要直接对外提供服务的虚拟机。
内部网络仅允许虚拟机之间的通信,不与宿主机或外部网络通信。提供隔离网络,适合测试和开发。虚拟机无法与外部网络通信。适合需要隔离的测试和开发环境。
仅主机网络允许虚拟机与宿主机通信,但不与外部网络通信。简单隔离,适合虚拟机与宿主机通信。虚拟机无法与外部网络通信。适合虚拟机与宿主机需要频繁交互的场景。

KVM 网络安装与准备

可以选择使用任意一款网络管理工具,这里**推荐使用NetworkManager**来管理网络桥接。

安装 NetworkManager

非 Fedora/RHEL 系列,需要手动安装 NetworkManager,并配置 NetworkManager 接管网络。

# Debian/Ubuntu 系列
sudo apt-get update
sudo apt-get install -y network-manager

配置系统网络支持

  1. 启用 NetworkManager

    # 启动并启用 NetworkManager 服务
    sudo systemctl start NetworkManager
    sudo systemctl enable NetworkManager
  2. 创建并配置网络桥接

    使用nmcli工具创建一个新的桥接接口。例如,创建名为br0的桥接接口并将现有的以太网接口(假设为eth0)添加到桥接中。

    sudo nmcli connection add type bridge autoconnect yes con-name br0 ifname br0
    sudo nmcli connection add type bridge-slave autoconnect yes con-name br0-slave ifname eth0 master br0
    sudo nmcli connection modify br0 ipv4.method auto
    sudo nmcli connection up br0
  3. 确认桥接网络配置

    使用以下命令确认桥接网络是否正确配置。

    nmcli connection show
    ip a
  4. 确认内核模块加载情况

    确保KVM相关的内核模块已加载:

    lsmod | grep kvm

示例配置文件

对于NetworkManager的配置文件(一般位于/etc/NetworkManager/system-connections/目录下),你可以手动编辑这些文件进行更复杂的配置。例如,编辑br0的配置文件:

[connection]
id=br0
type=bridge
interface-name=br0
autoconnect=true
 
[ipv4]
method=auto
 
[ipv6]
method=auto

其他注意事项

  1. 防火墙配置:确保你的防火墙规则允许桥接网络的流量。
  2. 验证桥接网络:创建一个虚拟机并将其连接到br0桥接网络,验证网络连接是否正常。

NAT 网络

**KVM 默认会创建一个名为 default 的 NAT 网络。**这个网络通常在安装 libvirt 时自动创建和启用。

  1. 检查并启用默认网络

    检查 default 网络是否已经存在并启用:

    sudo virsh net-list --all

    如果默认网络未启用,可以通过以下命令启用:

    sudo virsh net-start default
    sudo virsh net-autostart default
  2. 查看默认网络配置

    查看默认网络的详细配置:

    sudo virsh net-dumpxml default
    

    典型的默认网络配置如下:

    <network>
      <name>default</name>
      <uuid>……</uuid>
      <forward mode='nat'>
        <nat>
          <port start='1024' end='65535'/>
        </nat>
      </forward>
      <bridge name='virbr0' stp='on' delay='0'/>
      <mac address='52:54:00:d3:9b:fb'/>
      <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>
  3. 创建虚拟机

    创建一台连接到 default 网络的虚拟机。可以使用 virt-install 命令来完成:

    sudo virt-install \
      --name myvm \
      --ram 4096 \
      --disk path=/var/lib/libvirt/images/myvm_storage.qcow2,size=32 \
      --vcpus 2 \
      --os-type linux \
      --os-variant ubuntu20.04 \
      --network network=default \
      --graphics none \
      --console pty,target_type=serial \
      --location 'https://mirrors.tuna.tsinghua.edu.cn/ubuntu/dists/focal/main/installer-amd64/' \
      --extra-args 'console=ttyS0,115200n8 serial'
  4. 验证虚拟机网络连接

    登录到虚拟机,并验证其网络连接:

    ping -c 4 8.8.8.8

    检查虚拟机是否能够获得 IP 地址:

    ip a

virsh 创建自定义 NAT 网络

通过 virsh 命令创建自定义 NAT 网络,并配置 DHCP 和 IP 地址范围。

  1. 创建网络配置文件

    创建一个自定义网络配置文件(如 custom-net.xml):

    <network>
      <name>custom-net</name>
      <forward mode='nat'/>
      <bridge name='virbr1' stp='on' delay='0'/>
      <mac address='52:54:00:12:34:56'/>
      <ip address='192.168.100.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.100.2' end='192.168.100.254'/>
        </dhcp>
      </ip>
    </network>
  2. 定义并启动网络

    使用 virsh 命令定义并启动该网络:

    sudo virsh net-define custom-net.xml
    sudo virsh net-start custom-net
    sudo virsh net-autostart custom-net
  3. 查看自定义网络状态

    确认网络已启用:

    sudo virsh net-list --all

在上面的 custom-net.xml 文件中,已经定义了 DHCP 范围:

<ip address='192.168.100.1' netmask='255.255.255.0'>
  <dhcp>
    <range start='192.168.100.2' end='192.168.100.254'/>
  </dhcp>
</ip>

此配置表示:

  • 网关地址:192.168.100.1
  • DHCP 范围:192.168.100.2 到 192.168.100.254

NetworkManager 创建自定义 NAT 网络

  1. 确保 NetworkManager 已启用

    sudo systemctl enable --now NetworkManager
  2. 创建 NetworkManager 桥接连接

    编辑 NetworkManager 配置文件,创建一个桥接网络(例如 /etc/NetworkManager/system-connections/bridge-br1.nmconnection):

    [connection]
    id=bridge-br1
    type=bridge
    autoconnect=true
     
    [bridge]
    stp=true
     
    [ipv4]
    method=manual
    address1=192.168.100.1/24
     
    [ipv6]
    method=ignore
  3. 重启 NetworkManager 服务

    sudo systemctl restart NetworkManager
  4. 验证桥接网络

    确认新的桥接网络已创建并启用:

    nmcli connection show

桥接网络

使用 NetworkManager 的 nmcli 命令来创建和配置桥接网络接口,并将物理接口绑定到网桥。

  1. 创建桥接接口

    使用 nmcli 命令创建一个新的桥接接口:

    sudo nmcli connection add type bridge ifname br0
  2. 配置桥接接口的 IP 地址

    为桥接接口配置 IP 地址:

    sudo nmcli connection modify br0 ipv4.addresses 192.168.1.100/24 ipv4.method manual
    sudo nmcli connection modify br0 ipv4.gateway 192.168.1.1
    sudo nmcli connection modify br0 ipv4.dns "8.8.8.8,8.8.4.4"
    sudo nmcli connection modify br0 connection.autoconnect yes
  3. 将物理接口绑定到桥接接口

    假设物理接口为 eth0,使用 nmcli 将其绑定到 br0

    sudo nmcli connection add type ethernet ifname eth0 master br0
  4. 启用桥接接口

    启用桥接接口 br0 和物理接口 eth0

    sudo nmcli connection up br0
    sudo nmcli connection up eth0
  5. 编辑虚拟机的 XML 配置文件

    假设虚拟机名称为 testvm,使用以下命令编辑其 XML 配置文件:

    sudo virsh edit testvm
  6. 添加桥接网络接口配置

    <devices> 部分中添加以下内容,将 br0 作为桥接接口:

    <interface type='bridge'>
      <mac address='52:54:00:12:34:56'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
  7. 保存并退出

    保存配置文件并退出编辑器。

  8. 重启虚拟机

    重启虚拟机使新的网络配置生效:

    sudo virsh shutdown testvm
    sudo virsh start testvm

内部网络

内部网络允许虚拟机之间进行通信,而无需通过外部网络。这种网络模式适用于需要隔离的测试环境或需要内部通信的应用。

  1. 创建内部网络 XML 配置文件

    首先,创建一个 XML 文件(如 internal-net.xml),定义内部网络的配置:

    <network>
      <name>internal-net</name>
      <forward mode='none'/>
      <bridge name='virbr1' stp='on' delay='0'/>
      <ip address='192.168.200.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.200.2' end='192.168.200.254'/>
        </dhcp>
      </ip>
    </network>

在上面的 XML 文件中,已定义网络名称为 internal-net,IP 地址范围为 192.168.200.2192.168.200.254

  1. 定义并启动网络

    使用 virsh 命令定义并启动内部网络:

    sudo virsh net-define internal-net.xml
    sudo virsh net-start internal-net
    sudo virsh net-autostart internal-net
  2. 编辑虚拟机的 XML 配置文件:

    sudo virsh edit <vm_name>
    
  3. <devices>部分中添加以下内容,将 internal-net作为网络接口:

    <interface type='network'>
        <mac address='52:54:00:12:34:56'/>
        <source network='internal-net'/>
        <model type='virtio'/>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
  4. 保存并退出编辑器。

  5. 重启虚拟机使新的网络配置生效:

    sudo virsh shutdown <vm_name>
    sudo virsh start <vm_name>

仅主机网络

仅主机网络(Host-only Network)允许虚拟机与宿主机通信,但不允许虚拟机与外部网络通信。这种网络模式适用于需要虚拟机与宿主机进行隔离通信的场景。

  1. 创建仅主机网络 XML 配置文件

    创建一个 XML 文件(如 host-only-net.xml),定义仅主机网络的配置:

    <network>
      <name>host-only-net</name>
      <forward mode='none'/>
      <bridge name='virbr2' stp='on' delay='0'/>
      <ip address='192.168.150.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.150.2' end='192.168.150.254'/>
        </dhcp>
      </ip>
    </network>

    在上面的 XML 文件中,已定义网络名称为 host-only-net,IP 地址范围为 192.168.150.2192.168.150.254

  2. 定义并启动网络

    使用 virsh 命令定义并启动仅主机网络:

    sudo virsh net-define host-only-net.xml
    sudo virsh net-start host-only-net
    sudo virsh net-autostart host-only-net
  3. 编辑虚拟机的 XML 配置文件:

    sudo virsh edit <vm_name>
  4. <devices>部分中添加以下内容,将 host-only-net 作为网络接口:

    <interface type='network'>
      <mac address='52:54:00:12:34:56'/>
      <source network='host-only-net'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
  5. 保存并退出编辑器。

  6. 重启虚拟机使新的网络配置生效:

    sudo virsh shutdown <vm_name>
    sudo virsh start <vm_name>

高级网络功能

VLAN 配置

使用 NetworkManager 和 nmcli 命令创建 VLAN 网络。

  1. 创建 VLAN 接口

    假设物理接口为 eth0,VLAN ID 为 100,VLAN 接口命名为 eth0.100

    sudo nmcli connection add type vlan con-name vlan100 dev eth0 id 100
  2. 配置 VLAN 接口 IP 地址

    为 VLAN 接口配置 IP 地址:

    sudo nmcli connection modify vlan100 ipv4.addresses 192.168.100.1/24 ipv4.method manual
    sudo nmcli connection modify vlan100 ipv4.gateway 192.168.100.254
    sudo nmcli connection modify vlan100 ipv4.dns "8.8.8.8,8.8.4.4"
    sudo nmcli connection up vlan100
  3. 使用 virsh 配置 VLAN 网络

    1. 编辑虚拟机的 XML 配置文件:
    sudo virsh edit <vm_name>
    1. <devices>部分中添加以下内容,将 vlan100作为网络接口:
    <interface type='network'>
    <mac address='52:54:00:12:34:56'/>
    <source network='vlan100'/>
    <model type='virtio'/>
    <vlan>
     <tag id='100'/>
    </vlan>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    1. 保存并退出编辑器。

    2. 重启虚拟机使新的网络配置生效:

    sudo virsh shutdown <vm_name>
    sudo virsh start <vm_name>

配置虚拟机的多网卡

  1. 编辑虚拟机的 XML 配置文件:
sudo virsh edit <vm_name>
  1. <devices>部分中添加多个 <interface>元素,每个代表一个网络接口:
<interface type='network'>
  <mac address='52:54:00:12:34:56'/>
  <source network='default'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<interface type='network'>
  <mac address='52:54:00:12:34:57'/>
  <source network='vlan100'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>
  1. 保存并退出编辑器。

  2. 重启虚拟机使新的网络配置生效:

sudo virsh shutdown <vm_name>
sudo virsh start <vm_name>

配置网络带宽限制

  1. 编辑虚拟机的 XML 配置文件:
sudo virsh edit <vm_name>
  1. <interface> 元素中添加 <bandwidth> 元素,设置带宽限制参数,例如:
<interface type='network'>
  <mac address='52:54:00:12:34:56'/>
  <source network='default'/>
  <model type='virtio'/>
  <bandwidth>
    <inbound average='1000' peak='2000' burst='512'/>
    <outbound average='1000' peak='2000' burst='512'/>
  </bandwidth>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

以上配置将网络带宽限制为入站和出站各 1000 Kbps 平均速率,2000 Kbps 峰值速率,512 KB 突发流量。

  1. 保存并退出编辑器。

  2. 重启虚拟机使新的网络配置生效:

sudo virsh shutdown <vm_name>
sudo virsh start <vm_name>
  • 在宿主机和虚拟机上安装 iperf

    sudo apt install iperf3  # Ubuntu
    sudo yum install iperf3  # CentOS/RHEL
  • 在虚拟机上启动 iperf 服务端:

    iperf3 -s
  • 在宿主机上运行 iperf 客户端进行带宽测试:

    iperf3 -c <vm_ip_address>
  • 检查测试结果,验证带宽限制是否生效。

通过以上步骤使用 NetworkManager 和 nmcli 命令配置 VLAN 网络、为虚拟机添加多个网卡,并使用 virsh 配置网络带宽限制。同时,可以通过 iperf 工具验证网络带宽限制的效果。

管理和监控虚拟网络

virsh 命令管理网络

命令描述
virsh net-list --all列出所有虚拟网络
virsh net-info <network>显示虚拟网络的信息
virsh net-dumpxml <network>显示虚拟网络的 XML 配置
virsh net-create <network.xml>创建虚拟网络
virsh net-destroy <network>销毁虚拟网络
virsh net-start <network>启动虚拟网络
virsh net-autostart <network>设置虚拟网络开机自启
virsh net-undefine <network>取消定义虚拟网络
virsh net-edit <network>编辑虚拟网络的 XML 配置
virsh net-update <network> <command> <section> <xml>更新虚拟网络
virsh net-dhcp-leases <network>列出网络的 DHCP 租约

监控网络性能

使用 iftopvnstat 等工具

  1. 安装 iftopvnstat

     # 在 Ubuntu 上
    sudo apt install iftop vnstat
     
    # 在 CentOS/RHEL 上
    sudo yum install iftop vnstat
  2. 使用 iftop 监控实时网络流量

     sudo iftop -i <network_interface>

    iftop 会显示实时的网络流量,包括发送和接收数据的主机 IP 和带宽使用情况。

  3. 使用 vnstat 监控网络流量

    初始化 vnstat数据库:

    sudo vnstat -u -i <network_interface>
    • 查看实时流量:

      sudo vnstat -l
    • 查看流量统计:

      sudo vnstat
    • 查看详细流量统计:

      sudo vnstat -d  # 查看每日流量统计
      sudo vnstat -m  # 查看每月流量统计
      sudo vnstat -t  # 查看每小时流量统计

分析网络流量和性能

  1. 分析流量数据
    • 使用 iftopvnstat 收集的流量数据,可以帮助识别网络瓶颈和高流量的主机。
  2. 优化网络配置
    • 根据监控数据,优化虚拟网络的配置,例如调整网络带宽限制、优化网络拓扑结构等。
  3. 监控网络接口的性能
    • 定期检查和分析网络接口的性能,确保虚拟网络的稳定性和高效运行。

安全配置

配置防火墙规则

使用 iptables 配置防火墙

  1. 安装 iptables

    # 在 CentOS/RHEL 上
    sudo yum install iptables-services
    sudo systemctl enable --now iptables
     
    # 在 Ubuntu 上
    sudo apt install iptables
  2. 配置基本规则

    允许虚拟机网络通信:

    sudo iptables -A FORWARD -i virbr0 -o eth0 -j ACCEPT
    sudo iptables -A FORWARD -i eth0 -o virbr0 -j ACCEPT
  3. 保存规则

    # 在 CentOS/RHEL 上
    sudo service iptables save
     
    # 在 Ubuntu 上
    sudo iptables-save | sudo tee /etc/iptables/rules.v4

配置 firewalld 管理规则

  1. 安装 firewalld

    # 在 CentOS/RHEL 上
    sudo yum install firewalld
    sudo systemctl enable --now firewalld
     
    # 在 Ubuntu 上
    sudo apt install firewalld
    sudo systemctl enable --now firewalld
  2. 配置基本规则

    允许虚拟机网络通信:

    sudo firewall-cmd --zone=public --add-interface=virbr0 --permanent
    sudo firewall-cmd --zone=public --add-masquerade --permanent
    sudo firewall-cmd --reload

网络隔离与访问控制

使用 VLAN 实现网络隔离

  1. 创建 VLAN 接口

    使用 nmcli创建 VLAN 接口:

    sudo nmcli connection add type vlan con-name vlan100 dev eth0 id 100
    sudo nmcli connection modify vlan100 ipv4.addresses 192.168.100.1/24 ipv4.method manual

sudo nmcli connection up vlan100


2. **配置虚拟机使用 VLAN**:

使用 `virt-manager` 或 `virsh` 配置虚拟机连接到 VLAN 网络。

#### 配置虚拟机访问控制列表(ACL)

1. **使用 `virsh` 配置 ACL**:

为虚拟机创建网络 ACL 规则:

```shell
sudo virsh nwfilter-define /etc/libvirt/nwfilter/myfilter.xml

配置 myfilter.xml文件示例:

<filter name='myfilter' chain='ipv4'>
  <uuid>...</uuid>
  <rule action='accept' direction='in' priority='500'>
    <mac address='52:54:00:12:34:56'/>
  </rule>
  <rule action='drop' direction='in' priority='1000'/>
</filter>
  1. 应用 ACL 到虚拟机

    编辑虚拟机的 XML 配置文件,应用网络过滤器:

    <interface type='network'>
      <mac address='52:54:00:12:34:56'/>
      <source network='default'/>
      <model type='virtio'/>
      <filterref filter='myfilter'/>
    </interface>

    重启虚拟机使 ACL 生效。

故障排查

常见网络问题及解决方法

虚拟机无法连接网络

  1. 检查虚拟机的网络配置
    • 确认虚拟机的网络接口配置正确。
    • 使用 virsh dumpxml <vm_name> 命令查看虚拟机的 XML 配置,确保 <interface> 部分配置正确。
  2. 检查虚拟网络状态
    • 使用 virsh net-list --all 命令查看虚拟网络是否启动。
    • 如果虚拟网络未启动,使用 virsh net-start <network_name> 启动虚拟网络。
  3. 检查宿主机的网络配置
    • 确认宿主机的网络接口和桥接配置正确。
    • 使用 nmcli connection show 命令查看 NetworkManager 的连接状态,确保相关接口已连接。
  4. 检查虚拟机的 IP 地址
    • 登录到虚拟机,使用 ip a 命令查看虚拟机的 IP 地址是否正确分配。
    • 如果未分配 IP 地址,检查 DHCP 配置是否正确。

网络性能问题

  1. 检查网络带宽限制
    • 确认是否为虚拟机配置了带宽限制。
    • 使用 virsh edit <vm_name> 命令检查 <bandwidth> 配置。
  2. 检查网络流量
    • 使用 iftopvnstat 等工具监控网络流量,识别高流量主机和瓶颈。
  3. 优化网络配置
    • 调整虚拟机的网络接口配置,例如使用 Virtio 网络驱动以提高性能。
    • 使用桥接网络模式,确保虚拟机与物理网络的高效通信。

日志查看与分析

查看 libvirt 网络日志

  1. libvirt 日志路径
    • 在 CentOS/RHEL 上,libvirt 日志通常位于 /var/log/libvirt/ 目录下。
    • 在 Ubuntu 上,libvirt 日志通常位于 /var/log/libvirt/ 目录下。
  2. 查看网络日志
    • 使用 tail -f /var/log/libvirt/libvirtd.log 命令查看实时日志。
    • 使用 grep 命令筛选关键字以查找特定问题,例如 grep "network" /var/log/libvirt/libvirtd.log

使用系统日志进行排查

  1. 查看系统日志
    • 使用 journalctl 命令查看系统日志,例如 journalctl -u libvirtd 查看 libvirtd 服务的日志。
  2. 检查网络相关日志
    • 使用 dmesg 命令查看内核日志,查找与网络相关的错误信息。