文章目录
互联网和 gpt 的搬运工,很多也不是很理解,比如user,cgroup,time 的 namespace
概念
Linux Namespace 是 Linux 内核的一个特性,用于隔离和管理系统资源,使得不同的进程组可以拥有独立的视图,例如网络配置、文件系统、用户 ID 等。这是实现容器技术(如 Docker 和 LXC)的基础机制之一。Linux 提供了多种类型的 Namespace,每种类型隔离不同的资源:
1. Mount Namespace
Mount Namespace 是最早引入的 Namespace 类型之一,用于隔离文件系统的挂载点。不同的 Mount Namespace 中可以拥有不同的文件系统视图。它在 Linux 内核 2.4.19 (2002年) 中首次引入。
2. UTS Namespace
UTS (UNIX Time-sharing System) Namespace 允许每个 Namespace 有自己的 hostname 和 NIS 域名。它在 Linux 内核 2.6.19 (2006年) 中引入。
3. IPC Namespace
IPC (Inter-process Communication) Namespace 用于隔离 System V IPC 和 POSIX 消息队列 (隔离进程间通信[IPC]资源)。它也是在 Linux 内核 2.6.19 中引入。
4. PID Namespace
PID Namespace 允许每个 Namespace 有其独立的进程编号空间。这意味着同一进程在不同的 PID Namespace 中可以有不同的 PID。它在 Linux 内核 2.6.24 (2008年) 中引入。
5. Network Namespace
Network Namespace 允许隔离网络资源,如接口、IP 地址、路由表等。它在 Linux 内核 2.6.29 (2009年) 中被引入。
6. User Namespace
User Namespace 允许隔离用户和用户组 ID,使得一个用户在不同的 User Namespace 中可以拥有不同的权限。这在 Linux 内核 3.8 (2013年) 中引入。
7. Cgroup Namespace
Cgroup Namespace 是相对较新的 Namespace 类型,用于隔离 cgroup 的视图,使得进程只能看到某些 cgroup 层级。它在 Linux 内核 4.6 (2016年) 中引入。
8. Time Namespace
Time Namespace 允许隔离系统时间,它在 Linux 内核 5.6 (2020年) 中引入。
这些 Namespace 在不同的 Linux 版本中逐步引入,为系统的隔离性和安全性提供了强大的支持。通过这些特性,Linux 系统能够支持轻量级虚拟化(如容器),并为不同的用户和应用提供独立的运行环境。
实操
1. Mount Namespace
说明: Mount Namespace 允许隔离文件系统的挂载点,使不同 Namespace 的进程看到的文件系统结构不同。这样可以防止进程访问或看到全局文件系统中的特定部分。
工作原理: 当你创建一个新的 Mount Namespace 并进入它时(例如使用 unshare --mount 或 clone() 系统调用),新的 Namespace 会继承父 Namespace 的挂载点快照。这意味着初始时,两个 Namespace 中的挂载点是相同的。但是,这之后在一个 Namespace 中做的任何挂载或卸载操作,都不会影响到另一个 Namespace。
举例说明:
- 初始状态:父 Namespace 有一个挂载在 /mnt/data 的文件系统。
- 创建新的 Mount Namespace:新的 Namespace 也会有一个看似挂载在 /mnt/data 的文件系统。
- 在新 Namespace 中卸载:
如果在新的 Namespace 中执行 umount /mnt/data,只有这个新的 Namespace 中 /mnt/data 会被卸载。
父 Namespace 中的 /mnt/data 仍然是挂载状态,不受影响。
关键点:
- 当你在一个 Mount Namespace 中卸载挂载点时,它不会影响到其他 Namespace(包括父 Namespace)中的相同挂载点。
- 为了实现这种隔离,你需要确保已经正确地进入了一个新的 Mount Namespace。如果不是在新的 Mount Namespace 中,你的操作可能会影响到全局挂载状态。
验证操作
- 查看当前挂载点
# mount | grep /mnt/data
tmpfs on /mnt/data type tmpfs (rw,relatime,inode64)
- 新建 namespace
创建新的 Mount Namespace 并进入一个新的 shell
# unshare --mount --fork /bin/bash
- 在新 shell 内查看当前挂载点
# mount | grep /mnt/data
tmpfs on /mnt/data type tmpfs (rw,relatime,inode64)
- 在新的 shell 内卸载挂载点
# umount /mnt/data
# mount | grep /mnt/data
- 查看父 namespace 的挂载点
另起一个终端查看
# mount | grep /mnt/data
tmpfs on /mnt/data type tmpfs (rw,relatime,inode64)
- 在新 shell 内,挂载一个 tmpfs 文件系统到 /mnt
# mount -t tmpfs tmpfs /mnt
# 检查挂载点
# mount | grep /mnt
tmpfs on /mnt type tmpfs (rw,relatime,inode64)
7 在父 namespace 的查看挂载点 /mnt
可以看到只能看到自己的,看不到新的 namespace 的挂载点
# mount | grep /mnt
tmpfs on /mnt/data type tmpfs (rw,relatime,inode64)
PS: 在父 namespace 中 umount 了相关的挂载点也不会影响新的 namespace 中的挂载点
2. UTS Namespace
说明: UTS Namespace 允许每个 Namespace 有自己的 hostname 和 NIS 域名,隔离网络标识符。
验证操作
### 创建新的 UTS Namespace 并进入一个新的 shell
# unshare --uts --fork /bin/bash
### 查看当前的 hostname
# hostname
Florida-2c4g100g
### 改变新 Namespace 的 hostname
# hostname new-hostname
### 检查更改
# hostname
new-hostname
### 回到父 namespace 的终端,看看原来的主机名是否有变化(没有变化)
# hostname
Florida-2c4g100g
3. IPC Namespace
说明: IPC Namespace 隔离进程间通信资源,例如信号量、消息队列和共享内存段。
验证操作
### 创建新的 IPC Namespace 并进入一个新的 shell
# unshare --ipc --fork /bin/bash
### 创建一个新的消息队列
# ipcmk -Q
Message queue id: 0
### 列出消息队列
# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
0x7d27ac0d 0 root 644 0 0
### 回到父 namespace 的终端,查看消息队列(符合预期)
# ipcs -q
------ Message Queues --------
key msqid owner perms used-bytes messages
4. PID Namespace
说明: PID Namespace 隔离进程编号,使得每个 Namespace 内的进程有独立的 PID。
验证操作
### 创建新的 PID Namespace 并进入一个新的 shell
# unshare --pid --fork /bin/bash
### 查看进程列表,你将看到父 namespace 的所有进程,这是因为继承了父 namespace 的 /proc
# ps aux
### 创建新的 PID 和 MNT Namespace (如果不带上 mount 的 ns,那么在新的 ns 中挂载 proc 会影响父 ns 的 proc)
# unshare --pid --mount --fork /bin/bash
### mount 独立的 proc
# mount -t proc proc /proc
### 再次查看,结果符合预期
# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7196 3944 pts/1 S 22:22 0:00 /bin/bash
root 3 0.0 0.1 12296 5372 pts/1 R+ 22:23 0:00 ps -aux
5. Network Namespace
说明: Network Namespace 隔离网络设备、IP 地址和路由表等。
验证操作
### 创建新的 Network Namespace
# ip netns add mynetns
### 查看网络接口(天,只有一个lo接口,后续可以按需添加veth pair)
# ip netns exec mynetns ip link
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
### 清理
# ip netns del mynetns
6. User Namespace
说明: User Namespace 隔离用户和用户组 ID,一个用户在其 User Namespace 中可以是 root,而在全局中不是。
验证操作
### 创建新的 User Namespace 并进入一个新的 shell
# unshare --user --map-root-user --fork /bin/bash
### 查看当前用户 ID
# id
7. Cgroup Namespace
说明: Cgroup Namespace 隔离 cgroup 的视图,使进程只能看到某些 cgroup 层级。
验证操作
### 创建新的 Cgroup Namespace
# unshare --cgroup --fork /bin/bash
### 查看 cgroup 信息
# cat /proc/self/cgroup
8. Time Namespace
说明: Time Namespace 允许进程看到不同的系统时间,有助于测试时间敏感的应用。
验证操作
### 创建新的 Time Namespace 并进入一个新的 shell
# unshare --time --fork /bin/bash
不清楚怎么验证了。