namespace资源隔离

2020-06-29  本文已影响0人  于情于你

6项隔离

image.png

API

clone()

使用clone。来创建一个独立namespace的进程,是最常见的做法,也是Docker使用namespace最基本的方法,它的调用方式如下.

int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);

child_func传入子进程运行的程序主函数。
childstack传入子进程使用的栈空间。
flags表示使用哪些CLONE_
标志位,与namespace相关的主要包括CLONE_NEWIPC、
CLONE_NEWNS、CLONE_NEWNET、CLONE_NEWPID、CLONE_NEWUSER和CLONE_NEWUTS。
args应可用于传入用户参数。

setns()

通过setns()系统调用,进程从原先的namespace加入到某个已经存在的namespace,使用方法如下。通常为了不影响进程的调用者,也为了使新加入的pid namespace生效, 会在setns()函数执行后使用clone。创建子进程继续执行命令,让原先的进程结束运行。
int setns(int fd, int nstype);
docker exec就使用了此方法

为了把新加入的namespace利用起来,需要引入execvp()系列函数,该函数可以执行用户询
令,最常用的就是调用/bin/bash并接受参数,运行起一个shell,用法如下。
fd = open(argv[1], O_RDONLY);
setns(fd, 0);
execvp(argv[2], &argv[2]);
./setns-test ~/uts /bin/bash // 在此之前需要将/ptoc/[pid]/ns 挂载到uts

unshare()

调用unshare()的主要作用就是,不启动新进程就可以起到隔离的效果,相当于跳出原先的
namespace进行操作。这样,就可以在原进程进行一些需要隔离的操作。Linux中自带的unshare命令,就是通过unshare()系统调用实现的。

查看/proc/[pid]/ns文件

从3.8版本的内核开始,用户就可以在/proc/[pid]/ns文件下看到指向不同namespace号的文件,效果如下所示,形如[4026531839]者即为namespace号。


image.png

fork()

  当程序调用fork函数时,系统会创建新的进程,为其分配资源,例如存储数据和代码的空间,然后把原来进程的所有值都复制到新进程中,只有少量数值与原来的进程值不同,相当于复制了本身。那么程序的后续代码逻辑要如何区分自己是新进程还是父进程呢?
  fork的神奇之处在于它仅仅被调用一次,却能够返回两次(父进程与子进程各返回一次),通过返回值的不同就可以区分父进程与子进程。它可能有以下3种不同的返回值:

上一篇 下一篇

猜你喜欢

热点阅读