前言
之前有写过一个 OJ 业务项目放在简历上,那么 OJ 最重要的是评测模块,它的核心思想就是拿到用户代码,执行后,返回结果,当然这是从功能角度来说,从评测本身角度来说,我们更多考虑的是安全问题,因为用户代码是具有不确定性的,我们往往不能直接运行或者说起码要采取一些措施,否则不被信任的代码如果直接被运行很可能对我们的服务器造成损害:比如用户代码可能包含 fork 炸弹、恶意网络请求、死循环等,我们需要有一些手段去控制,那么就需要一个”黑盒“,它能够提供这么一种环境,对用户的代码进行一些限制。那么这个黑盒就是我们常说的“容器”。
提到容器我们都知道 Docker,理所当然的,我的评测也是利用了 Docker 去做,效果也很不错。但如果说在简历上要体现你的能力,只用 Docker 肯定不行,毕竟 Docker 已经把一切都封装好了,你只需要输入一些命令,传入一些参数就可以做到,没有什么技术价值,任何人都能做,面试没有亮点,那么说到这里,再结合标题,其实就能知道所谓的“亮点”和“含金量”是什么了,对,就是自己再手写一个 Docker。当然本次手写不仅仅是这种功利的初衷,更多的是希望去学习容器的底层技术。
概述
那么容器,我们刚刚提到了,它是作为一种限制进程的工具,在 Linux 内核中,也是提供了几种技术供我们实现该需求:Namespace 和 Cgroup。这里只是大概描述功能,后面再展开讲。Namespace命名空间,它主要能力是,它能让进程有独立的系统视图(包括进程视图、网络视图、挂载视图等),让进程之间互不干扰,对评测来说最简单的,就是不让它干涉我们的主机进程;Cgroup 控制组,它的能力是,对于操作系统上的所有进程,它们都有一个对应的控制组,这个控制组能对它所管控的这些进程进行资源的限制,比如 CPU、Memory 等,防止一个或多个进程占用过多的系统资源。