docker其实并没有实现什么新的技术,而是在linux的系统调用之上做了封装,达到了非常好的用户体验,让人们感觉好像是跑的一个虚拟机一样。
对比虚拟机技术在同一个宿主机上建立多个操作系统实现的彻底的进程隔离,这样的实现方式要跑多个操作系统,带来了非常大的资源开销。而docker容器技术则是通过一系列的namespace实现进程隔离,这是一种内核级别隔离系统资源的方法。
namespace隔离类型:
- uts namespace
uts(unix time-sharing system)namespace提供了主机名与域名的隔离,这样每个docker容器就可以拥有独立的主机名和域名了,在网络上可以被视为一个独立的节点,而非宿主机上的一个进程。 - ipc namespace
进程间通信(inter-process communication, ipc)涉及的ipc资源包括常见的信号量、消息队列和共享内存。在同一个ipc namespace 下的进程彼此可见,不同ipc namespace下的进程则互相不可见。 - pid namespace
pid namespace隔离非常实用,它对进程pid重新标号,即两个不同namespace 下的进程可以有相同的pid。每个pid namespace都有自己的计数程序。内核为所有的pid namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace,它创建的新pid namespace被称为child namespace(树的子节点)。通过这种方式,不同的pid namespace会形成一个层级体系。所属的父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。反过来,子节点却不能看到父节点pid namespace中的任何内容。
linux的namespace详细参见:浅谈linux namespace机制
docker是通过clone()接口在创建新进程的同时创建namespace。
int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);
我们在宿主机上使用ps aux查询该操作系统中所有的进程,可以发现有这么多
创建一个容器并进入到容器内部,同样执行ps aux,发现就两个