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. xcode修改项目名后反复出现 clang error

    xcode修改项目名后反复出现 clang error,  提示 ld: file not found . 并且该错误并不是出现在项目编译阶段,而是项目的Tests 的link阶段, 同时提示 xct ...

  2. PowerShell 批量签入SharePoint Document Library中的文件

    由于某个文档库设置了编辑前签出功能,导致批量导入文件时这些文件默认的状态都被签出了.如果手动签入则费时费力,故利用PowerShell来实现批量签入Document Library中的文件. Reso ...

  3. Python 文件 next() 方法

    描述 Python 3 中的 文件 对象不支持 next() 方法. Python 3 的内置函数 next() 通过迭代器调用 __next__() 方法返回下一项. 在循环中,next()方法会在 ...

  4. 10.翻译:EF基础系列---EF中的持久性

    原文链接:http://www.entityframeworktutorial.net/EntityFramework4.3/persistence-in-entity-framework.aspx ...

  5. STM32的JTAG下载模式

    SWJ:串行线JTAG配置 (Serial wire JTAG configuration)  SWJ(串行线JTAG)支持JTAG或SWD访问Cortex的调试端口. 系统复位后的默认状态是启用SW ...

  6. 并发测试 JavaDemo

    https://github.com/oldratlee/fucking-java-concurrency /** * @author Jerry Lee */ public class Testee ...

  7. Java:集合,Arrays工具类用法

    1. 描述 Arrays工具类提供了针对数组(Array)的一些操作,比如排序.搜索.将数组(Array)转换列表(List)等等,都为静态(static)方法: binarySearch - 使用二 ...

  8. 【SSH】Hibernate关联映射

    一对一关联映射 一对一主键关联映射    一句话:不加字段.主键既是主键又是外键. 一对一单向主键关联映射 配置: <span style="font-family:KaiTi_GB2 ...

  9. Android 消息分发机制

    Android 中针对耗时的操作,放在主线程操作,轻者会造成 UI 卡顿,重则会直接无响应,造成 Force Close.同时在 Android 3.0 以后,禁止在主线程进行网络请求. 针对耗时或者 ...

  10. Atitit  undac网络设备管理法案 (路由器 交换机等)    法案编号USRr101510

    Atitit  undac网络设备管理法案 (路由器 交换机等)    法案编号USRr101510 1.1. 版本历史1 1.2. 密码设置规范 与原则1 1.3. 如何设置密码 ,设置一个简单又安 ...