Docker原理11

Linux Namespace 11

AUFS文件系统17

重新理解Docker的各种命令18

Docker原理

Linux Namespace

docker是一个容器引擎,容器就要求对进程空间、用户空间、网络空间、硬盘空间等等做一些隔离,docker的底层是使用LXC实现的,LXC则使用Linux Namespace技术对各种技术做隔离。

Linux Namespace是Linux提供的一种内核级别环境隔离的方法, 隔离的资源包括:Mount、UTS、IPC、PID、Network、User。 篇幅限制,本文只介绍UTS、PID和Mount的隔离。

网上找来一段代码:

#define _GNU_SOURCE

#include <sys/types.h>

#include <sys/wait.h>

#include <stdio.h>

#include <sched.h>

#include <signal.h>

#include <unistd.h>

#include <errno.h>

/* 定义一个给 clone 用的栈,栈大小1M */

#define STACK_SIZE (1024 * 1024)

static char container_stack[STACK_SIZE];

char* const container_args[] = {

"/bin/bash",

NULL

};

int container_main(void* arg)

{

printf("Container - inside the container!\n");

/* 直接执行一个shell,以便我们观察这个进程空间里的资源是否被隔离了 */

execv(container_args[], container_args);

printf("Something's wrong!\n");

return ;

}

int main()

{

printf("Parent - start a container!\n");

/* 调用clone函数,其中传出一个函数,还有一个栈空间的(为什么传尾指针,因为栈是反着的) */

int container_pid = clone(container_main, container_stack+STACK_SIZE, SIGCHLD, NULL);

if (container_pid < )

{

fprintf(stderr, "clone failed WTF!!!! %s\n", strerror(errno));

return -;

}

/* 等待子进程结束 */

waitpid(container_pid, NULL, );

printf("Parent - container stopped!\n");

return ;

}

代码比较简单,就是用clone系统调用生成一个新的子进程,并运行container_main函数。

运行结果:

$./simple_clone

Parent - start a container!

Container - inside the container!

$ps aux |head

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root  0.0 0.0   ? Ss : : /usr/lib/systemd/systemd --switched-root --system --deserialize 

root  0.0 0.0   ? S : : [kthreadd]

root  0.0 0.0   ? S : : [ksoftirqd/]

root  0.0 0.0   ? S : : [kworker/u30:]

root  0.0 0.0   ? S : : [migration/]

root  0.0 0.0   ? S : : [rcu_bh]

root  0.0 0.0   ? S : : [rcuob/]

root  0.0 0.0   ? S : : [rcuob/]

root  0.0 0.0   ? S : : [rcuob/]

可以看到,在进入了子进程后看到的跟父进程完全一样。

我们往上段代码的clone函数中加入CLONE_NEWUTS flag, 并且在container_main函数中设置主机名:

#define _GNU_SOURCE

#include <sys/types.h>

#include <sys/wait.h>

#include <stdio.h>

#include <sched.h>

#include <signal.h>

/* 定义一个给 clone 用的栈,栈大小1M */

#define STACK_SIZE (1024 * 1024)

static char container_stack[STACK_SIZE];

char* const container_args[] = {

"/bin/bash",

NULL

};

int container_main(void* arg)

{

printf("Container - inside the container!\n");

sethostname("container",); /* 设置hostname */

/* 直接执行一个shell,以便我们观察这个进程空间里的资源是否被隔离了 */

execv(container_args[], container_args);

printf("Something's wrong!\n");

return ;

}

int main()

{

printf("Parent - start a container!\n");

/* 调用clone函数,其中传出一个函数,还有一个栈空间的(为什么传尾指针,因为栈是反着的) */

int container_pid = clone(container_main, container_stack+STACK_SIZE,

CLONE_NEWUTS | SIGCHLD, NULL); /*启用CLONE_NEWUTS Namespace隔离 */

if (container_pid < )

{

printf("%d clone failed WTF!!!! %s\n", container_pid, strerror(errno));

return -;

}

/* 等待子进程结束 */

waitpid(container_pid, NULL, );

printf("Parent - container stopped!\n");

return ;

}

运行:

$sudo ./uts

Parent - start a container!

Container - inside the container!

#hostname

container

#exit

exit

Parent - container stopped!

$

可以看到子进程中的hostname变成了container

我们接着在clone函数中加入CLONE_NEWPID flag, 并在主子进程中都打出pid:

#define _GNU_SOURCE

