KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
01 · 它到底解决了什么问题 — keel 龙骨
## 现场:那句"在我机器上是好的"
现场:那句"在我机器上是好的"
你写了一个小程序,在自己电脑上跑得好好的。发给同事,他打开就报错:ModuleNotFoundError,或者 command not found。
你们开始对:他装的是这个版本,你装的是另一个;他系统里没有那个库;他的环境变量没配。
对到第三轮,对话就变成那句所有人都说过的话:
在我机器上是好的。
问题不在于谁错了。问题在于:程序要跑起来,依赖的不只是代码,还有它脚下的那一整片环境——
运行时版本、系统库、环境变量、路径、时区。代码可以用 Git 传来传去,
那这片环境能不能也整份搬过去?
Docker 就是为这件事做出来的。
一、它是什么
一句话:Docker 把"一个程序 + 它需要的运行环境"打成一个能整份搬运的包,让它在哪台机器上都跑得一样。
它自己打的比方是集装箱。这个比喻有用,但要落到具体东西上才算数——
集装箱解决的问题是:不管里面装的是家具还是水果,吊车和货轮只需要认识箱子。
Docker 里对应的是这两个东西,它们是最容易混的一对:
| 名词 | 一句话 | 类比 |
|---|---|---|
| 镜像(image) | 一个打包好的、不会被改动的文件包——里面是程序和它要的环境 | 一张光盘:内容固定,可以刻很多张 |
| 容器(container) | 镜像跑起来之后的那一份实例——它自己产生的改动都在它自己身上 | 光盘放进播放机里放的那一次 |
记住这一条就够了:镜像是模板,容器是模板跑起来的那一份。
一张光盘可以放很多次,每一次播放就是独立的一次"容器"。
这两个词更完整的来历和形态,在《Docker 概念课》里各有一页
(镜像、容器)。
现在不需要点进去。
二、跑一条命令看看
先不解释,先看它长什么样。装好 Docker 之后(安装步骤不在本课范围内),敲这一行:
docker run hello-world
docker run 三个字的读法是"把某个镜像跑起来"。hello-world 是镜像的名字——
一个专门用来验证安装是否成功的、极小的镜像。
你会看到类似这样的输出:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
⚠️ 未实测:成稿时本机 Docker daemon 未运行,以上是官方文档给出的标准输出形状。
你实际看到的版本号、下载行数会不同——要读的是形状。
这段输出里发生了两件事,正好对应上面那两个词:
Unable to find image ... locally→Pulling:本机没有这个镜像,所以先去下载它;Hello from Docker!:镜像下载完之后,Docker 把它跑了起来——这句话是容器里跑出来的。
同一个镜像再跑第二次,就不会再看到 Pulling 那几行了:镜像已经在本地,
这次只是又跑了一次容器。
三、它不是什么
零基础最容易建立错的三条印象,先纠正:
- 不是虚拟机。 虚拟机是"在一台机器里模拟出一台完整的电脑",它自带一个操作系统内核;
容器共享你本机的内核,所以启动快得多,也不额外占一个操作系统的内存。
推论:容器里做不了"要动内核"的事——装自己编译的驱动、改内核参数,都不行。
这不是配置没写对,是模型本身的边界。 - 不是云平台。 Docker 装在你自己电脑上;只要镜像已经在本地,断网也能跑。
- 不是"必须会写代码才能用"。 你完全可以只跑别人做好的镜像,一个字代码都不写。
读完你能做什么
- 说清镜像和容器的区别,并能用一句话讲给别人听;
- 读懂
docker run hello-world的输出里,哪些行属于"下载镜像"、哪些行属于"容器在跑"; - 说出容器和虚拟机差在哪一条上。
下一步:现在你知道它是什么了。下一章把"跑一次"这件事做完整——
跑一个你能用浏览器打开的、真正的服务。