Docker诞生于2013年,并普及了容器的概念,以至于大多数人仍然将容器的概念等同于“Docker容器”。
作为第一个吃螃蟹的人,Docker设置了新加入者必须遵守的标准。例如,Docker有一个大型系统镜像库。所有的替代方案都必须使用相同的镜像格式,同时试图改变Docker所基于的整个堆栈的一个或多个部分。
在此期间,出现了新的容器标准,容器生态系统朝着不同方向发展。现在除了Docker之外,还有很多方法可以使用容器。
在本文中,我们将介绍以下内容:
-
将Chroot、cgroups和命名空间作为容器的技术基础
-
定义Docker所基于的软件堆栈
-
说明Docker和Kubernetes需要坚持和遵守的标准
-
介绍替代解决方案,这些解决方案尝试使用具有更好更安全的组件来替换原始Docker容器。
容器的软件堆栈
像Chroot 调用、 cgroups 和命名空间等 Linux 特性帮助容器在与所有其他进程隔离的情况下运行,从而保证运行时的安全性。
Chroot
所有类似Docker的技术都起源于类似Unix操作系统(OS)的根目录。在根目录上方是根文件系统和其他目录。
从长远来看,这是很危险的,因为根目录中任何不需要的删除都会影响整个操作系统。这就是为什么存在一个系统调用chroot()。它创建了额外的根目录,例如一个用于运行遗留软件,另一个用于包含数据库等等。
对于所有这些环境,chroot似乎是一个真正的根目录,而是实际上,它只是将路径名添加到任何以/开头的名字上。真正的根目录仍然存在,并且任何进程都可以引用指定根目录以外的任何位置。
Linux cgroups
自2008年2.6.24版本以来,Control groups (cgroups)一直是Linux内核的一项功能。Cgroup将同时限制、隔离和测量多个进程的系统资源(内存、CPU、网络和I/O)使用情况。
假设我们想阻止用户从服务器发送大量电子邮件。我们创建了一个内存限制为1GB、CPU占用率为50%的cgroup,并将应用程序的 processid添加到该组中。当达到这些限制时,系统将限制电子邮件发送过程。它甚至可能终止进程,这取决于托管策略。
Namespaces
Linux命名空间是另一个有用的抽象层。命名空间允许我们拥有许多进程层次,每个层次都有自己的嵌套“子树(subtree)”。命名空间可以使用全局资源,并将其呈现给其成员,就像它是自己的资源一样。
具体来看,Linux系统开始时的进程标识符(PID)为1,并且所有其他进程将包含在其树中。PID命名空间允许我们跨越一棵新树,它拥有自己的PID 1进程。现在有两个值为1的