#include <sys/types.h>

#include <sys/wait.h>

#include <stdio.h>

#include <sched.h>

#include <signal.h>

#include <unistd.h>

#include <errno.h>

/* 定义一个给 clone 用的栈,栈大小1M */

#define STACK_SIZE (1024 * 1024)

static char container_stack[STACK_SIZE];

char* const container_args[] = {

"/bin/bash",

NULL

};

int container_main(void* arg)

{

printf("Container [%5d] - inside the container!\n", getpid());

sethostname("container",); /* 设置hostname */

/* 直接执行一个shell,以便我们观察这个进程空间里的资源是否被隔离了 */

execv(container_args[], container_args);

printf("Something's wrong!\n");

return ;

}

int main()

{

printf("Parent [%5d] - start a container!\n", getpid());

/* 调用clone函数,其中传出一个函数,还有一个栈空间的(为什么传尾指针,因为栈是反着的) */

int container_pid = clone(container_main, container_stack+STACK_SIZE,

CLONE_NEWUTS | CLONE_NEWPID | SIGCHLD, NULL); /*启用CLONE_NEWUTS Namespace隔离 */

if (container_pid < )

{

printf("%d clone failed WTF!!!! %s\n", container_pid, strerror(errno));

return -;

}

/* 等待子进程结束 */

waitpid(container_pid, NULL, );

printf("Parent - container stopped!\n");

return ;

}

运行:

$sudo ./pid

Parent [] - start a container!

Container [ ] - inside the container!

#ps aux |head

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root  0.0 0.0   ? Ss : : /usr/lib/systemd/systemd --switched-root --system --deserialize 

root  0.0 0.0   ? S : : [kthreadd]

root  0.0 0.0   ? S : : [ksoftirqd/]

root  0.0 0.0   ? S : : [kworker/u30:]

root  0.0 0.0   ? S : : [migration/]

root  0.0 0.0   ? S : : [rcu_bh]

root  0.0 0.0   ? S : : [rcuob/]

root  0.0 0.0   ? S : : [rcuob/]

root  0.0 0.0   ? S : : [rcuob/]

#

可以看到子进程的pid变成了1。 这个变化很重要,意味着子进程后面的所有进程,都是挂在这个PID为1的进程后面。看起来就像是一个新的系统,而该子进程就像是pid为1的init进程。

但是上面的ps结果也看到,子进程仍然可以看以父进程的所有进程,原因是主子进程中的ps命令都是去读的/proc文件系统,我们需要对子进程单独mount一个proc文件系统出来。

接着改代码,给clone函数加一个CLONE_NEWNS flag, 并在子进程中运行 mount -t /proc proc /proc命令:

#define _GNU_SOURCE

#include <sys/types.h>

#include <sys/wait.h>

#include <stdio.h>

#include <sched.h>

#include <signal.h>

#include <unistd.h>

#include <errno.h>

/* 定义一个给 clone 用的栈,栈大小1M */

#define STACK_SIZE (1024 * 1024)

static char container_stack[STACK_SIZE];

char* const container_args[] = {

"/bin/bash",

NULL

};

int container_main(void* arg)

{

printf("Container [%5d] - inside the container!\n", getpid());

sethostname("container",); /* 设置hostname */

/* 重新mount proc文件系统到 /proc下 */

system("mount -t proc proc /proc");

/* 直接执行一个shell,以便我们观察这个进程空间里的资源是否被隔离了 */

execv(container_args[], container_args);

printf("Something's wrong!\n");

return ;

}

int main()

{

printf("Parent [%5d] - start a container!\n", getpid());

/* 调用clone函数,其中传出一个函数,还有一个栈空间的(为什么传尾指针,因为栈是反着的) */

int container_pid = clone(container_main, container_stack+STACK_SIZE,

CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL); /*启用CLONE_NEWUTS Namespace隔离 */

if (container_pid < )

{

printf("%d clone failed WTF!!!! %s\n", container_pid, strerror(errno));

return -;

}

/* 等待子进程结束 */

waitpid(container_pid, NULL, );

printf("Parent - container stopped!\n");

return ;

}

运行:

$sudo ./mount

Parent [] - start a container!

Container [ ] - inside the container!

#ps aux

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root  1.3 0.0   pts/ S : : /bin/bash

root  0.0 0.0   pts/ R+ : : ps aux

