Linux Network Name Space

Linux Network Name Space

Intro

A namespace wraps a global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource. Changes to the global resource are visible to other processes that are members of the namespace, but are invisible to other processes. One use of namespaces is to implement containers.
This page provides pointers to information on the various namespace types, describes the associated /proc files, and summarizes the APIs for working with namespaces.

以上为 Linux Manpage 中对命名空间的描述。综上所述,命名空间是实现资源隔离的强大工具,对于实现容器化、增强系统安全性和提高资源管理效率至关重要。

Namespace Types

The following table shows the namespace types available on Linux. The second column of the table shows the flag value that is used to specify the namespace type in various APIs. The third column identifies the manual page that provides details on the namespace type. The last column is a summary of the resources that are isolated by the namespace type.

Namespace Isolates Description
Cgroup Cgroup root directory Control Group 允许独立控制资源使用(CPU、内存等),实现资源限制与优先级分配
IPC System V IPC, POSIX message queues 隔离进程间通信资源,确保命名空间间通信独立,避免相互干扰
Network Network devices, stacks, ports, etc. 提供独立的网络环境配置能力,包括 IP 地址、网络设备和端口隔离
Mount Mount points 支持独立的文件系统挂载配置,每个命名空间可拥有独特的文件系统视图
PID Process IDs 实现进程 ID 的独立管理,命名空间内的 PID 与外界隔离,可重用 PID 值
Time Boot and monotonic clocks 允许独立设置系统时间和单调时钟,适合需要独立时钟管理的场景
User User and group IDs 使用户和组 ID 在命名空间内可重定义,增强安全隔离和权限管理灵活性
UTS Hostname and NIS domain name 允许设置独立的主机名和 NIS 域名,模拟独立的系统实例标识

Network Namespace

Linux 网络命名空间(Network Namespace)是 Linux 内核的一部分,用于隔离网络堆栈,允许每个命名空间有自己独立的网络配置,如网络接口、IP 地址、路由表、防火墙规则(iptables)等。这些隔离的环境使得在容器、虚拟机或独立的进程中能够拥有完全独立的网络配置。

在 Linux 系统中,当没有特别指定网络命名空间时,默认操作的是所谓的 root network namespace。这是系统启动时自动创建的第一个网络命名空间。

Query network configuration information

下面将介绍部分查询网络配置信息的命令

  • ip link: 显示和操作网络设备。
  • arp: 显示和操作 ARP 缓存表。
  • route: 显示或操作网络路由表。

ip link 命令用于显示和操作网络设备。它可以用来添加、删除或修改网络接口的状态。

  • 查看网络接口的状态 ip link show
  • 启用一个网络接口 ip link set eth0 up
  • 禁用一个网络接口 ip link set eth0 down
1
2
3
4
5
6
7
8
ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:15:5d:05:8f:2c brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
link/ether 38:f3:ab:8c:2f:1e brd ff:ff:ff:ff:ff:ff
...
  • 索引 (Index): 每个网络接口都有一个唯一的数字索引,它在输出的第一列显示。例如,“1”或“2”。
  • 接口名称 (Interface Name): 接口的名称,例如 eth0, wlan0, lo (loopback,回环接口)。
  • MTU (Maximum Transmission Unit): 这是接口上允许的最大数据包大小(Byte)。例如,“mtu 1500”。
  • qdisc (Queueing Discipline): 这是用于数据包调度的队列策略。例如,“qdisc pfifo_fast”。
  • State (State): 接口的状态,如<LOOPBACK,UP,LOWER_UP>常见的有:
    • UP: 接口正在运行; DOWN: 接口未运行; UNKNOWN: 接口的状态未知。
    • NO-CARRIER: 物理层无连接,常见于电缆未插上的情况。
    • DORMANT: 接口处于休眠状态,等待激活。
    • LOWER_UP: 链路层已启动。
  • Link Type (Link Type): 描述物理链路类型,例如 ether (以太网), loopback (回环), sit (IP-over-IP 隧道), tunnel (通用隧道), bridge (网桥) etc.
  • 硬件地址 (Hardware Address): 接口的 MAC 地址,如00:15:5d:05:8f:2c
  • 广播地址 (Broadcast Address): 广播地址,如 ff:ff:ff:ff:ff:ff

