最近容器化技术比较火热,所以出于兴趣,我打算自己造一个玩,下面就是造轮子的一点小小记录。
主要涉及到的内容
容器技术本身是建基于 *nix 的某些内核功能产生的轻量级隔离环境,或者说是准虚拟化系统,涉及到的内核功能在下面列出。
- namespace
namespace
算是容器技术的基础之一,它提供了简单的限制应用可访问的资源的方式。它能限制的资源包括但不限于网络,挂载点,用户等。 - chroot/pivot_root
chroot
作为一个古老的控制文件系统访问的方式,很早就被用来提高平台的安全性(cPanel 等网站托管平台经常使用 chroot 来隔离不同用户的网站)。而pivot_root
与chroot
的主要区别是,pivot_root
会将进程的根挂载点也切换过去 - cgroups
cgroups
其实是容器外围的一个不太必须的组件,它的主要作用是控制一组进程(容器进程等)的资源占用。 - overlayfs
overlayfs
也并不是容器的必须组件,但它提供了在容器间共享基础“镜像”的功能。
一个容器的启动流程
- 首先我们启动我们的容器控制进程,它就相当于这个新世界里的
init
- 在读取完运行时参数之后,利用
unshare/fork
系统调用创建namespace,fork出的进程是容器里的第一个进程。同时主进程负责创建网桥等通信机制和uid映射等。 - 在进入新命名空间后,利用
bind mount
挂载容器的根文件系统,之后利用 overlayfs 挂载基础镜像和容器的各“层”。 - 通过
pivot_root
和chroot
进入新的根文件系统。 - 启动容器中要运行的进程,整个过程完成。
题外话:关于gVisor
Google 的 gVisor 采用了一个更另类的方式增加安全性,在不考虑kvm的情况下,gVisor的进程通过使用 ptrace
挂钩目标程序的系统调用并进行过滤来防止恶意攻击(如 ditrycow 等),稍晚可能去试着实现一个轻量级的 gVisor。