`Linux Namespace` 是 Linux 提供的一种内核级别环境隔离的方法。用官方的话来说,Linux Namespace 将全局系统资源封装在一个抽象中,从而使 namespace 内的进程认为自己具有独立的资源实例。这项技术本来没有掀起多大的波澜,是容器技术的崛起让他重新引起了大家的注意。
Linux Namespace 有如下 6 个种类:
| **分类** | **系统调用参数** | **相关内核版本** |
| ------------------ | ---------------- | ------------------------------------------------------------ |
| Mount namespaces | CLONE_NEWNS | [Linux 2.4.19](http://lwn.net/2001/0301/a/namespaces.php3) |
| UTS namespaces | CLONE_NEWUTS | [Linux 2.6.19](http://lwn.net/Articles/179345/) |
| IPC namespaces | CLONE_NEWIPC | [Linux 2.6.19](http://lwn.net/Articles/187274/) |
| PID namespaces | CLONE_NEWPID | [Linux 2.6.24](http://lwn.net/Articles/259217/) |
| Network namespaces | CLONE_NEWNET | [始于Linux 2.6.24 完成于 Linux 2.6.29](http://lwn.net/Articles/219794/) |
| User namespaces | CLONE_NEWUSER | [始于 Linux 2.6.23 完成于 Linux 3.8](http://lwn.net/Articles/528078/) |
namespace 的 API 由三个系统调用和一系列 `/proc` 文件组成,本文将会详细介绍这些系统调用和 `/proc` 文件。为了指定要操作的 namespace 类型,需要在系统调用的 flag 中通过常量 `CLONE_NEW*` 指定(包括 `CLONE_NEWIPC`,`CLONE_NEWNS`, `CLONE_NEWNET`,`CLONE_NEWPID`,`CLONE_NEWUSER` 和 `CLONE_NEWUTS),可以指定多个常量,通过 **|**(位或)操作来实现。
简单描述一下三个系统调用的功能:
+ **clone()** : 实现线程的系统调用,用来创建一个新的进程,并可以通过设计上述系统调用参数达到隔离的目的。
+ **unshare()** : 使某进程脱离某个 namespace。
+ **setns()** : 把某进程加入到某个 namespace。
具体的实现原理请往下看。
## 1. clone()
----
`clone()` 的原型如下:
```c
int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);
```
+ **child_func** : 传入子进程运行的程序主函数。
+ **child_stack** : 传入子进程使用的栈空间。
+ **flags** : 表示使用哪些 `CLONE_*` 标志位。
+ **args** : 用于传入用户参数。
`clone()` 与 `fork()` 类似,都相当于把当前进程复制了一份,但 `clone()` 可以更细粒度地控制与子进程共享的资源(其实就是通过 flags 来控制),包括虚拟内存、打开的文件描述符和信号量等等。一旦指定了标志位 `CLONE_NEW*`,相对应类型的 namespace 就会被创建,新创建的进程也会成为该 namespace 中的一员。
clone() 的原型并不是最底层的系统调用,而是封装过的,真正的系统调用内核实现函数为 `do_fork()`,形式如下:
```c
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
```
其中 `clone_flags` 可以赋值为上面提到的标志。
下面来看一个例子:
```c
/* demo_uts_namespaces.c
Copyright 2013, Michael Kerrisk
Licensed under GNU General Public License v2 or later
Demonstrate the operation of UTS namespaces.
*/
#define _GNU_SOURCE
#include
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~