跳到主要内容

vsock 协议

传输​

项目值
guest 端监听 vsock 端口 5000
host 端Unix socket,通过 krun_add_vsock_port2(listen=true)绑定到端口 5000
握手无:连上 Unix socket 就直接到达 guest
每个连接的消息一个作业和一个结果

Frame​

Message framing

offset 0      4                          4 + N
┌──────┬──────────────────────────┐
│ N │ JSON (N bytes, UTF-8) │
└──────┴──────────────────────────┘
uint32 big-endian
  • N 只计算 payload。
  • frame 最大 64 MiB。host 的读取方在分配内存之前就拒绝超过这个大小的长度:没有这个限制,一个损坏的前缀(最大 4 GiB)会让读取方在读取正文之前就把内存全部分配出去。
  • host 用一次写操作发送前缀和正文,保证 guest 永远不会读到没有对应正文的前缀。

示例​

作业 {"trace_id":"t1","lang":"python","code":"print(1)","timeout":10} 的 JSON 有 64 字节:

00 00 00 40  7b 22 74 72 61 63 65 5f 69 64 22 3a ...
└─ 64 ─────┘ └─ {"trace_id": ...

Payload​

Streaming​

作业中带 "stream": true 时,guest 会用多个 frame 而不是一个来响应,格式全部相同(长度 + JSON),定义在 internal/protocol 中:

{"type":"stdout","data":"early\n"}
{"type":"stderr","data":"warn\n"}
{"type":"result","result":{"status":"success","stdout":"early\n","stderr":"warn\n","exception":null,"executionTime":12}}
  • 进程向管道的每次写入对应一个 frame(Linux 上最大 32 KiB),按 guest 读取的顺序发送。
  • result 总是最后一个,携带完整结果,与非 streaming 模式相同。
  • 不带 stream 时,线路上的内容与以前完全相同:一个结果 frame。就绪探测(sh true)使用这种模式。
  • 如果 host 收到一个没有 type 的 frame,说明镜像中的 guest 早于 streaming 功能:rc image build 会重建镜像。

操作​

作业的 op 字段选择操作。为空时是一直以来的代码作业,这样一次性作业的线路格式不会改变;其余操作服务于持久化 machine(internal/protocol)。

op使用的字段作用
(空)lang、code、files、stdin、timeout、stream运行某种语言的代码
execargv、env、cwd、user、timeout、stream运行一个程序,没有隐式 shell
put / getpath、offset、data、final、mode以 1 MiB 分块复制文件(每个文件最大 4 GiB)
ptyargv、rows、cols、user交互式终端:连接变为事件通道,host 发送 input/resize,guest 发送 output/exit
workloadargv、env、cwd、user、stop_on_exit启动 machine 持续运行的进程
shutdownsignal、timeout向 workload 发送信号,等待,执行 sync 后关机
dialport成功结果之后,连接变成一条通往 guest 内 127.0.0.1:port 的字节管道(发布的端口)
set-envenv把 secrets 保存在 guest 内存中,并附加到之后的每条命令上;从不写入磁盘
ssh-agentpath、port在 guest 中打开一个 Unix socket,把每个连接转发到 host 的 vsock 端口(SSH agent)
mount-s3path、s3、env确认 bucket 有响应后,在 guest 中通过 FUSE 挂载它

其他 vsock 端口​

端口方向用途
5000host → guest上述所有操作
5001guest → hostSSH agent(--ssh-agent)
5100 + iguest → host第 i 个 --mount-socket