ARP Table and Route Table

arp 命令用于显示和操作 ARP(地址解析协议)缓存表,这个表用于将网络层的 IP 地址解析为链路层的 MAC 地址。下面是对您提供的 arp 命令输出的解释:

  • Address: 这是 IP 地址,表示需要解析的网络地址。
  • HWtype: 硬件类型,表示网络接口的类型,ether 表示以太网。
  • HWaddress: 硬件地址,也就是 MAC 地址,用于链路层的通信。
  • Flags: 状态标志,包含以下可能的值:
    • C 表示已解析的(Complete),即 IP 地址已经成功解析为 MAC 地址。
    • M 表示永久的(Permanent),通常由管理员手动添加,不会自动过期。
    • 其他可能的标志还有 I(Incomplete,表示 ARP 请求尚未完成),S(Static,表示静态 ARP 条目)
  • Mask: 这个字段通常不显示,它表示 IP 地址的掩码部分。
  • Iface: 接口名称,表示该条目关联的网络接口。
1
2
3
4
5
6
arp
Address HWtype HWaddress Flags Mask Iface
_gateway ether 4e:69:2d:fd:be:bb C eth5
198.18.0.2 ether 00:15:5d:4d:29:29 C eth0
198.18.0.4 ether 00:15:5d:4d:29:29 C eth0
169.254.73.152 ether 00:11:22:33:44:55 CM loopback0

在 Linux 系统中,route 命令是一个用于显示或操作网络路由表的工具。路由表是操作系统用来决定如何将数据包从一个网络传输到另一个网络的规则集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 55 0 0 eth5
1.0.0.0 198.18.0.2 255.0.0.0 UG 0 0 0 eth0
2.0.0.0 198.18.0.2 254.0.0.0 UG 0 0 0 eth0
4.0.0.0 198.18.0.2 252.0.0.0 UG 0 0 0 eth0
8.0.0.0 198.18.0.2 248.0.0.0 UG 0 0 0 eth0
16.0.0.0 198.18.0.2 240.0.0.0 UG 0 0 0 eth0
32.0.0.0 198.18.0.2 224.0.0.0 UG 0 0 0 eth0
64.0.0.0 198.18.0.2 192.0.0.0 UG 0 0 0 eth0
128.0.0.0 198.18.0.2 128.0.0.0 UG 0 0 0 eth0
192.168.52.0 0.0.0.0 255.255.255.0 U 311 0 0 eth5
_gateway 0.0.0.0 255.255.255.255 UH 55 0 0 eth5
198.18.0.0 0.0.0.0 255.255.0.0 U 256 0 0 eth0
198.18.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 eth0

Communication Between Two Namespaces

要实现两个命名空间之间的通信,可以创建虚拟网络设备(如 veth 对)并将其分配给不同的命名空间。以下是创建和配置命名空间以及实现它们之间通信的步骤:

  1. 使用 ip netns add 创建命名空间。
  2. 创建 veth 对并分配给相应的命名空间。
  3. 在命名空间内为 veth 设备分配 IP 地址并激活它们。
  4. 配置路由表以实现命名空间间的路由。
  5. 使用 ping 测试两个命名空间之间的连通性。

create network namespace

使用 ip netns add <NAME> 命令,创建网络命名空间。

