KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA

00 · 交付包 — keel 龙骨

类型:主题概念 · 应用课对应:01 章 · 为什么「私有化」不是「多买一台服务器」

类型:主题概念 · 应用课对应:01 章 · 为什么「私有化」不是「多买一台服务器」

这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。它不讲怎么安装,也不讲怎么升级。

一、它为什么会出现

一次交付的两头差别很大。我们这边能构建、能从公共仓库取基础镜像、网络抖一下还能重试;客户那边是一台到不了外面的机器,中间只隔着一条能搬东西的通道。

现场的形状是这样的:

我们这边:能 docker build、能从仓库取基础镜像、失败能重试一次
搬运途中:只有 U 盘 / 摆渡机 / 刻录介质,没有人能"顺手看一眼"
客户那边:能做的事只有 docker load,装什么必须已经在手里

需求一句话:把「这次安装需要的全部输入」和「证明它们没在搬运途中坏掉」,装成一份能整体搬动的东西。

它要解决的不是"怎么把文件传过去",而是怎么让对面在没有人陪的情况下,只靠手里这一份东西把系统装起来。

二、它是什么

一句话:交付包 = 一次安装所需的全部输入 + 一份完整性证明,被打成一个可以整体搬运的目录。

四个名字先分清,后面几页都会用到:

名字 它指什么
board-delivery-1.0.0/ 交付包本身
board-delivery-1.0.0.tar.gz 它在搬运通道上的形态,160M
images/board__1.0.0.tar 包内最重的一件制品(未压缩)
MANIFEST.sha256 那份完整性证明

它不是下面这三样东西——混淆了就会做错取舍:

三、它长什么样

它长成一个目录,顶层每一行都有职责:

board-delivery-1.0.0/
  MANIFEST.sha256              每个制品的哈希
  images/
    board__1.0.0.tar           应用镜像(docker save 直出,未压缩)
    postgres__16-alpine.tar    数据库镜像 —— 别漏了这个
  compose.yml                  客户内网版编排文件,被直接使用的那一份
  env.example                  配置模板;真的 .env 由安装脚本照它现场生成
  install.sh                   客户唯一需要知道的那条命令
  upgrade.sh  rollback.sh  selfcheck.sh

它由两条 docker save 加一句 tar -czf 做出来,两条都不能省:

docker save --output "images/board__${VERSION}.tar" "${APP_IMAGE}"
docker save --output "images/postgres__${DB_IMAGE##*:}.tar" "${DB_IMAGE}"

应用镜像准备得再完整,客户机器上没有 postgres,编排一样会去仓库取,然后在没有出口的网络里挂到超时。

体积读数放在一起看,重量在哪就一目了然:

基础镜像 python:3.12-slim            179MB
应用镜像 board:1.0.0                 215MB
  其中:依赖层(一个 venv)           28.2MB
  其中:应用代码层                    61.4kB
交付包 board-delivery-1.0.0.tar.gz   160M

四、它怎么工作

从一张 Dockerfile 到一个能搬走的包,是五步:

① 构建   在我们这边把应用镜像做出来,版本号取自代码里自己的那一份声明
   ↓
② 备料   确保数据库镜像也在本地(不在就取一次)
   ↓
③ 立据   对包内每一个文件算 sha256,写进 MANIFEST.sha256
   ↓
④ 打包   整个目录压成一个 tar.gz,这是它上搬运通道时的形态
   ↓
⑤ 搬运   穿过介质缝隙;到对面之后第一件事是对这份清单,而不是先安装

第 ③ 步是这五步里唯一"凭空多出来"的一步:它不产出任何功能,它只产出一件东西——让对面能在动手之前判断"这份包有没有坏"。

五、它会带出哪些概念

六、回到应用课

应用课里的那句话 现在你知道它为什么成立
"把跑起来所需的一切放进一个能被搬动的介质里" "一切"要落到具体文件上:两个镜像、一份编排、一份模板、四个脚本、一份清单
"装什么必须提前就在介质里,现场没有可装的东西" 所以编排文件里只有 image:、没有 build:;镜像只能随包直送
"跨过那条介质缝隙之后,第一件要能做的事是「这份包有没有坏」" 那一件东西就是 MANIFEST.sha256,它存在的理由只有这一个
"env.example 里密码位是空的" 密钥不进包——它只能在生成现场配置那一刻产生

这一页改变了你的哪个判断:拿到一个交付目录,你不再先问"东西齐不齐",而是先问**"这里面哪几样丢了要回到有外网那台机器重来、哪几样随时能再生"**——前一类只有 MANIFEST.sha256 和 images/ 下那两个 tar。

→ 这一页的展开在应用课 01 章 · 为什么「私有化」不是「多买一台服务器」。

自测题

  1. 一个交付包里,哪几样东西丢了就必须回到有外网的那台机器上重打一次?其余的为什么随时能再生?
  2. 包内的 board__1.0.0.tar 为什么不压缩,而外面还要再压一层 .tar.gz?

进入 keel 阅读