Kibotos

实例指标存储

本页介绍如何接入实例指标存储,让 E2B SDK 读到 sandbox 的 CPU、内存与磁盘读数,让原生接口与 kibo workspace metrics 读到 Workspace 的读数。

概述

sandbox.getMetrics() 与 GetWorkspaceMetrics 读的就是这些读数。实例指标存储是可选的外部依赖,由部署方运营。不接入时其他功能照常:只有两个 sandbox 指标接口返回 501,GetWorkspaceMetrics 返回 failed_precondition。

各组件的分工:

  • node 每 5 秒采样每个运行中的 Instance,带着 instance_id 与 node_id 两个标签写入存储。其中 7 个读数来自 guest;其余由 node 在宿主上读取,来源是 VMM 的 cgroup、Instance 的 TAP 设备,Firecracker 后端还有 VMM 的块设备,所以 guest 不应答时它们照常写入。
  • 写入地址与凭证由 ctrl 下发,node 没有指标相关的配置。
  • ctrl 写入实例信息序列 kibotos_instance_info,把 Instance 对应到它的 Workspace,并带上部署选定的 Workspace labels。
  • E2B 网关查询 guest 读数与实例信息,按 sandbox 合并后返回。接口语义见 sandbox 指标。
  • 配了 query_url 后,ctrl 用写入的同一种 token 以同样方式查询,供 GetWorkspaceMetrics 使用,并一同返回宿主侧读数。方法语义见读取资源读数。

写入存储的每条序列及其读取方见序列。

指标只用于观察,不是用量或计费数据。存储不可达、guest 没有按时应答、node 重启或写入凭证过期时,对应时段的样本会丢失,之后不会补写。

它与 ctrl、node 和网关自己的指标是两回事。后者由采集器从各服务的指标监听抓取,参考部署另用一套存储,见集群与服务指标。

存储要求

要求说明
写入协议Prometheus remote write。node 与 ctrl 写同一个存储
查询协议Prometheus HTTP 查询 API(/api/v1/query 与 /api/v1/query_range),支持 PromQL 子查询
保留期与网关的 KIBOTOS_E2B_METRICS_RETENTION、ctrl 的 retention_seconds 相同,默认 7 天
token 认证验证 ctrl 签发的 JWT,按其中的 kibotos_role 放行:node 只能写入,ctrl 能写入与查询。存储一般不自己验证 JWT,由前置的代理完成
查询认证basic auth 或 bearer token,只放行查询

参考部署是 VictoriaMetrics 单节点版,前面放它的鉴权代理 vmauth。同时实现上面两种协议、并能在前面完成认证的存储都可以使用。

容量估算

  • 每个运行中的 Instance 有 21 条序列,每 5 秒各一个样本:7 条 guest 序列、宿主内存、运行时长与 12 条宿主侧计数器。Firecracker 后端的 Instance 另有 4 条磁盘计数器,共 25 条。ctrl 另为每个 Instance 每分钟写一个实例信息样本。
  • 1000 个同时运行的 Instance 约为每秒 4200 个样本,全是 Firecracker 时约 5000 个。在 VictoriaMetrics 上保存 7 天,占用的磁盘在 10 GB 量级。
  • 每次启动 Instance(包括 sandbox 恢复)都产生一组新序列。启动频繁时,按保留期内的启动次数乘以 22(Firecracker 为 26)估算序列总数。
  • 每台 node 每半小时向 ctrl 续取一次 token。

写入凭证

ctrl 用部署方生成的私钥签发写入凭证,node 不保存任何指标秘密。

凭证谁持有有效期
ctrl 写入用的 tokenctrl 进程内存1 小时,剩余不足一半时换新
node 写入用的 tokennode 进程内存,经与 ctrl 的连接取得1 小时,剩余不足一半时续取
  • token 是 ES256 签名的 JWT。sub 是 node ID,ctrl 自己的是 ctrl;kibotos_role 是 node 或 ctrl。
  • ctrl 没有 [metrics] 段时告诉 node 不采样。node 之后每 5 分钟再问一次,所以 ctrl 加上 [metrics] 并重启后,node 最多 5 分钟后开始采样。
  • 撤销一台 node 后,ctrl 不再给它签发;它的写入最迟在当前 token 到期时停止,最多一小时。
  • ctrl 不可达期间,node 用手里的 token 写到到期为止,之后样本出现缺口,ctrl 恢复后继续写入。

