Skip to content

计算

所有产品运行的基础。任意 OCI 镜像,每个实例都是独立的 Firecracker microVM;带键或不带键的实例,实例何时休眠、什么会唤醒它,以及方块和沙箱如何构建在它之上。

更新于

计算是 Glac 的产品运行的基础。它在实例中运行任意 OCI 镜像,公开或私有都可以(就是 docker 构建、镜像仓库提供的那种):每个实例都是一个独立的 Firecracker microVM。方块和沙箱是构建在它之上的产品,云盘则为它的实例提供不随实例消失的磁盘。

实例

实例是唯一在运行的东西:方块或沙箱运行的一切,都运行在实例中。

  • 一台独立的虚拟机。镜像的各层被解包成根文件系统,Firecracker 用平台的内核启动它:中间没有 Docker,也没有第二层虚拟机。命令和文件经由实例内部的代理程序到达它,而不是经由它的网络。实例中的一切都属于同一个项目。
  • 模板的副本。模板是一个启动过一次并被保存下来的镜像:包括它的内存、设备和磁盘。实例都是它的副本,所以模板启动的程序在每个实例中都已经在运行,程序用的内存在实例改动之前都是共享的。方块的实例是其版本模板的副本。从某个镜像创建的第一个沙箱要等平台拉取镜像、构建模板;之后的沙箱都是副本。
  • 规格。vCPU 和内存,不能超过套餐允许的上限:免费版为 2 vCPU 和 4 GiB,付费版为 8 vCPU 和 16 GiB。不指定规格时,各产品有自己的默认值:参见创建沙箱和什么是版本。
  • 带键或不带键。不带键的实例是众多实例中的一个,由平台挑选:方块的请求会送到它当前版本的实例,这些实例在有请求时启动。带键的实例有名字,带着这个键的一切都会到达这一个实例。沙箱就是键控实例,用 id 或名称指定。方块也可以有键控实例:带键的请求(放在请求头或路径的某一段中)都会送到这个键自己的实例(键控实例)。

无状态与有状态

计算可以保存状态,也可以不保存,按实例而定。

  • 休眠的实例保留它原有的一切:内存、进程、磁盘和网络位置。醒来时,打开的连接继续。sleep_tier 说明它如何休眠:paused(保持在宿主机内存中)、saved(内存保存在宿主机上)或 disk,即只剩下磁盘:下一次调用从磁盘启动它,之前运行的东西都没了。
  • 无状态:方块中不带键的实例(除非它把数据保存在自己的云盘上,见下文)。在 delete_after_ms(默认一小时,可以设得更短)内没有任何东西让它保持运行的实例会被删除,下一个请求会从模板创建新实例。必须长久保存的东西不要放在这样的实例里。
  • 有状态:会被保留的实例。沙箱一直保留到你删除它,或者你设置的规则删除它(expires_at、delete_after_idle_ms,或项目的 delete_after_idle_days);只是休眠不会删除任何东西。方块的键控实例连同内存和磁盘一起保留,供带同一个键的下一个请求使用,keys.delete_after_idle_ms 会在它休眠这么久之后删除它。有自己云盘的方块只有一个实例,一直保留到你删除它,运行在持有云盘的机器上(保存数据的服务)。
  • 任何实例消失后都必须保留的东西放在云盘上,云盘在写入的同时被复制到所在区域的对象存储中。

区域

共有三个区域:na、eu 和 ap。沙箱和云盘各自创建在其中一个区域;方块运行在它指定的每个区域中,请求在它进入的区域得到响应。每样东西在哪里创建,以及区域无法承接时会怎样,见区域。

休眠与唤醒

空闲的实例会进入休眠,之后由需要它的东西唤醒:没有专门的唤醒调用。怎样算空闲取决于产品:

