Linux.中国 - 开源社区

 找回密码
 骑士注册

QQ登录

微博登录


Docker背后的内核知识:命名空间资源隔离

2015-3-15 21:34    评论: 5 收藏: 2 分享: 16    

2. UTS(UNIX Time-sharing System)namespace

UTS namespace提供了主机名和域名的隔离,这样每个容器就可以拥有了独立的主机名和域名,在网络上可以被视作一个独立的节点而非宿主机上的一个进程。

下面我们通过代码来感受一下UTS隔离的效果,首先需要一个程序的骨架,如下所示。打开编辑器创建uts.c文件,输入如下代码。

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

#define STACK_SIZE (1024 * 1024)

static char child_stack[STACK_SIZE];
char* const child_args[] = {
  "/bin/bash",
  NULL
};

int child_main(void* args) {
  printf("在子进程中!\n");
  execv(child_args[0], child_args);
  return 1;
}

int main() {
  printf("程序开始: \n");
  int child_pid = clone(child_main, child_stack + STACK_SIZE, SIGCHLD, NULL);
  waitpid(child_pid, NULL, 0);
  printf("已退出\n");
  return 0;
}

编译并运行上述代码,执行如下命令,效果如下。

root@local:~# gcc -Wall uts.c -o uts.o && ./uts.o
程序开始:
在子进程中!
root@local:~# exit
exit
已退出
root@local:~#

下面,我们将修改代码,加入UTS隔离。运行代码需要root权限,为了防止普通用户任意修改系统主机名导致set-user-ID相关的应用运行出错。

//[...]
int child_main(void* arg) {
  printf("在子进程中!\n");
  sethostname("Changed Namespace", 12);
  execv(child_args[0], child_args);
  return 1;
}

int main() {
//[...]
int child_pid = clone(child_main, child_stack+STACK_SIZE,
    CLONE_NEWUTS | SIGCHLD, NULL);
//[...]
}

再次运行可以看到hostname已经变化。

root@local:~# gcc -Wall namespace.c -o main.o && ./main.o
程序开始:
在子进程中!
root@NewNamespace:~# exit
exit
已退出
root@local:~#  <- 回到原来的hostname

也许有读者试着不加CLONE_NEWUTS参数运行上述代码,发现主机名也变了,输入exit以后主机名也会变回来,似乎没什么区别。实际上不加CLONE_NEWUTS参数进行隔离而使用sethostname已经把宿主机的主机名改掉了。你看到exit退出后还原只是因为bash只在刚登录的时候读取一次UTS,当你重新登陆或者使用uname命令进行查看时,就会发现产生了变化。

Docker中,每个镜像基本都以自己所提供的服务命名了自己的hostname而没有对宿主机产生任何影响,用的就是这个原理。

查看其它分页:

发表评论


最新评论

我也要发表评论

sailingsz 2015-3-16 09:53  新浪微博网友评论
@我的印象笔记
回复
_BrianChen 2015-3-16 00:33  新浪微博网友评论
@我的印象笔记
回复
lestat_henry 2015-3-15 23:33  新浪微博网友评论
@我的印象笔记 比起2.6的时候,内核对ns的支持完善不少啊
回复
颓颓熊 2015-3-15 22:03  新浪微博网友评论
@我的印象笔记
7 回复
大水坛坛 2015-3-15 22:03  新浪微博网友评论
@mywiz
7 回复

热点评论

大水坛坛 2015-3-15 22:03
@mywiz
7
颓颓熊 2015-3-15 22:03
@我的印象笔记
7
返回顶部

分享到微信朋友圈

打开微信,点击底部的“发现”,
使用“扫一扫”将网页分享至朋友圈。