在 ctrl 宿主上生成签名私钥并导出公钥。公钥不是秘密,要写进 vmauth 的配置:

sudo install -o kibotos-ctrl -g kibotos-ctrl -m 0600 /dev/null /etc/kibotos/ctrl/metrics-signing-key.pem
sudo openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out /etc/kibotos/ctrl/metrics-signing-key.pem
sudo openssl pkey -in /etc/kibotos/ctrl/metrics-signing-key.pem -pubout
  • 私钥只给 kibotos-ctrl 读取。持有它的人能以任何 node 的身份写入,也能签出一个可以读全部 Workspace 读数的 ctrl token。
  • 私钥只在泄露时轮换,步骤见轮换签名私钥。

安全

  • node、ctrl 与网关要能访问 vmauth。租户不能访问它:guest 网络与公网都不应能连到它的地址。能写入的人可以伪造任意 sandbox 的读数,能查询的人可以看到全部 sandbox 的读数。
  • 被攻破的 node 在当前 token 到期前仍能写入,可以搅乱它知道 ID 的 sandbox 的读数,但不能查询。
  • ctrl 的 token 能读全部 Workspace 的读数。它只在 ctrl 进程内存里。
  • ctrl 只把 instance_info_labels 列出的 Workspace labels 写入存储。E2B 部署列哪些见ctrl 的配置。

参考部署:VictoriaMetrics 与 vmauth

VictoriaMetrics 只听同机 vmauth 能访问的地址,自身不设口令;vmauth 对外提供写入与查询入口,并负责认证:

用途地址
ctrl 的 remote_write_url,node 从 ctrl 取得同一个地址https://metrics.example.com:8427/api/v1/write
网关的 KIBOTOS_E2B_METRICS_URLhttps://metrics.example.com:8427
ctrl 的 query_urlhttps://metrics.example.com:8427

VictoriaMetrics 的启动参数:

参数示例说明
-retentionPeriod7d保留期,对应网关的默认值 168h
-httpListenAddr127.0.0.1:8428只让同机的 vmauth 访问
-storageDataPath/var/lib/victoria-metrics数据目录

vmauth 至少用 v1.152.0,这个版本修复了按 JWT claim 选择路由时的授权绕过。启动参数:

参数示例说明
-auth.config/etc/vmauth/auth.yml下面的配置文件
-httpListenAddr10.0.0.5:8427只监听 ctrl、node 与网关能访问的内网地址
-tls、-tlsCertFile、-tlsKeyFile证书与私钥的路径流量经过不受信任的网络时启用 HTTPS
-configCheckInterval1m定期重读配置,改公钥或口令后不必重启

把在写入凭证里导出的公钥写进 vmauth 配置的三个 JWT 用户。网关的口令从 vmauth 进程的环境变量 KIBOTOS_E2B_METRICS_PASSWORD 读取:

users:
- name: kibotos-other-sink
  jwt:
    default_vm_access_claim: {}
    public_keys:
    - |
      -----BEGIN PUBLIC KEY-----
      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
      -----END PUBLIC KEY-----
    match_claims:
      kibotos_role: ".+"
      kibotos_sink: ".+"
  url_map:
  - src_paths: [".*"]
    deny_paths: [".*"]
    url_prefix: "http://127.0.0.1:1"
- name: kibotos-node
  jwt:
    default_vm_access_claim: {}
    public_keys:
    - |
      -----BEGIN PUBLIC KEY-----
      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
      -----END PUBLIC KEY-----
    match_claims:
      kibotos_role: node
  url_map:
  - src_paths: ["/api/v1/write"]
    url_prefix: "http://127.0.0.1:8428/"
- name: kibotos-ctrl
  jwt:
    default_vm_access_claim: {}
    public_keys:
    - |
      -----BEGIN PUBLIC KEY-----
      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
      -----END PUBLIC KEY-----
    match_claims:
      kibotos_role: ctrl
  url_map:
  - src_paths: ["/api/v1/write", "/api/v1/query", "/api/v1/query_range"]
    url_prefix: "http://127.0.0.1:8428/"
