TT Lab
开始
学习 学习路径 课程

虚拟化与 QEMU/KVM

虚拟机网络的四种模式

在 TT Lab 中继续学习

一句话总结

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

为什么需要了解这些

“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=...——因为在无特权环境中,这是唯一可行的选择。