网络命名空间:隔离虚拟机网络

发布: (2025年11月30日 GMT+8 06:31)
5 min read
原文: Dev.to

Source: Dev.to

引言

在之前的文章中,我讨论了 Linux 虚拟化的各种网络方案,并介绍了 qcontroller,这是一款管理 QEMU 虚拟机实例完整生命周期的工具。
qcontroller 还使用 nftables 配置防火墙。最初的方案使用桥接、TAP 设备和全局的 nftables 规则,这会污染主机的网络栈,并且在删除虚拟机时需要小心手动清理。

Linux 网络命名空间提供了一种方式来隔离所有网络组件,这样删除单个命名空间时,内部创建的所有内容会自动被移除。

什么是网络命名空间?

网络命名空间是 Linux 内核的一个特性,它为每个命名空间提供独立的:

  • 网络设备
  • IPv4/IPv6 协议栈
  • 路由表
  • 防火墙规则
  • /proc/net/sys/class/net 以及相关的 /proc/sys/net 文件
  • 端口号(套接字)
  • UNIX 域抽象套接字命名空间

当命名空间被删除时,属于该命名空间的所有设备(包括 veth 对)会自动销毁。

veth 设备对就像一根虚拟以太网线,可以连接两个命名空间(或一个命名空间与主机)。这是为隔离的命名空间提供互联网连接的基础构件。

创建和配置网络命名空间

# 创建一个名为 'example' 的新网络命名空间
sudo ip netns add example

# 创建一个 veth 对(虚拟以太网线)
sudo ip link add host-veth type veth peer name example-veth

# 将 veth 对的一端移动到新命名空间中
sudo ip link set example-veth netns example

# 分配 IP 地址
sudo ip addr add 192.168.26.1/24 dev host-veth               # 主机侧
sudo ip netns exec example ip addr add 192.168.26.2/24 dev example-veth  # 命名空间侧

# 启动两个接口
sudo ip link set dev host-veth up
sudo ip netns exec example ip link set dev example-veth up

测试连通性:

sudo ip netns exec example ping -c 3 192.168.26.1

你应该会看到来自 192.168.26.1 的回复,表明两个命名空间可以相互通信且保持隔离。

启用互联网访问

  1. 在命名空间内部设置默认路由,使流量发送到 veth 对的主机端。

    sudo ip netns exec example ip route add default via 192.168.26.1
  2. 在主机上配置转发和 NAT(将 enp0s1 替换为你的实际外部接口)。

    # 启用 IP 转发
    sudo sysctl -w net.ipv4.ip_forward=1
    
    # 允许来自互联网的已建立/相关流量返回
    sudo iptables -A FORWARD -i enp0s1 -o host-veth -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    
    # 允许来自命名空间的新建外发连接
    sudo iptables -A FORWARD -i host-veth -o enp0s1 -j ACCEPT
    
    # 对命名空间子网进行伪装(NAT)
    sudo iptables -t nat -A POSTROUTING -s 192.168.26.0/24 -o enp0s1 -j MASQUERADE

在命名空间中测试互联网连通性:

sudo ip netns exec example ping -c 3 8.8.8.8

如果收到成功的回复,说明该命名空间已经拥有互联网访问权限。

为虚拟机添加桥接和 TAP 设备

要在隔离的命名空间内部运行虚拟机,需要创建一个桥接,将 IP 地址移动到桥接上,并将虚拟机的 TAP 设备附加到该桥接。

# 1. 在命名空间内部创建一个桥接
sudo ip netns exec example ip link add name br0 type bridge

# 2. 将 IP 地址从 veth 接口移动到桥接
sudo ip netns exec example ip addr del 192.168.26.2/24 dev example-veth
sudo ip netns exec example ip addr add 192.168.26.2/24 dev br0

# 3. 将 veth 接口附加到桥接
sudo ip netns exec example ip link set example-veth master br0

# 4. 启动桥接
sudo ip netns exec example ip link set br0 up

现在,任何附加到 br0 的 VM TAP 设备都将成为隔离网络的一部分。当 example 命名空间被删除时,桥接、veth 对以及所有附加的 TAP 设备会自动消失,保持主机网络的整洁。

Back to Blog

相关文章

阅读更多 »

Friday Five — 2025年12月5日

https://www.redhat.com/rhdc/managed-files/styles/default_800/private/number-1.png.webp?itok=pDWx13kK Red Hat 将在 AWS 上提供增强的 AI 推理