- name: kibotos-e2b
  username: kibotos-e2b
  password: "%{KIBOTOS_E2B_METRICS_PASSWORD}"
  url_map:
  - src_paths: ["/api/v1/query", "/api/v1/query_range"]
    url_prefix: "http://127.0.0.1:8428/"
  • node 的 token 只能写入;ctrl 的 token 能写入,也能查询,供 GetWorkspaceMetrics 使用;网关的口令只能查询。其他路径一律拒绝。
  • kibotos-other-sink 拒绝带 kibotos_sink 声明的 token,即 ctrl 签的追踪 token,返回 403。指标 token 不带这个声明,match_claims 又写不出「不带某个声明」,所以要靠这个用户:vmauth 先试 match_claims 条目多的用户,它比另两个 JWT 用户多一条。链路追踪与实例指标共用一把私钥时,两个存储因此互相隔离。
  • 三个 JWT 用户都要有 default_vm_access_claim: {}。vmauth 只放行带 vm_access 声明的 token,或配了这一项的用户;ctrl 签的 token 不带 vm_access,缺了这一项时所有写入都返回 401。
  • 公钥直接写在配置文件里,不放单独的文件:vmauth 只在配置文件本身变化时重新加载。
  • -search.latencyOffset 保持默认值 30s 时,网关的查询延迟用默认值即可。调大它时同步调大网关的 KIBOTOS_E2B_METRICS_QUERY_DELAY,见E2B 网关的配置。

Kubernetes 上的参考部署

deploy/helm/kibotos-instance-metrics/ 是同一套参考部署的 Helm chart,在 Kubernetes 集群里装出:

  • VictoriaMetrics 单节点,跑在 StatefulSet 上,数据在持久卷里。它只在集群内可达,NetworkPolicy 只放行 vmauth 的 Pod。
  • vmauth,配置就是上面的 auth.yml:公钥从 values 传入,网关口令从部署方创建的 Secret 经环境变量注入,chart 不渲染口令。vmauth 自己的 /metrics、/flags、pprof 与配置重载用 chart 生成的 Secret <release>-vmauth-admin 的键 key 作 authKey,不对网络敞开。
  • vmauth 的 Service。ctrl、node 与网关运行在集群外,经这个地址访问;它要能被三者访问,不能被 guest 与公网访问。用内网负载均衡或 NodePort,不要给它公网地址。

前提:签名私钥已按写入凭证生成;集群的 CNI 执行 NetworkPolicy,否则同一集群里的任何 Pod 都能直接写 VictoriaMetrics。

把导出的公钥存为 metrics-signing-public.pem,生成网关口令,创建命名空间与口令 Secret,然后安装。口令文件不能带换行:vmauth 把 Secret 的内容原样当作口令,多一个换行网关就对不上。示例用命名空间 kibotos-instance-metrics、阿里云 ACK 的内网负载均衡注解;其他集群换成对应的注解,或者改用 NodePort:

set -eu
umask 077
openssl rand -hex 24 | tr -d '\n' > metrics-query-password
kubectl create namespace kibotos-instance-metrics
kubectl -n kibotos-instance-metrics create secret generic kibotos-instance-metrics-query --from-file=password=metrics-query-password
cat > instance-metrics.yaml <<EOF
vmauth:
  publicKeys:
    - |
$(sed 's/^/      /' metrics-signing-public.pem)
  query:
    secretName: kibotos-instance-metrics-query
  service:
    type: LoadBalancer
    annotations:
      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: intranet
EOF
helm install kibotos-instance-metrics deploy/helm/kibotos-instance-metrics -n kibotos-instance-metrics -f instance-metrics.yaml --wait
kubectl -n kibotos-instance-metrics get service kibotos-instance-metrics-vmauth

最后一条输出的 EXTERNAL-IP 就是存储的地址:ctrl 的 remote_write_url 写 http:// 加这个地址加 :8427/api/v1/write,网关的 KIBOTOS_E2B_METRICS_URL 写 http:// 加这个地址加 :8427,KIBOTOS_E2B_METRICS_PASSWORD 是 metrics-query-password 的内容。给地址配一个 DNS 名字时,ctrl 与网关都用那个名字。

本 chart 特有的键与默认值见下表;与另外两个存储 chart 共有的键见 chart 的通用 values。

