Kibotos

服务与端口

Workspace 里的服务可以从本机浏览器或客户端打开,可以发布成公开 URL 给别人看,也可以让自己的程序直接连接 guest 内的端口或 socket。本页逐一介绍这几种方式,先讲 kibo 命令。

概述

按谁需要访问服务来选:

需要用法谁能访问
在本机浏览器打开 Web 服务kibo workspace service http只有这台机器
用本机客户端(如 psql、SSH、VNC)连接kibo workspace service forward本机上的任何进程
让本机的网页连接端口或 socketkibo workspace service bridge来自同一个本机 origin 的网页
把 Web 服务给别人看kibo exposure create任何拿到地址的人
让自己的程序连接端口或 socket服务连接只有持有会话凭证的一方

只有公开 URL 需要域名,由部署方配置。

在本机浏览器打开 HTTP 服务

kibo workspace service http 把 Workspace 里一个 HTTP 端口代理到本机的 127.0.0.1,用浏览器直接打开。只有这台机器能访问,不需要部署方配置域名。

代理 Workspace 里的 5173 端口,打开命令输出的 URL:

kibo workspace service http "$workspace_id" --tcp-port 5173
# URL  http://127.0.0.1:5173/

代理一直运行到按 Ctrl-C 为止,正在进行的连接一并结束。

代理可以一直开着。凭证在到期前自动换新,Workspace 重新启动后也不用重开。

参数

参数默认值说明
--tcp-port必填服务在 Workspace 里监听的端口
--familyipv4服务监听在 ::1 时写 ipv6
--listen-port与 --tcp-port 相同本机端口;0 取一个空闲端口

注意

  • 本机端口默认与 Workspace 里的端口相同,应用写死的 localhost:5173 回调地址和跨域配置照常可用。
  • 本机端口被占用时,命令以退出码 2 失败,换一个 --listen-port。
  • 服务只监听 127.0.0.1 也能用,不需要改成监听 0.0.0.0。
  • 服务可以晚于代理启动,未启动期间请求返回 502。
  • 代理只接受 Host 为 127.0.0.1 或 localhost 加本机端口的请求,其他 Host 返回 403。这挡住了把别的域名解析到 127.0.0.1 的网页。
  • 应用看到的 Host 就是浏览器发来的值,它生成的重定向与绝对地址会回到本机代理。
  • keep-alive、SSE 等流式响应与 WebSocket 都可用。
  • 代理同时最多持有 32 条到服务的连接,空闲、使用中与已升级为 WebSocket 的合计。找不到空闲连接的请求会等待。WebSocket 关闭前一直占着它的连接,所以开着 32 个 WebSocket 时其他请求都要等。

要把服务给别人看时,发布一条公开 URL。

本机端口转发

kibo workspace service forward 把 Workspace 里的一个 TCP 端口或受管 Unix socket 转发到本机 127.0.0.1 的一个端口。它不理解应用协议,所以数据库、SSH、VNC、gRPC 这类不走 HTTP/1.1 的服务都能用本机客户端直接连。

转发 5432 端口上的 PostgreSQL,再用 psql 连接:

kibo workspace service forward "$workspace_id" --tcp-port 5432
# Address  127.0.0.1:5432
psql -h 127.0.0.1 -p 5432 -U postgres

用原生 VNC 客户端连桌面时,把桌面的 VNC socket 转发到本机 5900 端口:

kibo workspace service forward "$workspace_id" \
  --unix-path /run/kibotos/services/desktop/vnc.sock --listen-port 5900

转发一直运行到按 Ctrl-C 为止,正在进行的连接一并重置。

警告

转发不检查经过的数据。本机上任何进程都能连这个端口,包括其他账号的进程;浏览器里的网页也能向它发请求。对 HTTP 服务,网页可以借 DNS rebinding 读写它,所以 HTTP 服务请用 service http,它会校验 Host。这与 kubectl port-forward、ssh -L 的风险相同。

参数

参数默认值说明
--tcp-port与 --unix-path 二选一服务在 Workspace 里监听的端口
--familyipv4服务监听在 ::1 时写 ipv6
--unix-path与 --tcp-port 二选一Workspace 里 /run/kibotos/services/ 下的 Unix socket
--listen-port与 --tcp-port 相同;Unix socket 必填本机端口;0 取一个空闲端口

