网络命名空间:隔离虚拟机网络
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 的回复,表明两个命名空间可以相互通信且保持隔离。
启用互联网访问
-
在命名空间内部设置默认路由,使流量发送到 veth 对的主机端。
sudo ip netns exec example ip route add default via 192.168.26.1 -
在主机上配置转发和 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 设备会自动消失,保持主机网络的整洁。