ip netns 是 Linux 系统中用于管理网络命名空间 的命令行工具,它是 iproute2 软件包的一部分,是现代 Linux 网络管理中非常强大的一个功能。

什么是网络命名空间?
理解“网络命名空间”是关键。
想象一下,Linux 系统默认只有一个“网络世界”,在这个世界里,所有的网络接口(如 eth0, lo)、IP 地址、路由表、防火墙规则等都是全局共享的。
网络命名空间 的作用就是将这个“网络世界”进行虚拟化隔离,每个网络命名空间都拥有自己独立的、完整的网络栈,包括:
- 网络接口
- IP 地址、路由表
- 端口
- 防火墙规则
/proc/net和/sys/class/net中的信息
这就像为你的 Linux 系统创建了多个独立的“虚拟网络机”,每个“虚拟机”都有自己的网络配置,互不干扰。

ip netns 命令的主要用途
网络命名空间是许多高级网络功能的基础,ip netns 命令让我们可以方便地操作它们,主要用途包括:
- 容器技术:Docker、Podman 等容器技术使用网络命名空间来为每个容器提供独立的网络环境。
- 网络虚拟化:创建虚拟路由器、防火墙等网络功能。
- 网络测试与安全:在不影响主机网络的情况下,隔离和测试应用程序。
- 系统虚拟化:轻量级的虚拟化方案,如 LXC。
ip netns 命令详解
ip netns 的基本语法是 ip [ OPTIONS ] netns { COMMAND | help }。
1. 前提条件:/var/run/netns 目录
ip netns 命令需要在一个特定的目录下工作,这个目录通常是 /var/run/netns,它用于持久化存储命名空间。
- 如果该目录不存在,你需要手动创建它:
sudo mkdir -p /var/run/netns
2. 常用命令和示例
2.1. 创建网络命名空间
使用 add 子命令来创建一个新的命名空间。

