linux namespace教程 linux中namespace
第1天:Linux namespace概述
#### 从本文开始,我们将会从零开始带领大家学习Linux namespace的相关内容。
#### 在本文中,我们将会首先介绍namespace的基本概念。
## 什么是namespace?
Namespace是对全局系统资源的一种封装隔离,使得处于不同namespace的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace中的进程没有影响。
Linux内核支持的namespaces如下:
名称 | 宏定义 | 隔离内容
--|--|--
Cgroup | CLONE_NEWCGROUP | Cgroup root directory (since Linux 4.6)
IPC | CLONE_NEWIPC | System V IPC, POSIX message queues (since Linux 2.6.19)
Network | CLONE_NEWNET | Network devices, stacks, ports, etc. (since Linux 2.6.24)
Mount | CLONE_NEWNS | Mount points (since Linux 2.4.19)
PID | CLONE_NEWPID | Process IDs (since Linux 2.6.24)
User | CLONE_NEWUSER | User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8)
UTS | CLONE_NEWUTS | Hostname and NIS domain name (since Linux 2.6.19)
Ps:其中,cgroup namespace在4.6的内核中才实现,并且和cgroup v2关系密切,现在普及程度还不高,比如docker现在就还没有用它,所以在namespace系列文章中暂时不会介绍cgroup namespace。
## 查看进程所属的namespaces
系统中的每个进程都有/proc/[pid]/ns/这样一个目录,里面包含了这个进程所属namespace的信息,里面每个文件的描述符都可以用来作为setns函数(后文会介绍)的参数。
查看当前bash进程所属的namespace信息:

其中:
1. 以ipc:[4026531839]为例,ipc是namespace的类型,4026531839是inode number,如果两个进程的ipc namespace的inode number一样,说明他们属于同一个namespace。这条规则对其他类型的namespace也同样适用。
2. 从上面的输出可以看出,对于每种类型的namespace,进程都会与一个对应的namespace ID关联。
## namespace相关的API
和namespace相关的函数只有三个,如下所示:
一、`clone`: 创建一个新的进程并把他放到新的namespace中。
``` int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg); ```其中:flags用于指定一个或者多个上面的CLONE_NEW*宏定义(当然也可以包含跟namespace无关的flags,多个flags用|进行分隔),这样就会创建一个或多个新的不同类型的namespace,并把新创建的子进程加入新创建的这些namespace中。
二、`setns`: 将当前进程加入到已有的namespace中。
``` int setns(int fd, int nstype); ```其中:
1. fd:指向/proc/[pid]/ns/目录里相应namespace对应的文件,表示要加入哪个namespace
2. nstype:指定namespace的类型(上面的任意一个CLONE_NEW*),具体分为两种情况:1. 如果当前进程不能根据fd得到它的类型,如fd由其他进程创建,并通过UNIX domain socket传给当前进程,那么就需要通过nstype来指定fd指向的namespace的类型。2. 如果进程能根据fd得到namespace类型,比如这个fd是由当前进程打开的,那么nstype设置为0即可。
三、`unshare`: 使当前进程退出指定类型的namespace,并加入到新创建的namespace(相当于创建并加入新的namespace)。
``` int unshare(int flags); ```其中:flags用于指定一个或者多个上面的CLONE_NEW*宏定义(当然也可以包含跟namespace无关的flags,多个flags用|进行分隔),这样就会创建一个或多个新的不同类型的namespace,并把新创建的子进程加入新创建的这些namespace中。
### clone和unshare的区别
clone和unshare的功能都是创建并加入新的namespace, 他们的区别是:
1. unshare是使当前进程加入新的namespace。
2. clone是创建一个新的子进程,然后让子进程加入新的namespace,而当前进程保持不变。
## 补充信息
当一个namespace中的所有进程都退出时,该namespace将会被销毁。当然还有其他方法让namespace一直存在,假设我们有一个进程号为1000的进程,以ipc namespace为例:
1. 通过`mount --bind`命令。例如:
``` mount --bind /proc/1000/ns/ipc /other/file ```此时,就算属于这个ipc namespace的所有进程都退出了,只要`/other/file`还在,这个ipc namespace就一直存在,其他进程就可以利用`/other/file`,通过`setns`函数加入到这个namespace。
2. 在其他namespace的进程中打开`/proc/1000/ns/ipc`文件,并一直持有这个文件描述符不关闭,以后就可以用`setns`函数加入这个namespace。
linux namespace 命令 linux中namespace
Hugging Face Space教程:轻松创建和分享机器学习应用
Linux namespaces linux namespace实现
linux namespaces 详解 linux namespace技术
linux namespace使用 linux namespace技术
linux namespace 实现 linux namespace详解
【Linux】 - Linux中的权限机制linux中权限最大的账户是
【Linux】linux中的strip命令linux中ls命令的用法