可以看到,ps也只能看到子进程中的进程了。
这个时候还可以看一下,父进程实际上可以看到子进程的进程,并且pid不为1,而子进程就像一只井底之蛙,只能看到自己被隔离出来的进程。

$ps aux |grep /bin/bash

root  0.0 0.0   pts/ S+ : : /bin/bash

lijun.s+  0.0 0.0   pts/ S+ : : grep --color=auto /bin/bash

AUFS文件系统

docker使用的文件系统有aufs、devicemapper等,aufs是docker的首选文件系统,但是可惜没有合到Linux主干代码中,不过主流的系统像ubuntu都是支持的。 而像centos这种系统不支持aufs, 就只能使用devicemapper了。 
由于aufs对理解docker的layer(层)的概念更容易一些,这里介绍下aufs文件系统。

闲话不多说,找个ubuntu
12.04版本的系统做如下测试:
建两个目录d1,d2
d1中有文件a和b,
d2中有文件b和c:

root@vultr:~/test_aufs/test1# ls -R

d1 d2

./d1:

a b

./d2:

b c

其中每个文件的值为: d1/a -> 'a', d1/b -> 'b1', d2/b -> 'b2', d2/c -> 'c'
用d1,
d2 mount一个aufs文件系统的目录:

root@vultr:~/test_aufs/test1# mount -t aufs -o dirs=./d1:./d2 none ./mnt

root@vultr:~/test_aufs/test1# ls mnt/

a b c

root@vultr:~/test_aufs/test1# cat mnt/b

b1

可以看到mnt/b中的值为d1/b中的值,而d2/b被丢掉了。 可见mnt多个目录同一个文件名的文件,只保留按顺序第一次出现的那个。

再尝试着更改文件内容:

root@vultr:~/test_aufs/test1/mnt# echo 'new_a' > a

root@vultr:~/test_aufs/test1/mnt# cat ../d1/a

new_a

root@vultr:~/test_aufs/test1/mnt# echo 'new_b' > b

root@vultr:~/test_aufs/test1/mnt# cat ../d1/b

new_b

root@vultr:~/test_aufs/test1/mnt# cat ../d2/b

b2

root@vultr:~/test_aufs/test1/mnt# echo 'new_c' > c

root@vultr:~/test_aufs/test1/mnt# cat ../d2/c

c

root@vultr:~/test_aufs/test1/mnt# cat ../d1/c

new_c

root@vultr:~/test_aufs/test1/mnt#

前几个都好理解,注意往mnt/c中写一段内容后,d2/c的内容并没有改变,反而在d1目录下面出现了一个c,内容为mnt/c的内容,好诡异,这是什么逻辑呢。

原来mount aufs文件系统的目录时,最前面的目录是可写的,而后面的都是只读的,往mnt下面的文件写内容时,会先找到第一个可写的目录,然后更新其内容, 如果文件不存在则会建一个。 d2/c被mnt成只读的了不会改变内容,而且d1目录是可写的,所以会在d1下面新生成一个c文件。

我们还可以试着mount aufs时在目录后面加上:rw, :ro来表示读写和只读,会有不同的结果,但是原理与上段描述的一样,可以猜猜结果会是怎样。

不知道大家有没有用过Ubuntu或Fedora的live系统盘,只要插上光盘就可以运行系统,而且还可以写数据,只不过系统退出后变更的文件就找不到了。当时觉得很神奇,现在想想也正是使用了aufs这种文件系统的特性,只要将光盘和硬盘mount在一起,就可以看上去在光盘上读写数据了。

回到docker,docker的镜像其实就是一些只读层,而容器是在docker镜像上加了一层读写层,这样就可以在不更改镜像的基础上还能像普通vm一样读写数据。 网上有张图比较好:

aaarticlea/jpeg;base64,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" alt="" name="Image1" width="547" height="184" align="bottom" border="0" />

重新理解Docker的各种命令

我们了解了docker的文件系统及namespace功能后,再试图重新理解一下docker的几个命令:

docker images : 列出所有顶层的只读镜像

docker run : 先是利用只读的镜像外加一层可读写的层,并且加了一个被隔离的进程空间来创建了一个容器,然后运行指定的程序。

docker stop : 保留可读写层,收回隔离的进程空间。

docker ps -a : 列出所有包含读写层的容器,包含stop(Exit)状态的。

docker commit : 将当前容器的只读层加可读写层一起产生一个新的只读层做为镜像。

参考:

1. Docker概述

2. docker的使用及原理 知乎