键说明
vmauth.publicKeys公钥 PEM 的列表,必填。可以有多把,轮换私钥期间新旧并存
vmauth.query.secretName、vmauth.query.username口令 Secret 的名字(键 password),必填;用户名默认 kibotos-e2b
victoriaMetrics.retentionPeriod默认 7d。改了就同步改网关的 KIBOTOS_E2B_METRICS_RETENTION 与 ctrl 的 retention_seconds
victoriaMetrics.storage.size默认 20Gi
  • 设了 vmauth.tls.secretName、证书由私有 CA 签发时,CA 交给 ctrl 的 ca_file 与网关的 KIBOTOS_E2B_METRICS_CA_FILE。
  • 配置变化后 vmauth 重启,重启的几秒里写入失败,这段时间的样本有缺口,之后 node 与 ctrl 继续写入。
  • 轮换签名私钥的第 2 步与第 4 步在这里就是改 vmauth.publicKeys 再 helm upgrade。

chart 的通用 values

三个存储 chart 共有下面这些键:本 chart、集群与服务指标的 kibotos-metrics,以及链路追踪的 kibotos-traces。kibotos-traces 里存储的键以 victoriaTraces. 开头,不是 victoriaMetrics.。每个 chart 的 values.yaml 在注释里说明了全部键。

键说明
vmauth.readers给看板用的只读用户,每项 name 与 secretName(键 password),名字只用小写字母、数字与连字符。两个指标 chart 里只能调 Prometheus 查询 API:query、query_range、query_exemplars、series、labels、label/<名字>/values、metadata、status/buildinfo;kibotos-traces 里只能调 /select/jaeger/api/ 下的 Jaeger 查询 API
vmauth.tls.secretNamekubernetes.io/tls 类型的 Secret。设了之后 vmauth 只提供 HTTPS,地址改用 https://。流量经过不受信任的网络时启用
vmauth.service.type、annotations、loadBalancerIP、loadBalancerSourceRanges、nodePortService 的类型与限制。类型默认 ClusterIP,只在集群内可达;端口 port 默认 8427
victoriaMetrics.retentionPeriod保留期,各 chart 的默认值不同
victoriaMetrics.storage.size、victoriaMetrics.storage.storageClassName持久卷大小与 StorageClass。StorageClass 留空时用集群默认的
victoriaMetrics.resources、vmauth.resources两个容器的资源请求与上限
victoriaMetrics.extraArgs、vmauth.extraArgs额外的启动参数,每项一个 -name=value
  • 镜像按 digest 固定。vmauth 与集群与服务指标的 vmagent 同一版本。
  • 改 values 后 helm upgrade。vmauth 的配置变化会让它重启。
  • helm uninstall 不删除持久卷,确认不要数据后再删 PVC。

ctrl 的配置

只有 ctrl 有 [metrics] 段。没有这个段时,ctrl 不写实例信息序列,node 不采样。每个键的取值范围与默认值见 ctrl 配置参考的 [metrics]。

在 /etc/kibotos/ctrl/config.toml 末尾加上:

[metrics]
remote_write_url = "https://metrics.example.com:8427/api/v1/write"
signing_key_file = "/etc/kibotos/ctrl/metrics-signing-key.pem"
instance_info_labels = ["e2b.kibotos.app/namespace", "e2b.kibotos.io/namespace"]
query_url = "https://metrics.example.com:8427"

然后重启 ctrl。node 不需要改配置,也不需要重启。

  • 文件都用绝对路径,可以是符号链接,最终指向的要是 kibotos-ctrl 能读取的普通文件。
  • retention_seconds 要等于存储的保留期,query_delay_seconds 不能小于存储的可见延迟,规则与E2B 网关的配置相同。默认值与参考部署一致。
  • E2B 部署把 instance_info_labels 写成命名空间的两个 key:e2b.kibotos.app/namespace,以及 v0.3.0 之前的网关写的 e2b.kibotos.io/namespace,后者到 v0.4.0 去掉。缺少前者时,网关找不到任何 sandbox 的 Instance,所有 sandbox 的指标都是空数组。
  • E2B sandbox metadata 生成的 labels(m.e2b.kibotos.app/ 前缀)是调用方的数据,不要列入。
  • kibotos-ctrl 的 init、enrollment create、check-upgrade 与服务本身都校验 [metrics] 并读取私钥与 CA 文件,与 dsn_file 相同。文件读不到或格式不对时这些命令都会失败。migrate 只读取数据库连接,不校验 [metrics]。
  • 启用后,ctrl 日志有一行 instance info series enabled,每台 node 日志有一行 guest metrics sampling enabled。配了 query_url 时 ctrl 日志还有一行 Workspace metrics reads enabled。
  • Platform 的 guest 早于采样接口时,node 不采样这个 Instance,日志记一行 guest does not support resource sampling。

