菜鸟科技网

ip netns命令如何实现网络命名空间隔离?

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

ip netns命令如何实现网络命名空间隔离?-图1
(图片来源网络,侵删)

什么是网络命名空间?

理解“网络命名空间”是关键。

想象一下,Linux 系统默认只有一个“网络世界”,在这个世界里,所有的网络接口(如 eth0, lo)、IP 地址、路由表、防火墙规则等都是全局共享的。

网络命名空间 的作用就是将这个“网络世界”进行虚拟化隔离,每个网络命名空间都拥有自己独立的、完整的网络栈,包括:

  • 网络接口
  • IP 地址、路由表
  • 端口
  • 防火墙规则
  • /proc/net/sys/class/net 中的信息

这就像为你的 Linux 系统创建了多个独立的“虚拟网络机”,每个“虚拟机”都有自己的网络配置,互不干扰。

ip netns命令如何实现网络命名空间隔离?-图2
(图片来源网络,侵删)

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 子命令来创建一个新的命名空间。

ip netns命令如何实现网络命名空间隔离?-图3
(图片来源网络,侵删)
# 创建一个名为 myns 的新网络命名空间
sudo ip netns add myns

执行后,/var/run/netns/ 目录下会生成一个名为 myns 的文件,代表这个命名空间。

2.2. 列出所有网络命名空间

使用 listshow 子命令。

# 列出所有网络命名空间
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 网络工程师和系统管理员的瑞士军刀,它通过提供网络栈的虚拟化隔离,为构建复杂、安全、灵活的网络环境(如容器、虚拟网络)提供了底层支持。

核心要点回顾:

  1. 隔离:每个 netns 都是一个独立的网络世界。
  2. ip netns add/del:创建和销毁命名空间。
  3. ip netns exec <ns> <command>:在指定命名空间中执行命令。
  4. ip link set <dev> netns <ns>:移动网络接口。
  5. VETH Pair:是连接不同命名空间的“虚拟网线”。
  6. 实践:亲手创建、配置、连接命名空间是掌握它的最好方式。
分享:
扫描分享到社交APP
上一篇
下一篇