方块的实例 沙箱
何时保持运行 它正在响应请求(打开着的 HTTP/2 流,比如一次 gRPC 调用,在结束前都算),有 API 调用在使用它,或者它里面的程序让它保持运行。CPU、网络包、打开的连接和定时器都不算。 有调用在等它,它的程序平均占用至少一个核心的 2%,有网络包经过它的网络链路,它持有到外部的 TCP 连接,有定时器在 5 秒内到期,或者它里面的程序让它保持运行(何时休眠)。
何时休眠 根据应用的流量选定的等待时间,最长为 sleep_after_ms 毫秒:默认 3,000(最多 600,000)。 空闲 sleep_after_seconds 秒后:默认 30,最少 1,null 表示永不休眠。
由什么唤醒 下一个请求,或它保持打开的 WebSocket 上来了新数据。 任何需要它的东西:命令、文件、发往其端口链接的请求、项目网络上对它的连接、它已有连接上的新数据、在它的终端中按下的键、快照、分叉、定时器。
何时删除 不带键时:在 delete_after_ms(默认一小时,可以设得更短)内没有任何东西让它保持运行。 你删除它时,或者由 expires_at、delete_after_idle_ms 或项目的 delete_after_idle_days 删除。
  • 保持请求。响应之后还有工作的程序(要清空的队列、要完成的写入),可以自己通过 Unix 套接字 /run/sbx/awake 让实例保持运行,最长 sleep_hold_max_ms(方块上为 scale.sleep_hold_max_ms;默认 30,000 毫秒)。具体做法和代码见从内部保持运行。
  • 唤醒用了多久。需要唤醒实例的 API 调用会在 Server-Timing: wake;dur=… 响应头中以毫秒给出。方块的日志会在每个唤醒了实例的请求那一行注明(日志与指标)。

机器丢失时

机器不再响应、一段时间都没有消息时,会被判定为丢失,它上面的沙箱和键控实例会由另一台机器接管:同区域有机器能接时用同区域的,否则用下一个区域的。它们从对象存储恢复,状态就是那台机器最后一次复制过去时的样子:

  • 当时在休眠的,连同内存和进程恢复,与它进入休眠时一样。
  • 当时在运行的,从磁盘重新启动:正在运行的东西都没了,它写入的数据恢复到复制完成的程度(云盘会说明复制到了哪里)。接管完成后,它会在新机器上被唤醒,不必等请求到来。有检查点时,它改为从最新的检查点带着进程继续运行。
  • 不会被接管的:在机器自己的磁盘上有存储卷、而对象存储中没有其副本的沙箱,以及不向对象存储复制任何数据的机器上的所有实例;机器恢复后,它们也随之恢复。

在此期间,发往它们的请求和需要它们的调用都返回 503 node_unavailable,可重试 (retryable)。每个被接管的实例都会在项目中产生一个 sandbox.moved 事件,reason 为 host_lost,with_processes 说明它是否带着进程恢复。方块中不带键的实例不会被接管:应用的其他机器会创建新实例。

整个站点丢失、而控制平面也在那里时,它在另一个站点的第二个副本会先接管。在接管完成之前,API 调用返回 503 standby,可重试 (retryable),带 Retry-After。

恢复的机器在运营人员重新放行之前不能与控制平面通信,也不会为可能已被接管的东西响应:从它的租约到期起,发往它的沙箱的请求会等待三秒,然后得到 503 fenced。在此期间,键控实例和带存储卷的沙箱会被保持静止;其他沙箱的机器继续运行,但没人能访问。控制平面响应后,已在别处被接管的东西在这台机器上结束 (409 moved),没被接管的则在这里恢复服务。任何沙箱都不会同时从两台机器响应。

方块与沙箱

这两个产品以两种方式使用同样的实例:

  • 方块:把镜像作为有自己地址的服务运行:这个服务就是方块,API 称它为 app (/v1/apps)。每次部署产生一个版本,版本的实例是其模板的副本;有请求时平台启动它们,没有请求时一个都不保留。每个方块都是其项目中的一个服务:服务在项目的私有网络上互相发现,一起部署,还可以从 Compose 文件导入(服务与 Compose)。
  • 沙箱:为 AI 智能体提供可在其中工作的键控实例,通过 API (/v1/sandboxes) 创建和使用:你可以在沙箱中运行命令、读写它的文件、打开终端、为它创建快照和分叉、用 SSH 连接它,以及设置它的网络规则。
  • 底层是同一种实例。方块的实例出现在项目的沙箱列表中(标签 app),和其他沙箱一样计量,你也可以在里面运行命令。

费用

无论属于哪个产品,每个实例的计量方式都一样:运行时,按使用的 CPU 时间和占用的内存计量(内存以 128 MiB 为一档,按毫秒计);休眠时不计 CPU:暂停在宿主机内存中的实例仍要为这部分内存付费,内存已保存下来的实例只为保存的内容付费,按 GB·月计。套餐对同时运行数量的限制,把账户所有项目中的沙箱和方块实例合在一起计算。参见价格与套餐和限制。

导航

输入以搜索……

↑↓ 切换↵ 选择Esc 关闭