KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
02 · 实例 — keel 龙骨
类型:主题概念 · 应用课对应:05 章 · 一套代码、多个客户:配置注入与实例隔离
类型:主题概念 · 应用课对应:05 章 · 一套代码、多个客户:配置注入与实例隔离
这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。它不讲怎么给实例命名。
一、它为什么会出现
第二个客户来了。他不能和第一个客户共用一套部署——数据要分开、端口要分开、升级节奏也要分开。但机器还是那一台,镜像还是那一张。
装上之后,那台机器上同时跑着六个容器、两个编排项目:
$ docker compose ls
NAME STATUS CONFIG FILES
board running(3) ...board-delivery-1.0.0\compose.yml
board2 running(3) ...board-delivery-1.0.0-b\compose.yml
它们用的是同一个镜像、同一份编排文件,两份配置之间只差三行。
需求一句话:一套代码不等于一套部署,也不等于一个客户;能各自独立指认,才叫两套。
二、它是什么
一句话:一个实例 = 一个资源名前缀 + 一份配置 + 一份数据。
三者里换掉任何一个,都等于换了一个实例;三者里少任何一样能被独立指认,多实例就不成立。
它不是下面这三样东西:
- 不是"一个客户"。 同一个客户的演示、测试、生产可以是三个实例——判据不落在"人"上。
- 不是"一份配置"。 配置只是三者之一;只有配置、而没有跟着走的前缀与数据,第二套会直接接管第一套的资源。
- 不是"一次部署动作"。 部署是动词,做完就结束了;实例是部署完之后仍然能被单独点出来的那个东西。
三、它长什么样
三者各自落在什么地方,看这一行就够——编排文件的第一行:
name: ${BOARD_INSTANCE_NAME:-board}
name: 决定这套实例的资源前缀。容器名、网络名、卷名都会带上它,所以改这一个值,就换了一整套命名空间:
board-db-1 5432/tcp
board-web-1 0.0.0.0:8080->8080/tcp
board-worker-1 8080/tcp
board2-db-1 5432/tcp
board2-web-1 0.0.0.0:8090->8080/tcp
board2-worker-1 8080/tcp
那份配置差的三行,正好对上三样东西:
BOARD_INSTANCE_NAME board / board2 ← 前缀
BOARD_HTTP_PORT 8080 / 8090 ← 对外端口
BOARD_JOB_SECONDS 3 / 20 ← 不是隔离必需的(见下一节)
注意那两个 5432/tcp:数据库没有映射到宿主机端口。 两套实例的 postgres 各占一个 5432,外面看不到任何一个——这是 01 页 那条 internal: true 的直接后果。
四、它怎么工作
一套代码变成两套独立的部署,四步:
① 分名 两份配置的 BOARD_INSTANCE_NAME 取不同的值
↓
② 派生 编排层据此派生出容器名、网络名、卷名的整套前缀
↓
③ 分资 数据卷与网络跟着前缀走:board_pgdata 与 board2_pgdata 是两个卷
↓
④ 分口 唯一不能自动分开的东西是对外端口,它必须有人显式分配并记下来
第 ④ 步是这套模型里唯一需要"有人记一笔"的地方:前缀与数据都是自动跟着走的,端口不是。
五、它会带出哪些概念
- 交付包:包里带的是制品与脚本;实例是包外那一份配置造出来的。→ 00 页
- 内网隔离:不需要对外的服务不要对外,正是多套部署能并存的前提。→ 01 页
- 停机窗口:同一份编排里两个实例可以对同一个参数取不同的值——这正是它能被当成实验台的原因。→ 04 页
六、回到应用课
| 应用课里的那句话 | 现在你知道它为什么成立 |
|---|---|
| "「实例」这个词在这一课里有一个精确的判据" | 判据就是那三样东西:前缀、配置、数据,缺一样就指认不出来 |
"name: 决定这套实例的资源前缀" |
前缀是派生出来的,所以改一个值能换掉容器名、网络名、卷名这一整套 |
| "数据必须跟着前缀走" | board_pgdata 与 board2_pgdata 是两个卷;少这个前缀就是两个客户共用一份数据库 |
| "对外端口必须显式分配" | 端口是三者里唯一不会自动分开的东西,它必须有人去分配、去登记 |
这一页改变了你的哪个判断:装第二套时你不再先问"配置改了吗",而是先问**"容器名、网络名、卷名这几个前缀是不是都跟着换了,端口有没有人记过一笔"**。
→ 这一页的展开在应用课 05 章 · 一套代码、多个客户:配置注入与实例隔离。
自测题
- 「实例」由哪三样构成?为什么"少任何一样能被独立指认"就会破坏多实例?
- 两套实例的资源名前缀不同,为什么数据库端口相同却不会冲突?