很久之前就了解使用过docker,但是之后就慢慢淡忘了,并且一直没有真正了解下docker底层的基本原理。
然后今天想好好学习一下,这只是我的一个总结,大家可以直接去看陈皓大大的几篇博客。
DOCKER基础技术:LINUX NAMESPACE(上)
DOCKER基础技术:LINUX NAMESPACE(下)
DOCKER基础技术:LINUX CGROUP
DOCKER基础技术:AUFS
DOCKER基础技术:DEVICEMAPPER
以下内容大部分来自陈皓大大的博客,只是作为个人学习资料进行总结。
Namespace解决的问题主要是环境隔离的问题
Linux CGroup解决对计算机资源使用上的隔离
一、Namespace
首先了解下Linux Namespace,是Linux提供的一种内核级别环境隔离的方法,提供了对UTS、IPC、mount、PID、network、User等的隔离机制。
UTS命名空间使得不同的UTS命名空间有不同的主机名和域名。
IPC全称 Inter-Process Communication,是Unix/Linux下进程间通信的一种方式,IPC有共享内存、信号量、消息队列等方法。所以,为了隔离,我们也需要把IPC给隔离开来,这样,只有在同一个Namespace下的进程才能相互通信。
新建进程的时候加上CLONE_NEWIPC
参数就没法共享信息。
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | CLONE_NEWIPC | SIGCHLD, NULL);
- 加上
CLONE_NEWPID
之后新建进程pid变为1,我们知道,在传统的UNIX系统中,PID为1的进程是init,地位非常特殊。他作为所有进程的父进程,有很多特权(比如:屏蔽信号等),另外,其还会为检查所有进程的状态,我们知道,如果某个子进程脱离了父进程(父进程没有wait它),那么init就会负责回收资源并结束这个子进程。所以,要做到进程空间的隔离,首先要创建出PID为1的进程,最好就像chroot那样,把子进程的PID在容器内变成1。
但是,我们会发现,在子进程的shell里输入ps,top等命令,我们还是可以看得到所有进程。说明并没有完全隔离。这是因为,像ps, top这些命令会去读/proc文件系统,所以,因为/proc文件系统在父进程和子进程都是一样的,所以这些命令显示的东西都是一样的。
所以,我们还需要对文件系统进行隔离。
int container_pid = clone(container_main, container_stack+STACK_SIZE,
CLONE_NEWUTS | CLONE_NEWIPC | SIGCHLD, NULL);
我们在启用了mount namespace并在子进程中重新mount了/proc文件系统。这里,多说一下。在通过CLONE_NEWNS创建mount namespace后,父进程会把自己的文件结构复制给子进程中。而子进程中新的namespace中的所有mount操作都只影响自身的文件系统,而不对外界产生任何影响。这样可以做到比较严格地隔离。
我们还有别的一些文件系统也需要这样mount。User Namespace
Network Namespace
二、Linux CGroup
Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。
三、AUFS
四、DEVICEMAPPER