E2B 网关的配置

在 /etc/kibotos/e2b/config.env 里填写下面的变量,然后重启网关。示例见 e2b.example.env 末尾。

变量说明
KIBOTOS_E2B_METRICS_URL查询 API 的基础地址,不带 /api/v1,例如 https://metrics.example.com:8427。留空时两个 sandbox 指标接口返回 501,能力名 metrics
KIBOTOS_E2B_METRICS_USERNAMEbasic auth 用户名,参考部署是 kibotos-e2b
KIBOTOS_E2B_METRICS_PASSWORDbasic auth 口令,与 vmauth 配置里的相同
KIBOTOS_E2B_METRICS_BEARER_TOKENbearer token。与 basic auth 只能选一种
KIBOTOS_E2B_METRICS_CA_FILE可选。替换系统根证书的 PEM 文件,kibotos-e2b 账户要能读取
KIBOTOS_E2B_METRICS_RETENTION存储的保留期,写法如 168h,默认 168h。必须与存储的保留期相同
KIBOTOS_E2B_METRICS_QUERY_DELAY查询延迟,写法如 30s,默认 30s。网关只返回在「当前时间减去查询延迟」之前已经结束的桶,批量接口的最新样本也只取到这个时刻。不能小于存储的可见延迟
  • 没有设置地址、却设置了凭证或 CA 时,网关拒绝启动。
  • 查询延迟要不小于存储的可见延迟,也就是新写入的样本多久之后才出现在查询结果里。VictoriaMetrics 的可见延迟是 -search.latencyOffset,默认 30s,与网关的默认值相同;调大它时同步调大查询延迟。网关按本机时钟计算截止时刻,与存储所在宿主机的时钟有偏差时再留出余量。
  • 查询延迟小于可见延迟时,最近一段的桶可能是存储补出来的值:刚暂停的 sandbox 末尾会多出没有样本的桶,稍后又消失;批量接口也可能找不到最新样本。
  • 查询延迟设为 0 只适合样本写入后立即可查的存储。
  • 同一部署的所有网关实例使用相同的指标配置。
  • 启用后,启动日志 starting kibotos-e2b gateway 一行的 sandbox_metrics 为 true。

确认

用 E2B SDK 创建一个 sandbox,它运行一分钟后 sandbox.getMetrics() 应返回非空数组。样本要过了查询延迟(默认 30 秒)才会返回。

也可以用网关的口令直接查询,确认两类序列都已写入。curl 会提示输入口令:

curl -sS -u kibotos-e2b --get \
  --data-urlencode 'query=count by (__name__) ({__name__=~"kibotos_instance_info|kibotos_guest_cpu_count"})' \
  https://metrics.example.com:8427/api/v1/query

结果里应同时出现 kibotos_instance_info 与 kibotos_guest_cpu_count。

配了 query_url 后,对一个运行了一分钟的 Workspace,kibo workspace metrics <workspace-id> 应显示宿主侧与 guest 内两组读数。返回 unavailable、ctrl 日志里 workspace metrics unavailable 带着 vmauth 的 HTTP 400 或 401 时,vmauth 配置里 ctrl 用户缺那两个查询路径。

轮换签名私钥

签名私钥只在泄露时轮换。按下面的顺序做,写入不会中断:

  1. 生成新私钥,导出新公钥。
  2. 把新公钥加到 vmauth 配置三个 JWT 用户的 public_keys,旧公钥保留。等 vmauth 重新加载配置。Kubernetes 上是把新公钥追加到 values 的 vmauth.publicKeys,再 helm upgrade。
  3. 用新私钥替换 signing_key_file 指向的文件,重启 ctrl。
  4. 一小时后,旧私钥签的 token 都已到期,从 vmauth 配置里删掉旧公钥。

看板

实例指标有两个 Grafana 看板,导入时都选一个指向实例指标存储的 Prometheus 类型数据源。数据源用 chart 的通用 values 里 vmauth.readers 的只读用户,不要用网关的口令。集群内的地址按示例的命名空间是 http://kibotos-instance-metrics-vmauth.kibotos-instance-metrics.svc:8427,Basic auth 填这个用户的名字与口令。类型要选 Prometheus 而不是 VictoriaMetrics 插件:看板只用标准 PromQL,数据源变量也只列 Prometheus 类型的数据源。