docker原理的更多相关文章

  1. 一篇不一样的docker原理解析

    转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...

  2. docker原理与上帝进程

    做个笔记, 先水一会. 虚拟机指的是: 在软件的层面上通过模拟硬件进行的输入输出. docker原理:docker就是一个linux系统的进程, 它通过 Linux 的 namespaces 对不同的 ...

  3. Docker原理探究

    问题思考:-------------------------------------Docker浅显原理理解-------------------------------------P1. ubunt ...

  4. Docker原理(开发技术分享转发)

    Docker原理Docker是啥Docker是一个程序运行.测试.交付的开放平台,Docker被设计为能够使你快速地交付应用.在Docker中,你可以将你的程序分为不同的 基础部分,对于每一个基础部分 ...

  5. docker原理(转)

    转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...

  6. 一篇文章带你吃透 Docker 原理

    容器的实现原理 从本质上,容器其实就是一种沙盒技术.就好像把应用隔离在一个盒子内,使其运行.因为有了盒子边界的存在,应用于应用之间不会相互干扰.并且像集装箱一样,拿来就走,随处运行.其实这就是 Paa ...

  7. Docker系列(4)- run的流程和docker原理

    回顾HelloWorld流程 底层工作原理 Docker是怎么工作的? Docker是一个Client-Server结构的系统,Docker的守护进程运行在宿主机上.通过Socket从客户端访问 Do ...

  8. docker原理(转)

    可能是把Docker的概念讲的最清楚的一篇文章 [编者的话]本文只是对Docker的概念做了较为详细的介绍,并不涉及一些像Docker环境的安装以及Docker的一些常见操作和命令. Docker是世 ...

  9. docker 原理

    docker项目的目标是实现轻量级的操作系统虚拟化,Docker的基础是Linux容器(LXC)等技术. 在LXC的基础上,Docker做了进一步的封装,让用户不关心容器的管理,使得操作更为简单.用户 ...

随机推荐

  1. Photoshop做32位带Alpha通道的bmp图片

    原文链接: http://blog.sina.com.cn/s/blog_65c0cae801016e5u.html   批量制作32位带Alpha通道的bmp图片,可以制作一个动作,内容可以如下: ...

  2. Linux中iptables防火墙指定端口范围

    我需要700至800之间的端口都能tcp访问 代码如下 复制代码 -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 7 ...

  3. 【转载】Oracle死锁概念,阻塞产生的原因以及解决方案

    参考原文:http://blog.sina.com.cn/s/blog_9d12d07f0102vu72.html 锁是一种机制,一直存在:死锁是一种错误,尽量避免.​ 首先,要理解锁和死锁的概念:​ ...

  4. mysql -- 优化之ICP(index condition pushdown)

    一.为了方法说明ICP是什么.假设有如下的表和查询: create table person( id int unsigned auto_increment primary key, home_add ...

  5. windows如何查看某个端口被谁占用

    我们在启动应用的时候经常发现我们需要使用的端口被别的程序占用,但是我们又不知道是被谁占用,这时候我们需要找出“真凶”,如何做到呢? cmd命令中 输入命令:netstat -ano,列出所有端口的情况 ...

  6. Linux重启命令与如何重启网络?

    分享下Linux重启命令的用法,linux如何重启网络的方法? 第一部分,有关Linux重启命令的用法 1.shutdown2.poweroff3.init4.reboot5.halt *---具体说 ...

  7. Shiro系列(2) - 权限模型以及权限分配的两种方式

    1. 顶级账户分配权限用户需要被分配相应的权限才可访问相应的资源.权限是对于资源的操作一张许可证.给用户分配资源权限需要将权限的相关信息保存到数据库.这些相关内容包含:用户信息.权限管理.用户分配的权 ...

  8. PCIE 调试过程记录

    遇到的问题 PCIE link不稳定 配置空间读写正常,Memory mapping空间读写异常 缘由 之前对PCIE的认识一直停留在概念的阶段,只知道是一个高速通讯协议,主要用于板内.板间的高速BU ...

  9. 隐藏Tengine的版本信息

    http { ..... server_tokens on; server_info on; server_tag bass; reset_timedout_connection on; keepal ...

  10. Fluent UDF【5】:第一个UDF

    这里以一个简单的初始化案例来描述UDF的使用过程. 0 Fluent中的Patch Fluent中提供了全域初始化以及局部Patch功能.对于整体区域的全局初始化可以采用starndard及hybri ...