# 创建一个名为 myns 的新网络命名空间 sudo ip netns add myns
执行后,/var/run/netns/ 目录下会生成一个名为 myns 的文件,代表这个命名空间。
2.2. 列出所有网络命名空间
使用 list 或 show 子命令。
# 列出所有网络命名空间 sudo ip netns list # 或者 sudo ip netns show
输出示例:
myns
another_ns
2.3. 删除网络命名空间
使用 delete 子命令。
# 删除名为 myns 的网络命名空间 sudo ip netns delete myns
这会删除 /var/run/netns/myns 文件。
2.4. 在命名空间中执行命令
这是最常用的功能之一,使用 exec 子命令,可以在指定的命名空间中运行任意命令,通常是网络相关的命令。
示例:在 myns 命名空间中查看网络接口
# 在 myns 命名空间中执行 ip addr 命令 sudo ip netns exec myns ip addr
由于 myns 是一个全新的命名空间,它目前只有一个回环接口 lo。
输出示例:
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
注意:这里的 ip addr 是在 myns 的网络环境中执行的,不会影响主机的网络。
2.5. 将网络接口移动到命名空间
这是构建复杂网络拓扑的关键步骤,使用 link 子命令。
示例:将物理网卡 eth0 移动到 myns 命名空间
# 1. 查看 eth0 当前状态(在主机命名空间中) ip addr show eth0 # 2. 将 eth0 移动到 myns 命名空间 sudo ip link set eth0 netns myns # 3. 再次在主机中查看 eth0,会发现它已经消失了 ip addr show eth0 # Error: cannot find device "eth0" # 4. 在 myns 命名空间中查看,会发现 eth0 出现了 sudo ip netns exec myns ip addr show
eth0 的所有权完全属于 myns 命名空间,主机无法再直接控制它。
将接口移回主机命名空间:
# 在 myns 命名空间中,将 eth0 的状态设为 UP(可选) sudo ip netns exec myns ip link set eth0 up # 将 eth0 从 myns 移回主机默认的命名空间(通常是 '1') sudo ip link set eth0 netns 1
2.6. 管理回环接口
每个网络命名空间都有一个自己的回环接口 lo,默认是 DOWN 状态,需要手动将其 UP 起来。
# 在 myns 命名空间中启用回环接口 sudo ip netns exec myns ip link set lo up # 再次查看,lo 状态变为 UP sudo ip netns exec myns ip addr show
输出示例:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2.7. 命名空间之间的通信
默认情况下,不同命名空间是完全隔离的,无法通信,要让它们通信,需要创建“虚拟以太网对”(VETH Pair)。
VETH Pair 是一对虚拟接口,像一根虚拟网线,一端在命名空间 A,另一端在命名空间 B,从 A 端发出的数据会直接进入 B 端,反之亦然。
示例:创建 VETH Pair 连接主机和 myns 命名空间
# 1. 创建一对名为 veth0 和 veth1 的虚拟网卡 sudo ip link add veth0 type veth peer name veth1 # 2. 将 veth1 端移动到 myns 命名空间 sudo ip link set veth1 netns myns # 3. 为主机的 veth0 端配置 IP 地址并启用 sudo ip addr add 192.168.100.1/24 dev veth0 sudo ip link set veth0 up # 4. 为 myns 命名空间中的 veth1 端配置 IP 地址并启用 sudo ip netns exec myns ip addr add 192.168.100.2/24 dev veth1 sudo ip netns exec myns ip link set veth1 up sudo ip netns exec myns ip link set lo up # 5. 测试连通性 # 在主机上 ping myns ping 192.168.100.2 # 在 myns 中 ping 主机 sudo ip netns exec myns ping 192.168.100.1
这样,主机和 myns 命名空间就通过虚拟网线 veth0/veth1 连通了。
实战演练:一个完整的例子
这个例子将演示如何创建两个隔离的网络命名空间,并为它们配置 IP 地址,实现它们之间的通信。
# 1. 创建两个命名空间 sudo ip netns add ns_A sudo ip netns add ns_B # 2. 创建两对 VETH,用于连接 ns_A 和 ns_B,以及连接它们到外网 # VETH Pair 1: 连接 ns_A 和 ns_B sudo ip link add vethA type veth peer name vethB # VETH Pair 2: 连接 ns_A 和外网 sudo ip link add veth_extA type veth peer name veth_extB # 3. 将 VETH 的另一端移动到对应的命名空间 sudo ip link set vethB netns ns_A sudo ip link set veth_extA netns ns_A sudo ip link set veth_extB netns ns_B # 4. 在 ns_A 中配置 IP 并启用接口 sudo ip netns exec ns_A ip addr add 10.0.0.1/24 dev vethA sudo ip netns exec ns_A ip addr add 192.168.100.1/24 dev veth_extA sudo ip netns exec ns_A ip link set vethA up sudo ip netns exec ns_A ip link set veth_extA up sudo ip netns exec ns_A ip link set lo up # 5. 在 ns_B 中配置 IP 并启用接口 sudo ip netns exec ns_B ip addr add 10.0.0.2/24 dev vethB sudo ip netns exec ns_B ip addr add 192.168.100.2/24 dev veth_extB sudo ip netns exec ns_B ip link set vethB up sudo ip netns exec ns_B ip link set veth_extB up sudo ip netns exec ns_B ip link set lo up # 6. 在主机上配置 veth_extB 的 IP 并启用 sudo ip addr add 192.168.100.254/24 dev veth_extB sudo ip link set veth_extB up # 7. 测试连通性 # 在 ns_A 中 ping ns_B sudo ip netns exec ns_A ping 10.0.0.2 # PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. # 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.048 ms # 在 ns_B 中 ping ns_A sudo ip netns exec ns_B ping 10.0.0.1 # PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data. # 64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.042 ms # 在 ns_A 中 ping 主机 sudo ip netns exec ns_A ping 192.168.100.254 # PING 192.168.100.254 (192.168.100.254) 56(84) bytes of data. # 64 bytes from 192.168.100.254: icmp_seq=1 ttl=64 time=0.051 ms # 8. 清理环境(非常重要!) sudo ip link del veth0 # 删除之前创建的 veth pair sudo ip link del veth_extA # 删除另一对 sudo ip netns del ns_A sudo ip netns del ns_B
ip netns 是 Linux 网络工程师和系统管理员的瑞士军刀,它通过提供网络栈的虚拟化隔离,为构建复杂、安全、灵活的网络环境(如容器、虚拟网络)提供了底层支持。
核心要点回顾:
- 隔离:每个
netns都是一个独立的网络世界。 ip netns add/del:创建和销毁命名空间。ip netns exec <ns> <command>:在指定命名空间中执行命令。ip link set <dev> netns <ns>:移动网络接口。- VETH Pair:是连接不同命名空间的“虚拟网线”。
- 实践:亲手创建、配置、连接命名空间是掌握它的最好方式。
