前面和大家简要介绍了容器技术的发展,我们都知道了容器最核心的是实现了要用服务资源隔离。那么到底容器是如何实现资源隔离的呢?实际上依赖了Namespace(命名空间)、Cgroups(控制组)以及Union File System(统一文件系统)等底层Linux内核技术。
Namespace
我们先来看下wiki中关于Linux Namespace的描述:
Namespaces are a feature of the Linux kernel that partitions kernel resources such that one set of processes sees one set of resources while another set of processes sees a different set of resources. The feature works by having the same namespace for a set of resources and processes, but those namespaces refer to distinct resources.
这描述看上去就很绕,总结一下就是Linux Namespace是Linux kernel提供的一种进行资源隔离的底层能力。通过Namespace实现对服务器全局资源的封装隔离,使得不同Namespace中的进程互相独立,彼此透明。
在一台宿主服务器当中,Linux的Namespace实际就是Linux内核中资源隔离的实现方式。玩过Docker的同学都知道,到我们run了一个docker镜像之后,在服务器中就会产生一个docker容器,当我们进入到容器里面去之后,使用ps命令查看,我们会惊奇的发现容器中运行的服务pid=1。相当于这个服务是容器内的第一号进程。而如果我们在服务器中运行这个服务,操作系统会给这个服务进程分配一个全局唯一的进程号,假设是34134。同样是这个程序在服务器中运行pid时34134,但是在Docker容器中的pid却是1。这是怎么回事呢?
这种隔离技术就是Namspace机制,通过Namespace构建了一个全新的运行环境,与其他运行环境互相透明,让服务在这个小空间里面自封为王。实际上是Linux kernel内核提供的系统调用函数clone()。通过clone函数创建的新进程会在一个全新的进程空间当中。因此实际上容器的本质还是进程,只不过是一种特殊的进程,在创建它的时候指定了一些参数,使得容器只能访问到当前Namespace内的文件、IO等资源。
Cgroups
Namespace机制帮助我们解决了资源隔离的问题,那么仅仅只是隔离对于容器运行来说就够了吗?虽然在容器内部应用服务可能是个王者,资源都是他独享的,但是映射到服务器内核当中的真实的进程后它就是个各个普普通通的青铜,需要和其他青铜共享计算机各类资源。显然这不是我们想要的容器的效果。而Linux Cgroups技术就是帮助我们设置资源限制的功能。Linux Cgroups即Linux Control Group就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
在Linux操作系统中,Cgroups的能力通过内核的文件系统操作接口暴露出来的,它是以文件和目录的方式组织在操作系统的/sys/fs/cgroup路径下。