注意

  • 本机每条连接对应 Workspace 里的一条连接。连上就建立,服务端先发数据的协议(MySQL、SSH、VNC)不用等客户端先写。
  • 两个方向的数据原样转发,一端结束写入后另一端读到 EOF。
  • 一端不读时另一端的写入会等待,连接不会因此断开,也没有空闲超时。
  • 最多同时转发 32 条连接,超出的新连接被重置。
  • 连不上服务、Workspace 停止或连接中途失败时,本机连接被重置,stderr 写一行原因,例如 connection from 127.0.0.1:52144 reset: unavailable: …。
  • 服务可以晚于转发启动。
  • 转发可以一直开着。凭证在到期前自动换新,Workspace 重新启动后也不用重开。
  • 本机端口被占用时,命令以退出码 2 失败,换一个 --listen-port。
  • Unix socket 必须属于 root、权限为 0600,路径不能经过符号链接,否则连接以 permission_denied 失败。

本机 WebSocket 桥接

kibo workspace service bridge 把 Workspace 里的一个服务变成 127.0.0.1 上的 WebSocket,供本机上直接与服务通信的网页使用。它输出以 /stream 结尾的 WebSocket 地址,以及一个内置测试页的地址,测试页检查 guest 里的回显服务是否原样送回字节。

为你在 http://127.0.0.1:8080 提供的网页桥接 Workspace 的 7000 端口:

kibo workspace service bridge "$workspace_id" --tcp-port 7000 --origin http://127.0.0.1:8080
  • 目标参数 --tcp-port、--family、--unix-path 与 service forward 相同。--listen-port 设置本机端口,默认取一个空闲端口。
  • 只接受 Origin 与 --origin 完全一致的握手。不给 --origin 时,只有内置测试页能连接。
  • 每个 WebSocket 各自建立一条到服务的连接。每条消息都是 binary,原样承载字节,没有 opcode 字节,单条最多 32 KiB。收到 text 消息时关闭 WebSocket。
  • 服务结束写入时,桥接结束这条连接,以 1000 关闭 WebSocket,网页之后不能再发送。
  • 最多同时桥接 16 个 WebSocket,超出的握手返回 503。
  • 凭证自动换新。桥接一直运行到按 Ctrl-C 为止,开着的 WebSocket 一并关闭。

公开 URL

kibo exposure 把 Workspace 内一个 HTTP 端口换成一条 https:// 地址,任何拿到这条地址的人都能在浏览器里打开它。适用于 Agent 在 Workspace 里写出一个 Web 服务、你需要直接看到它的场景。

前提条件

没有配置这个域名时,kibo 不会列出 kibo exposure 这组命令,创建也会失败。

创建公开 URL

把 Workspace 的 3000 端口公开两小时:

workspace_id=workspace-example
kibo exposure create --workspace "$workspace_id" --port 3000 --ttl 2h

输出里的 url 就是可以直接打开、也可以发给别人的地址。它不带结尾斜杠,要访问某个路径时直接接在后面。

警告

没有访问控制。拿到地址的人就能访问,没有口令、来源或 IP 限制。地址是随机的,这是它唯一的保护。不要用它公开不该被看到的东西。

查看与撤销

列出一个 Workspace 的 Exposure、查看其中一条,再撤销它:

kibo exposure list --workspace "$workspace_id"
kibo exposure get exposure-example
kibo exposure revoke exposure-example

撤销后该地址立即停止服务,正在进行的连接一并结束。重复撤销不报错。

注意

  • 端口在 guest 的 loopback 上读。服务只监听 127.0.0.1 也能用,不需要为此改成监听 0.0.0.0。服务监听在 ::1 时加 --ipv6。
  • Exposure 撤销之后,它的地址不会再分给别人。
  • --ttl 必填,上限 24 小时。到期自动停止服务。
  • Workspace 停止或删除时,它的全部 Exposure 一并撤销。Workspace 再次启动后要重新创建 Exposure,地址也是新的。
  • 协议只有 HTTP,其中 WebSocket 与 SSE 可用。TCP、TLS 直通、UDP 与 QUIC 不在范围内。

Exposure 的 API