看板内容
grafana-instances.json「Kibotos 实例概览」总览:采样中与 ctrl 登记的 Instance 数、分配的 vCPU 与 guest 内存、宿主实占的 guest 内存与实占比、内存或磁盘超过 90% 的 Instance 数、vCPU 加权的 CPU 忙碌率、最近 5 分钟出现与消失的 Instance。采样健康:最近 2 分钟没有样本的 node、ctrl 实例信息最近写入距今、有实例信息却没有 guest 样本(以及反过来)的 Instance 列表、每台 node 最近一次样本距今。按 node 与按命名空间的 vCPU、内存、宿主实占与根文件系统分布。CPU 最忙、内存使用率最高、磁盘最满、宿主占用最多、运行最久的前 15 个 Instance
grafana-workspace.json「Kibotos Workspace」一个 Workspace 各个 Instance 的 CPU、内存(used、cache、total)、根文件系统、宿主实占对比 guest 分配、vCPU 数,以及 Instance 所在的 node 与运行时长
  • 概览的变量 node、命名空间 缩小范围;表格里的 Workspace 可以点进「Kibotos Workspace」,带着命名空间与时间范围。
  • 命名空间来自实例信息上的 label_e2b_kibotos_app_namespace,instance_info_labels 没有列 e2b.kibotos.app/namespace 时按命名空间的面板为空。v0.3.0 之前写入的样本带的是 label_e2b_kibotos_io_namespace,按命名空间的面板不显示它们。
  • kibotos_instance_host_memory_bytes 与 kibotos_instance_uptime_seconds 从 v0.2.0 的 node 起写入,更早的版本这几块没有数据。
  • 看板暂不展示宿主侧计数器与磁盘计数器。宿主侧的 CPU、压力与网络计数器从 v0.3.0 的 node 起写入。
  • 「采样健康」里的列表与计数正常时为空或为 0。刚启动的 Instance 在第二次采样之前只有实例信息、没有 guest 样本,属正常。

序列

下面的序列由 node 写入,带 instance_id 与 node_id 两个标签,每个运行中的 Instance 每 5 秒一个样本;kibotos_instance_info 由 ctrl 写入。

序列值读取方
kibotos_guest_cpu_countguest 在线的 CPU 数E2B 网关、GetWorkspaceMetrics、看板
kibotos_guest_cpu_used_percent自上一个样本以来 guest CPU 时间里忙碌的比例,0 到 100。idle 与 iowait 不算忙碌E2B 网关、GetWorkspaceMetrics、看板
kibotos_guest_memory_total_bytesguest 的 MemTotalE2B 网关、GetWorkspaceMetrics、看板
kibotos_guest_memory_used_bytesguest 的 MemTotal 减 MemAvailableE2B 网关、GetWorkspaceMetrics、看板
kibotos_guest_memory_cache_bytesguest 的 CachedE2B 网关、GetWorkspaceMetrics、看板
kibotos_guest_disk_total_bytes、kibotos_guest_disk_used_bytesguest 看到的 / 所在文件系统的大小,以及它减去非特权用户可用空间后的值E2B 网关、GetWorkspaceMetrics、看板
kibotos_instance_host_memory_bytesVMM 在宿主上占用的 guest 内存:VMM 的 cgroup 的 memory.stat 里 anon 与 shmem 之和。用它按 Instance 查看实际占用、估算内存超卖倍数GetWorkspaceMetrics、看板
kibotos_instance_uptime_secondsVMM 进程启动以来的时长。一个 VMM 进程就是一次 guest 开机,node 升级接管时不重新计时看板
12 条宿主侧计数器VMM 的 cgroup 与 Instance 的 TAP 设备。guest 不应答时可以看出 VMM 是否仍在消耗 CPU、网络是否还有收发GetWorkspaceMetrics
4 条磁盘计数器VMM 的块设备,只有 Firecracker 后端暂无
kibotos_instance_info值为 1。标签是 instance_id、workspace_id,以及 instance_info_labels 里每个 key 各一个。ctrl 在 Instance 运行后写入,之后每分钟一次E2B 网关、GetWorkspaceMetrics、看板

宿主侧计数器

