KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

02 · 容器 — keel 龙骨

类型:主题概念 · 应用课对应:01 章 §一、06 章 · 信号与优雅停机

类型:主题概念 · 应用课对应:01 章 §一、06 章 · 信号与优雅停机

这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。

一、它为什么会出现

一台机器上要跑十个服务,每个服务自带自己的依赖,而十个服务用的库版本还互相冲突。把它们直接装在同一台机器上,迟早会打起来。

它面对的需求是两件事同时成立:互相隔离,而且不要虚拟机的代价。

虚拟机确实能隔离,但每一台都自带一个内核、都要走一遍引导流程——启动慢、内存占用高;而你现在想跑的是一个进程,不是想模拟一台机器。

二、它是什么

一句话:容器 = 一份只读的镜像 + 一个可写层 + 一个进程。

这个定义里有三处经常被读错:

三、它长什么样

docker run -d --name api -p 3000:3000 myapp:1.7.2

这一行的读法是"在只读镜像之上,加一个可写层,起一个进程":

容器 = [ 镜像:只读的层堆叠 ]
       [ 可写层:这次运行产生的一切改动都写在这里 ]
       [ 进程:config 里 CMD 指定的那条命令 ]
       + 边界:文件系统 / 进程视图 / 资源视图,都是宿主的切片

两个日常现象,从这张结构直接读出来:

四、它怎么工作

从 docker run 到进程跑起来,是四步:

① 解压    把镜像的层按顺序叠加,拼成一个只读的根文件系统
② 加层    在最上面加一个空的可写层,之后所有写入都落在它上面
③ 起进程  按 config 拉起 CMD 指定的进程,并把它放进隔离边界里
④ 收尾    收到停止信号 → 等一段时间 → 没退出就强杀(应用课 06 章整章讲这段时序)

第 ③ 步里"隔离边界"具体由哪些机制实现,本页不展开——那属于内核文档的范围。这一层只需要一个判断:某件事能不能在容器里做,先问一句"它需要动内核吗"。

五、它会带出哪些概念

六、回到应用课

应用课里的那句话 现在你知道它为什么成立
"容器不是小虚拟机" 差别只在一条上:内核是共享的。隔离单位是进程,不是硬件
"容器无状态" 可写层不持久;要留下东西就必须落到卷或外部存储上
"容器停止时,正在处理的请求会不会被切断" 信号发给容器里的 1 号进程;它有没有把信号转给真正干活的进程,看 CMD 是哪种写法

这一页改变了你的哪个判断:听到"要在容器里做某件事"时,你先分流——是要动内核(做不了或要特权),还是只是文件与进程层面的事(正常做)。这一问能挡掉大部分返工。

自测题

  1. 容器里 rm -rf /app/node_modules 之后,镜像体积变了吗?为什么?
  2. "容器里不能装自己编译的驱动"——这是配置没写对,还是模型限制?

进入 keel 阅读