LabHub
学习 学习路径 课程

虚拟化与 QEMU/KVM

虚拟机网络的四种模式

在 LabHub 中继续学习

一句话总结

VM 网络模式的选择取决于由谁处理数据包:用户空间(SLIRP)、内核(TAP)、内核网桥,以及内核中的 virtio 处理(vhost-net)。

概念图: 由谁处理数据包 · 用户空间完整实现 TCP/IP 协议栈 · 完全不需要特权。 · 外部无法直接连接客户机。

为什么需要了解这些

“VM 能访问互联网,但外部无法连接 VM。”这类问题几乎总是由 user(SLIRP)模式引起。它常被用作开发环境的默认值,如果不了解其特性,就可能原样带入生产环境。

工作原理

user(SLIRP)

QEMU 在用户空间完整实现 TCP/IP 协议栈。QEMU 解析客户机发出的数据包,再将其转换为宿主机上的普通套接字流量发送出去。

tap

在内核中创建虚拟以太网设备,由 QEMU 持有其中一端。由于数据包会直接进入内核网络栈,从宿主机看,它就像一个真实接口。但创建 TAP 设备需要特权,或者需要对预先创建的设备拥有权限。

bridge

将 TAP 接入 Linux 网桥。如果物理 NIC 也接入该网桥,VM 就会像直接连接物理网络一样工作。VM 可以通过 DHCP 获取企业内网地址,其他服务器也能直接通过该地址连接它。这是生产环境的基本配置。

ip link add br0 type bridge
ip link set eth0 master br0
ip link set br0 up
qemu-system-x86_64 -netdev tap,id=n0,ifname=tap0,script=no -device virtio-net-pci,netdev=n0

vhost-net

内核中处理 virtio 环形缓冲区。无需往返 QEMU 用户空间,因此可以显著降低延迟和 CPU 使用率。配置方式为 -netdev tap,...,vhost=on

模式 特权 外部→内部连接 性能 用途
user 不需要 仅限 hostfwd 开发/测试
tap 需要 可以 隔离的 VM 网络
bridge 需要 可以(直连物理网络) 中~高 生产环境
vhost-net 需要 可以 高性能工作负载

生产现场中的常见情况

开发环境中正常的功能到了预发布环境却无法工作。 开发环境使用 user 模式,只通过 hostfwd 开放了 22 端口,而预发布环境使用 bridge,所有端口都可以访问。反过来,从只能依靠 hostfwd 访问的环境迁移到网桥后,必须重新设计防火墙——此前 QEMU 实际上承担了防火墙的作用。

MTU 问题。 在网桥上叠加 VXLAN 等覆盖网络后,有效 MTU 会减小。VM 内仍然使用 1500,导致大数据包悄无声息地丢失。此时需要降低客户机 MTU,或进行 MSS 钳制。

与容器网络有何异同

前面介绍的四种模式,在容器网络中几乎都会原样出现。名称不同,作用却相同;理解其中一侧,另一侧也就很容易掌握。

两者的差异也很明确。容器共享宿主机内核,只隔离网络命名空间;VM 则拥有自己的内核。 因此,在 VM 内修改内核参数不会影响宿主机;而容器内的许多内核设置要么与宿主机共享,要么根本无法修改。另一方面,VM 启动时间更长,也会完整占用所分配的内存。

转化为实际决策就是:如果必须操作内核本身(加载模块、使用不同内核版本)、确实需要极高隔离级别,或需要运行非 Linux 系统,就选择 VM。除此之外,容器几乎总是更轻、更快。而且二者混合使用十分常见——典型结构是 Kubernetes 节点本身运行在 VM 中,容器再运行于其上。此时网络层叠加两层,前面提到的 MTU 问题尤其容易出现。

下一步要做什么

本模块只讲解概念。现在应当能够解释为何前面的 vm-boot 实验使用 -netdev user,hostfwd=...——因为在无特权环境中,这是唯一可行的选择。