1
2
3
4
5
6
7
8
9
10
11
ip netns help
Usage: ip netns list # list all network namespaces
ip netns add NAME # create a new network namespace
ip netns attach NAME PID # attach a process to a network namespace
ip netns set NAME NETNSID # set the namespace ID of a network namespace
ip [-all] netns delete [NAME] # delete a network namespace
ip netns identify [PID] # identify a network namespace
ip netns pids NAME # list the PIDs of processes in a network namespace
ip [-all] netns exec [NAME] cmd ... # ⭐ execute a command in a network namespace
ip netns monitor
ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
1
2
3
# 创建网络命名空间
ip netns add ns1
ip netns add ns2

create and config veth pair and

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建虚拟网卡
ip link add veth_ns1 type veth peer name veth_ns2
ip link set veth_ns1 netns ns1
ip link set veth_ns2 netns ns2
# 检测network namespace中的网卡
ip --all netns exec ip link

netns: ns2
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: veth_ns2@if10: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 36:b6:79:b6:f3:13 brd ff:ff:ff:ff:ff:ff link-netns ns1

netns: ns1
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth_ns1@if9: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether ae:a0:29:4d:6c:7e brd ff:ff:ff:ff:ff:ff link-netns ns2

在 Linux 系统中的网络接口上添加 IP 地址,使用ip addr add [ADDRESS]/PREFIXLENGTH dev INTERFACE,并激活设备

1
2
3
4
5
6
7
8
# 为网络接口添加 IP 地址
ip netns exec ns1 ip addr add 192.168.20.1/24 dev veth_ns1
ip netns exec ns2 ip addr add 192.168.20.2/21 dev veth_ns2
# 激活设备,使其可以接收和发送数据包
ip -n ns1 link set veth_ns1 up
ip -n ns1 link set lo up
ip -n ns2 link set veth_ns2 up
ip -n ns2 link set lo up

config route table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ip netns exec ns1 ip route add default via 192.168.20.1 dev veth_ns1
ip netns exec ns2 ip route add default via 192.168.20.2 dev veth_ns2
ip --all netns exec route -n

netns: ns2
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.20.2 0.0.0.0 UG 0 0 0 veth_ns2
192.168.16.0 0.0.0.0 255.255.248.0 U 0 0 0 veth_ns2

netns: ns1
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.20.1 0.0.0.0 UG 0 0 0 veth_ns1
192.168.20.0 0.0.0.0 255.255.255.0 U 0 0 0 veth_ns1

ping between two network namespace

完成上述步骤后,就可以在两个网络命名空间之间进行通信了。

1
2
3
4
5
6
7
8
9
10
ip netns exec ns1 ping 192.168.20.2 -c 4
PING 192.168.20.2 (192.168.20.2) 56(84) bytes of data.
64 bytes from 192.168.20.2: icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from 192.168.20.2: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 192.168.20.2: icmp_seq=3 ttl=64 time=0.062 ms
64 bytes from 192.168.20.2: icmp_seq=4 ttl=64 time=0.043 ms

--- 192.168.20.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3117ms
rtt min/avg/max/mdev = 0.027/0.043/0.062/0.012 ms

Communicate using Linux Bridge

在探讨了网络命名空间如何实现基本通信之后,让我们将目光转向一个更贴近实际应用的场景:在同一台宿主机上运行多个网络命名空间。面对这种情况,如果继续采用之前逐对连接的方法,将变得非常不便
为了简化这一过程并实现更高效的通信,引入 bridge 作为命名空间的中介。

网桥 bridge:一种用于数据链路层实现中继,连接两个或多个局域网的网络互连设备。
交换机 switch:广义的来说,交换机指的是一种通信系统中完成信息交换的设备。这里工作在数据链路层的交换机指的是交换式集线器,其实质是一个多接口的网桥

