Linux Namespace
什么是Namespace?
Namespaces are a feature of the Linux kernel that partition kernel resources such that one set of processes sees one set of resources while another set of processes sees a different set of resources. The feature works by having the same namespace for a set of resources and processes, but those namespaces refer to distinct resources. Resources may exist in multiple spaces. Examples of such resources are process IDs, host-names, user IDs, file names, some names associated with network access, and Inter-process communication.
From wikipedia
简单的说,Linux 中,命名空间(Namespace)是一种轻量级的虚拟化技术,它可以将系统资源封装起来,使得在命名空间内的进程只能看到封装后的视图。这样,每个命名空间内的进程就感觉自己是在自己的独立系统中运行。
以下是几种常见的 Linux 命名空间:
Namespace | Flag | 控制内容 | 内核版本 |
---|---|---|---|
Cgroup | CLONE_NEWCGROUP | Cgroup root directory cgroup 根目录 | 4.6 |
IPC | CLONE_NEWIPC | System V IPC, POSIX message queues信号量,消息队列 | 2.6.19 |
Network | CLONE_NEWNET | Network devices, stacks, ports, etc.网络设备,协议栈,端口等等 | 2.6.24 |
Mount | CLONE_NEWNS | Mount points挂载点 | 2.4.19 |
PID | CLONE_NEWPID | Process IDs进程号 | 2.6.24 |
User | CLONE_NEWUSER | 用户和组 ID | 3.8 |
UTS | CLONE_NEWUTS | 系统主机名和 NIS(Network Information Service) 主机名(有时称为域名) | 2.6.19 |
Namespace 类型
Cgroup Namespace
Cgroup Namespace(控制组命名空间)用于隔离和管理控制组(cgroup)层次结构。控制组是一种用于对进程组进行资源限制和管理的机制。
通过Cgroup Namespace,可以创建独立的控制组层次结构,使得在不同的命名空间中的进程可以有各自独立的控制组视图,从而实现资源的隔离和管理。每个Cgroup Namespace都有自己的根控制组,进程在不同的Cgroup Namespace中看到的控制组层次结构是独立的。
Cgroup Namespace的创建可以使用clone()系统调用的CLONE_NEWCGROUP标志,或者使用unshare()系统调用的CLONE_NEWCGROUP选项。创建Cgroup Namespace后,可以使用cgroupfs文件系统(通常在/sys/fs/cgroup目录下)进行控制组的管理和配置。
通过Cgroup Namespace,可以实现在不同的命名空间中对进程组进行资源隔离和限制,例如 CPU、内存、磁盘IO等。这对于容器化技术和系统资源管理非常有用,可以确保不同的容器或进程组之间相互隔离并按照预期进行资源分配。
IPC Namespace
IPC Namespace(进程间通信命名空间)用于隔离进程间通信(IPC)机制。IPC是进程之间进行数据交换和通信的机制,包括共享内存、信号量、消息队列等。
通过IPC Namespace,可以创建独立的IPC环境,使得在不同的命名空间中的进程无法直接访问其他命名空间中的IPC资源,从而实现IPC的隔离和安全性。
每个IPC Namespace都有自己独立的System V IPC和POSIX消息队列,进程在不同的IPC Namespace中看到的IPC资源是独立的。这意味着,进程在一个IPC Namespace中创建的共享内存段、信号量或消息队列对其他IPC Namespace中的进程是不可见的。
IPC Namespace的创建可以使用clone()系统调用的CLONE_NEWIPC标志,或者使用unshare()系统调用的CLONE_NEWIPC选项。创建IPC Namespace后,可以使用相应的IPC机制的系统调用(如shmget()、semget()、msgget()等)来创建和操作IPC资源。
通过IPC Namespace,可以实现进程间通信的隔离和安全性,确保不同的命名空间中的进程无法干扰或访问彼此的IPC资源。这对于容器化和多租户环境中的进程隔离和安全性非常有用。
Network Namespace
Network Namespace(网络命名空间)用于隔离网络栈和网络资源。通过Network Namespace,可以创建独立的网络环境,使得在不同的命名空间中的进程或容器可以拥有自己独立的网络设备、IP地址、路由表和网络配置。
每个Network Namespace都有自己独立的网络设备和配置,包括网络接口(如eth0、wlan0等)、IP地址、路由表、网络协议栈等。这意味着,在不同的Network Namespace中,进程或容器可以拥有不同的网络配置,彼此之间互不干扰。
通过Network Namespace,可以实现以下功能和应用:
- 网络隔离:不同的Network Namespace中的进程或容器可以独立配置和管理自己的网络环境,避免相互干扰和冲突。
- 虚拟网络:通过创建多个Network Namespace,可以创建虚拟的网络环境,使得不同的进程或容器可以在自己的网络中通信,就像它们在不同的物理网络中一样。
- VPN和隧道:可以在不同的Network Namespace中创建VPN连接或网络隧道,实现安全的网络通信。
- 负载均衡和网络分区:通过将不同的进程或容器放置在不同的Network Namespace中,可以实现负载均衡和网络分区,以提高网络性能和安全性。
创建Network Namespace可以使用clone()系统调用的CLONE_NEWNET标志,或者使用ip netns命令行工具。创建Network Namespace后,可以使用ip命令行工具或编程接口(如libnetlink)来配置和管理网络设备、IP地址、路由表等。
Mount Namepsace
Mount Namespace(挂载命名空间)用于隔离文件系统挂载点和挂载状态。通过Mount Namespace,可以创建独立的文件系统视图,使得在不同的命名空间中的进程或容器看到的文件系统层次结构是独立的。
每个Mount Namespace都有自己独立的根文件系统和挂载点列表。进程或容器在不同的Mount Namespace中看到的文件系统层次结构可以是不同的,它们可以拥有自己的根文件系统、挂载点和文件系统挂载状态。这样可以实现文件系统的隔离和管理。
通过Mount Namespace,可以实现以下功能和应用:
- 文件系统隔离:不同的Mount Namespace中的进程或容器可以拥有自己独立的文件系统视图,彼此之间互不干扰。这使得不同的进程或容器可以在相同的主机上拥有不同的文件系统配置和访问权限。
- 挂载点隔离:在不同的Mount Namespace中可以创建独立的挂载点,使得挂载操作只在当前的Mount Namespace中可见。这可以防止不同的进程或容器之间干扰彼此的挂载状态。
- 文件系统沙盒:通过创建新的Mount Namespace,可以将进程或容器限制在特定的文件系统视图中,防止它们访问主机的其他文件系统。
创建Mount Namespace可以使用clone()系统调用的CLONE_NEWNS标志,或者使用unshare()系统调用的CLONE_NEWNS选项。创建Mount Namespace后,可以使用mount和umount命令行工具,或者使用mount()和umount()系统调用来进行文件系统的挂载和卸载。
PID Namespace
PID Namespace(进程标识符命名空间)用于隔离进程的标识符和进程层次结构。每个PID Namespace都有自己独立的进程ID(PID)空间,进程在不同的PID Namespace中看到的进程ID是独立的。
通过PID Namespace,可以创建独立的进程层次结构和进程标识符空间。在不同的PID Namespace中,进程可以拥有相同的PID,但它们实际上对应不同的进程。这样可以实现进程间的隔离和管理。
PID Namespace的主要功能和应用包括:
- 进程隔离:不同的PID Namespace中的进程可以拥有相同的PID,但它们之间是隔离的,彼此不可见。这样可以实现进程的隔离和保护,避免不同命名空间中的进程相互干扰。
- 容器化:PID Namespace是容器化技术(如Docker、LXC等)的基础之一。通过创建独立的PID Namespace,可以在不同的容器中运行进程,并使它们在自己的PID命名空间中看到的进程层次结构是独立的。
- 进程管理:PID Namespace使得在独立的命名空间中,可以对进程进行独立的管理和控制。例如,可以在一个PID Namespace中创建子进程,并在另一个PID Namespace中看到它们,而其他的PID Namespace看不到这些进程。
创建PID Namespace可以使用clone()系统调用的CLONE_NEWPID标志,或者使用unshare()系统调用的CLONE_NEWPID选项。创建PID Namespace后,可以使用ps命令行工具或编程接口(如libproc)来查看和管理当前命名空间中的进程。
User Namespace
User Namespace(用户命名空间)用于隔离用户和用户组标识符。通过User Namespace,可以创建独立的用户标识符空间,使得在不同的命名空间中的进程或容器看到的用户和用户组是独立的。
每个User Namespace都有自己独立的用户和用户组标识符,包括用户ID(UID)和组ID(GID)。进程或容器在不同的User Namespace中看到的用户和用户组标识符可以是不同的,它们可以拥有自己的用户和用户组映射。
通过User Namespace,可以实现以下功能和应用:
- 用户隔离:不同的User Namespace中的进程或容器可以拥有相同的用户和用户组标识符,但它们之间是隔离的,彼此不可见。这样可以实现用户的隔离和保护,避免不同命名空间中的进程相互干扰。
- 特权分离:User Namespace可以用于特权分离,即将特权操作限制在特定的User Namespace中。这样可以降低特权操作的风险,并增加系统的安全性。
- 容器化:User Namespace是容器化技术(如Docker、LXC等)的基础之一。通过创建独立的User Namespace,可以在不同的容器中运行进程,并使它们在自己的用户标识符空间中看到的用户和用户组是独立的。
- 用户映射:User Namespace允许进行用户映射,将不同User Namespace中的用户和用户组标识符映射到不同的标识符范围。这可以解决不同命名空间中的用户标识符冲突问题。
创建User Namespace可以使用clone()系统调用的CLONE_NEWUSER标志,或者使用unshare()系统调用的CLONE_NEWUSER选项。创建User Namespace后,可以使用useradd、groupadd等命令行工具或编程接口(如libuser)来管理当前命名空间中的用户和用户组。
UTS Namespace
UTS Namespace(UTS命名空间)用于隔离主机名和域名。每个UTS Namespace都有自己独立的主机名和域名,进程在不同的UTS Namespace中看到的主机名和域名是独立的。
通过UTS Namespace,可以创建独立的主机名空间,使得在不同的命名空间中的进程或容器看到的主机名和域名是独立的。这样可以实现主机名的隔离和管理。
UTS Namespace的主要功能和应用包括:
- 主机名隔离:不同的UTS Namespace中的进程可以拥有自己独立的主机名和域名,彼此之间互不干扰。这使得不同的进程或容器可以在相同的主机上拥有不同的主机名配置。
- 容器化:UTS Namespace是容器化技术(如Docker、LXC等)的基础之一。通过创建独立的UTS Namespace,可以在不同的容器中运行进程,并使它们在自己的UTS命名空间中看到的主机名和域名是独立的。
- 主机名管理:通过UTS Namespace,可以对主机名进行独立的管理和配置。每个UTS Namespace可以拥有自己的主机名,这样可以方便地为容器或进程设置具有意义的主机名。
创建UTS Namespace可以使用clone()系统调用的CLONE_NEWUTS标志,或者使用unshare()系统调用的CLONE_NEWUTS选项。创建UTS Namespace后,可以使用hostname命令行工具或编程接口(如sethostname()系统调用)来配置和管理当前命名空间中的主机名。
需要注意的是,每个 Namespace 仅用于隔离自己的标识符和层次结构,而不影响其他Namespace。