# 4. 标准极简容器runC

## introduction

这玩意儿是啥, 有点神秘 , 名字带run都有点神秘, 神秘 (神必). 现在你知道 (顿), 容器相关的神奇表现是怎么搞出来的, 但你也知道 (顿), 这些是我们自己打的草稿, 离真正的docker, 架构那些设计, 还有一些距离. **我想弥补这些距离, 讲真的, 我想弥补这些距离**

1. **linux**, 提供了一些可以拿来隔离的手段
2. **libcontainer**, 包装了这些手段, 然后你调用库函数就能实现隔离
3. **runC**, 包装了这个库, 变成了一个启停容器的命令行的工具
4. **docker**, 包装了runC, 变成了一个特性丰富的, 管容器的, 命令行的工具

为什么呢? 你要包装一下LinuxAPI方便docker调用我可以理解, 但为什么要做出两套命令行工具呢? 原因是某一天大家觉得容器真好用, 于是每家就都想自己做出一套自己的容器, 整出自己的"Docker". 可是这样不行, 容器引擎五花八门就跟铁轨修的乱七八糟一样麻烦. 于是就找来几家大佬, 说你们自研没问题, 但我们得符合一些容器规范, 于是我们就有了Open Container Format规范, Docker说好的我提供一种引擎能起容器, 也符合这套规范, 于是就有了runC

## 我们希望这个引擎能够:

那么关于这套标准, 他是这样说的: 我们希望这个引擎能不受硬件制约, 无论在任何架构上, 你的引擎都能起出一模一样的容器. 同时我们希望你的引擎应该老老实实的做好一个引擎该做的事, 无论是什么客户端, 无论是任何编排工具来了都能通过调你接口起容器. 标准里, 启动一个容器需要的材料包含:

* **config.json , 配置文件** : 比如环境变量, 初始(pid=0)进程的运行参数, 配置信息, 是否绑定终端, 内存限制, 文件系统的挂载点设置, 支持设置容器运行前/后执行的脚本文件(钩子)
* **rootfs**, 包含 /bin, /lib等, 值得一提, 为了能起容器我们其实只要求rootfs下包含所需要的目录与文件, 但是并没有要求过镜像. 镜像这种特性其实是docker为了方便存储rootfs自己想出来的, runC作为纯粹的容器引擎, 没有

👆除去上面用于启动一个容器的文件, 我们还需要为每个容器生成一个名为 **state.json** 的文件, 用于记录容器的运行状态. 里面包含有 容器ID, pid 等.