特性 网桥 (Bridge) 交换机 (Switch)
端口数量 通常较少,如 2 到 16 个 大量,可高达数百个
转发方式 基于软件实现的数据包转发 基于硬件(ASIC)实现的快速数据包转发
性能 相对较低 高性能,低延迟
生成树实例 只能支持一个生成树协议实例 支持多个生成树协议实例,提高网络冗余和效率
过滤机制 具备基本的帧过滤功能 具有更高级的帧过滤和管理功能
冲突域 通常整个设备构成一个冲突域 每个端口可以视为独立的冲突域
广播域 整个设备属于同一个广播域 同样,但可以通过 VLAN 技术分割成多个逻辑广播域
VLAN 支持 不支持或有限支持 广泛支持 VLAN,可以划分多个逻辑网络
管理功能 管理功能有限 提供丰富的管理功能,包括配置、监控和故障排除

Linux 网桥不仅能够简化命名空间间的连接配置,还能提供一种无缝的网络通信方式,使得处于不同命名空间的虚拟设备能够像连接到同一个物理网络一样进行数据交换。通过使用 Linux 网桥,我们可以构建一个更加灵活和可扩展的虚拟网络环境

以下是使用 bridge 实现 network namespace 之间通信的步骤:

  1. 使用 ip netns add 创建 namespace&bridge
  2. 创建 veth 对,与 bridge 建立连接
  3. 为 veth 设备分配 IP 地址并激活它们。
  4. 使用 ping 测试

create network namespace and bridge

1
2
3
4
5
6
# create network namespace
ip netns add h1
ip netns add h2
ip netns add h3
# create bridge
brctl addbr s1

brctl 命令来自于 bridge-utils

create veth pair and connect to bridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# create veth pair
ip link add veth1 type veth peer name br1
ip link add veth2 type veth peer name br2
ip link add veth3 type veth peer name br3
# add interface to namespace
ip link set veth1 netns h1
ip link set veth2 netns h2
ip link set veth3 netns h3
# add interface to bridge(s1)
brctl addif s1 br1
brctl addif s1 br2
brctl addif s1 br3
# check
brctl show
bridge name bridge id STP enabled interfaces
s1 8000.82fcceb79d4c no br1
br2
br3

Config veth pair and bridge

配置 Ip 地址,设置状态为 up

1
2
3
4
5
6
7
8
9
10
11
ip -n h1 addr add local 192.168.1.1/24 dev veth1
ip -n h2 addr add local 192.168.1.2/24 dev veth2
ip -n h3 addr add local 192.168.1.3/24 dev veth3

ip link set s1 up
ip link set br1 up
ip link set br2 up
ip link set br3 up
ip -n h1 link set veth1 up
ip -n h2 link set veth2 up
ip -n h3 link set veth3 up

连接到桥上的 veth 接口通常不会配置 IP 地址,原因如下:
桥接设备(例如 br0)的作用是转发数据包,它相当于一个二层交换机,工作在链路层。数据包在桥上的转发不依赖于 IP 地址,而是基于 MAC 地址。

IP 地址既不是网卡的,也不是这个这个 PC 机的,是 OSI 第三层协议栈的
see more

二层交换机工作在 OSI 模型的第二层,即数据链路层。二层交换机专注于局域网内的 MAC 地址学习和数据帧转发,不支持跨网络路由。
三层交换机结合了二层交换机和路由器的功能,工作在 OSI 模型的第三层,即网络层。可以进行路由选择,IP 地址的配置,以及 VLAN 间通信

ping

1
2
3
4
5
6
7
8
ip netns exec h1 ping 192.168.1.2 -c 2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.076 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.080 ms

--- 192.168.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1027ms
rtt min/avg/max/mdev = 0.076/0.078/0.080/0.002 ms

Communicate with outside world

容器或命名空间内的进程可能需要与外部网络通信。这通常通过将容器网络接口连接到宿主机的网络接口或使用网络地址转换(NAT)来实现。

Reference

linux manpage namespace
linux manpage ip-link
linux manpage arp
OpenStack Neutron 分析:Linux 虚拟网络知识

Author

Efterklang

Posted on

2024-07-01

Updated on

2024-09-18

Licensed under

Comments