指标来源
kibotos_instance_cpu_seconds_totalVMM 单元 cgroup 的 cpu.stat usage_usec:VMM 的全部线程,Firecracker 还包括 jailer
kibotos_instance_cpu_pressure_some_seconds_total该 cgroup 的 cpu.pressure some 行的 total
kibotos_instance_memory_pressure_some_seconds_total、kibotos_instance_memory_pressure_full_seconds_totalmemory.pressure 的 some、full 行
kibotos_instance_io_pressure_some_seconds_total、kibotos_instance_io_pressure_full_seconds_totalio.pressure 的 some、full 行
kibotos_instance_network_receive_bytes_total、kibotos_instance_network_transmit_bytes_totalInstance 的 TAP 设备的字节数
kibotos_instance_network_receive_packets_total、kibotos_instance_network_transmit_packets_totalTAP 的包数
kibotos_instance_network_receive_dropped_total、kibotos_instance_network_transmit_dropped_totalTAP 的丢包数
  • 时间都换算成秒。用 rate() 或 increase() 读:采样丢点时区间内的总量仍然正确。
  • 每次启动 VMM 都有新的 cgroup,CPU 与压力计数器从 0 开始,查询按计数器重置处理。
  • 宿主内核关闭了 PSI(psi=0)时不写三类压力计数器,node 日志记一次,其他序列照常。
  • 网络方向按 guest 的视角:TAP 发出的是 guest 收到的。TAP 是 guest 网卡在宿主侧的一端,经 Egress 转发的流量、经 Resolver 应答的 DNS 查询也经过它;exec、文件与端口转发走 vsock,不计入。

磁盘计数器

指标来源
kibotos_instance_disk_read_bytes_total、kibotos_instance_disk_written_bytes_totalguest 向它的全部虚拟盘读、写的字节数,由 VMM 的块设备按请求累计
kibotos_instance_disk_read_requests_total、kibotos_instance_disk_write_requests_total读、写请求数
  • 计数的是 guest 请求了多少,与宿主页缓存是否命中、盘放在本地还是 NFS 存储池上无关。只读的 Template 基础层、可写层与 Volume 合在一起。
  • 数据面传输本身不计入;上传的文件写到盘上时按写入计。
  • 用 rate() 或 increase() 读。新的 VMM 与 node 重启接管时都从 0 开始,查询按计数器重置处理。
  • 目前只有 Firecracker 后端写这 4 条:node 在 VMM 开机前把 Firecracker 的 metrics 指向 jail 里的命名管道,每轮采样时让它 flush 再读取。KiboVM 后端暂不写。
  • 升级前启动的 Firecracker VMM 没有配置 metrics,重启之前不写。
  • 宿主侧的 cgroup io.stat 与 /proc/<pid>/io 量的是宿主存储层:NFS 上的块文件不计入 io.stat,缓存命中的读不计,同一块回写前的重复写只计一次。要看存储被压了多少,读它们;要看 Instance 做了多少 IO,读这 4 条。

排查

现象原因处理
两个 sandbox 指标接口返回 501 metrics网关没有设置 KIBOTOS_E2B_METRICS_URL设置后重启网关
所有 sandbox 都返回 []ctrl 没有 [metrics] 段,或 instance_info_labels 缺少 e2b.kibotos.app/namespace补上后重启 ctrl
个别 sandbox 始终返回 []它所用 Platform 的 guest 早于采样接口,node 日志有 guest does not support resource sampling用这个版本发布 Platform 并设为默认版本,之后创建的 sandbox 会被采样
接口返回 500网关连不上存储,或认证失败查看网关日志里的 sandbox metrics unavailable
最后一个桶重复前一个桶的值,稍后又消失;批量接口返回的 sandbox 时有时无查询延迟小于存储的可见延迟把 KIBOTOS_E2B_METRICS_QUERY_DELAY 调到不小于存储的可见延迟后重启网关
样本出现缺口,node 与 ctrl 日志有 metrics remote write rejected 与 HTTP 401vmauth 的公钥与 ctrl 的私钥不匹配,JWT 用户缺少 default_vm_access_claim,或 vmauth 早于 v1.152.0对照上面的配置检查 vmauth,重新导出公钥
样本出现缺口,node 日志有 metrics write credential request failednode 连不上 ctrl,token 到期后停止写入恢复 node 与 ctrl 的连接,node 会自动续取
样本出现缺口存储短暂不可达,或拒绝了写入查看 node 与 ctrl 日志里的 metrics remote write failed、metrics samples dropped

本页内容