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 是两个卷
   ↓
④ 分口   唯一不能自动分开的东西是对外端口,它必须有人显式分配并记下来

第 ④ 步是这套模型里唯一需要"有人记一笔"的地方:前缀与数据都是自动跟着走的,端口不是。

五、它会带出哪些概念

六、回到应用课

应用课里的那句话 现在你知道它为什么成立
"「实例」这个词在这一课里有一个精确的判据" 判据就是那三样东西:前缀、配置、数据,缺一样就指认不出来
"name: 决定这套实例的资源前缀" 前缀是派生出来的,所以改一个值能换掉容器名、网络名、卷名这一整套
"数据必须跟着前缀走" board_pgdata 与 board2_pgdata 是两个卷;少这个前缀就是两个客户共用一份数据库
"对外端口必须显式分配" 端口是三者里唯一不会自动分开的东西,它必须有人去分配、去登记

这一页改变了你的哪个判断:装第二套时你不再先问"配置改了吗",而是先问**"容器名、网络名、卷名这几个前缀是不是都跟着换了,端口有没有人记过一笔"**。

→ 这一页的展开在应用课 05 章 · 一套代码、多个客户:配置注入与实例隔离。

自测题

  1. 「实例」由哪三样构成?为什么"少任何一样能被独立指认"就会破坏多实例?
  2. 两套实例的资源名前缀不同,为什么数据库端口相同却不会冲突?

进入 keel 阅读