命名空间简介
命名空间
用户命名空间实现首次实现(在 Linux2.6.23 中)
名称 | 宏定义 | 隔离的内容 |
---|---|---|
Mount | CLONE_NEWNS | Mount points (since Linux 2.4.19) |
UTS | CLONE_NEWUTS | Hostname and NIS domain name (since Linux 2.6.19) |
IPC | CLONE_NEWIPC | System V IPC, POSIX message queues (since Linux 2.6.19) |
PID | CLONE_NEWPID | Process IDs (since Linux 2.6.24) |
Network | CLONE_NEWNET | network device interfaces, IPv4 and IPv6 protocol stacks, IP routing tables, firewall rules, the /proc/net and /sys/class/net directory trees, sockets, etc (since Linux 2.6.24) |
User | CLONE_NEWUSER | User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8) |
Cgroup | CLONE_NEWCGROUP | Cgroup root directory (since Linux 4.6) |
每种命名空间的目的是将特定的全局系统资源包装在一个抽象中,使命名空间中的进程认为它们拥有全局资源的独立实例
命名空间的目标之一是支持容器的实现,容器是一种用于轻量级虚拟化(以及其他目的)的工具,它为一组进程提供了一种错觉,即它们是系统上唯一的进程
Mount namespaces
隔离一组被进程看到的文件系统挂载点
因此,不同挂载命名空间中的进程可具有不同的文件系统层次结构视图
随着挂载命名空间的添加,mount()
和 umount()
系统调用不再对系统上所有进程可见的全局挂载点集的进行操作,而仅操作与调用进程相关的挂载命名空间
挂载命名空间的用途之一是创建类似于 chroot 的限制环境,然而,与使用 chroot()系统调用相比,挂载命名空间更安全、灵活
挂载命名空间还可用于更复杂的用途,例如:可以在主从关系中单独设置一个挂载命名空间,以便挂载事件自动从一个命名空间传播到另一个命名空间;例如:允许挂载在一个命名空间中的光盘设备自动出现在其它命名空间中
UTS namespaces
隔离两种系统标识符(由 uname()
返回,使用 sethostname()
和 setdomainname()
设置):
-
主机名
-
NIS 域名
在容器的上下文中,UTS 命名空间允许每个容器有自己的主机名和 NIS 域名,这有助于基于这些名称进行初始化操作和配置脚本
术语“UTS”来源于传递给 uname()
的结构体的名称:struct utsname
,该结构体的名称来源于“UNIX 时分系统”
IPC namespaces
隔离特定的进程间通信(IPC)资源,即 System V IPC 对象和POSIX 消息队列
这些 IPC 机制的共同特点是 IPC 对象并不通过文件路径名标识,每个 IPC 命名空间都有自己的 System V IPC 标识符集和 POSIX 消息队列文件系统
PID namespaces
隔离进程的 ID 空间
换句话说,不同 PID 命名空间中的进程可以具有相同的 PID
PID 命名空间的主要好处之一是,可以在主机之间迁移容器,同时保持容器内进程的进程 ID 不变
PID 命名空间还允许每个容器有自己的 init(PID 1),它是“所有进程的祖先”,管理各种系统初始化任务,并在孤儿进程终止时获取它们
站在每个 PID 命名空间实例的角度来看,进程有两个 PID:
- 命名空间内的 PID
- 主机系统上命名空间外的 PID
PID 命名空间可以嵌套:一个进程可从其所在的 PID 命名空间开始,一直到根 PID 命名空间,每层命名空间都有一个 PID
一个进程只能看到(例如,通过 /proc/pid
查看并使用 kill()
发送信号)它自己的 PID 命名空间中包含的进程以及该 PID 命名空间下面嵌套的命名空间
Network namespaces
隔离网络相关的系统资源
因此,每个网络命名空间都有自己的网络设备、IP 地址、IP 路由表、/proc/net
目录、端口号等
从网络的角度,网络命名空间使得容器很有用:每个容器可以有自己的(虚拟)网络设备和绑定到命名空间中的端口号的应用程序;主机系统中的路由规则可以将网络数据包定向到与特定容器关联的网络设备;因此,例如,可以在同一主机系统上有多个容器化的 web 服务器,每个服务器可绑定到其(每个容器)网络命名空间中的端口 80
User namespaces
隔离用户和组 ID
换句话说,进程的用户和组 ID 在用户命名空间内外可以不同
一个进程可以在用户命名空间外有一个普通的无特权用户 ID,同时在命名空间内有一个值为 0 的用户 ID,这意味着进程对用户命名空间内的操作具有完全的 root 权限,但对命名空间外的操作没有权限