程序通过 ExposureService 的 CreateExposure、GetExposure、ListExposures 与 RevokeExposure 管理公开 URL。只有部署方配置了专用域名时,服务端才宣告 exposure.* 能力,见能力名。

需要的是一条给自己程序用的字节通道,而不是一个给浏览器的地址时,用服务连接:它要凭证,不需要域名,也不对公网开放。

用 API

服务连接把程序连接到 guest 内某个 TCP loopback 端口或 Unix socket,例如 VNC、Chrome DevTools 或应用端口。kibo workspace service 各命令与桌面查看页面都建立在它之上。

申请会话

两条连接路径的第一步相同:申请数据面会话时请求 SERVICE_CONNECT 权限范围,并在 service_targets 中列出目标。会话申请本身见申请会话凭证。

目标字段
TCPLoopbackTargetaddress_family、port
UnixStreamTargetpath
  • 目标必须精确,不支持通配、端口范围或任意 IP。
  • Unix socket 目标的规则与 --unix-path 相同,见本机端口转发。
  • 凭证只对列出的目标有效。
  • 目标列表参与幂等判断。

选择路径

之后有两条路径,语义相同,编码不同:

WebSocket(默认)双向流
入口session.endpoint 上的 GET /v1/serviceServiceConnectionService/Connect
需要一次普通的 WebSocket 升级每一跳端到端 HTTP/2
适合前面有 L7 反向代理或 CDN 的部署;浏览器直连或 L4 代理的部署

WebSocket

用下面的请求连接 guest 内的 TCP 端口或 Unix socket。完整参数见 /v1/service。

GET <endpoint>/v1/service?tcp_family=ipv4&tcp_port=9222
GET <endpoint>/v1/service?unix_path=/run/kibotos/services/desktop/vnc.sock

凭证放在请求头里:

  • 凭证放 Authorization: Bearer。
  • 浏览器不能给 WebSocket 握手设请求头,改用 Sec-WebSocket-Protocol: kibotos-dp-credential.<credential>,服务端在 101 里回选同一个 subprotocol。

警告

不要把凭证放进 query,它会进访问日志和 Referer。

鉴权与连接 guest 都在升级之前完成,所以 101 就表示 guest 内的 socket 已经连上。在这之前的失败是普通 HTTP 响应,错误体与 /v1/files 一致。

升级之后,字节走 binary frame,每帧首字节是 opcode;失败以关闭帧送达。opcode 见帧,关闭码见关闭码。

警告

只有关闭码 1000 表示连接正常完成。1001 在这里是失败,尽管很多 WebSocket 库把它当作正常结束:例如 guest 内的服务重置了连接时,服务端以 1001 和 unavailable 开头的原因关闭。请自行判断关闭码。

双向流

  1. 向 session.endpoint 发起 ServiceConnectionService/Connect。这是 Connect 协议的双向流,基于 HTTP/2。
  2. 第一条消息发 open{target},目标必须在会话授予的列表中。服务端连上 socket 后回复一条 connected,之后才开始传数据。
  3. 双向都用 data 消息传原始字节。发送 half_close 表示不再写入,之后不能再发请求消息;收到 eof 表示对端已关闭写入。

两个方向都结束后,RPC 正常完成。

连接数上限

  • 每个 Workspace 最多同时有 128 条服务连接,每台 node 最多 1024 条,两条路径合计。超出时新连接以 resource_exhausted 失败。
  • 两条路径的单条消息大小、拨号期限与速率上限相同,结束方式也相同,见 /v1/service 的限制与说明。

从浏览器连接

浏览器只信任系统根证书,而数据面证书由内部 CA 签发,所以浏览器直连只在数据面前面有公共可信证书时可用。

没有这种边缘时,用 kibo workspace service bridge 或桌面查看页面:它们在本机把连接转成 loopback 上的 WebSocket。guest 里的服务本身是 HTTP 时,用 kibo workspace service http 在本机 loopback 上直接代理它,见在本机浏览器打开 HTTP 服务。

下一步

  • 桌面:在浏览器里查看和操作桌面。
  • 网络概览:Workspace 能访问哪些外部地址。
  • 数据面:为服务连接申请会话凭证。
  • E2B 应用端口:经 E2B 网关访问 sandbox 内的端口。

本页内容