命令行参考:opendsecctl
opendsecctl 是 OpenDsec 的命令行工具,管理员和调用方都用它:创建和操作 sandbox、管理镜像、项目、身份和 token、查看集群、签发证书、管理集群版本(fleet)。
opendsecctl <命令> [参数] [选项]
opendsecctl help # 列出全部命令
opendsecctl fleet # fleet 子命令的帮助- 安装后在
/usr/local/bin/opendsecctl(单机安装)或/opt/opendsec/current/bin/opendsecctl(集群节点);运维机上是$OPENDSEC_OPS/current/bin/opendsecctl。 - 选项可以写在位置参数前面或后面,例如
opendsecctl sandbox stop <id> -addr x和opendsecctl sandbox stop -addr x <id>等价。 - 除特别说明外,命令的输出是 JSON(protobuf 的 JSON 形式,值为默认值的字段省略)。
- 命令成功时退出码为 0,失败时打印
error: <reason>: <说明>并以非 0 退出。exec以命令自己的退出码退出。
连接与环境变量
| 选项 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
-addr | OPENDSEC_ADDR | — | apiserver 地址,多个用逗号分隔 |
-token | OPENDSEC_TOKEN | — | token。建议用环境变量,避免出现在 shell 历史和进程列表里 |
-project | OPENDSEC_PROJECT | root | 默认项目 |
-ca | OPENDSEC_CA | — | 集群 CA 证书,设置后使用 TLS |
-store | OPENDSEC_IMAGE_STORE | — | 镜像库的挂载点(image import、image gc、image store-check) |
-deadline | — | 5m | 整个命令的时限;image import 默认不限 |
单机安装后,管理员和调用方的环境分别在:
. /root/opendsec-ops/env # 管理员:admin token,项目 root
. /root/opendsec-ops/demo.env # 调用方:项目 root/demo 的 token,以及 E2B SDK 的变量sandbox
sandbox create
opendsecctl sandbox create -backend <后端> [-image I] [-cpu N] [-mem MB] [-disk MB] [-gpus N]
[-task T] [-ttl-idle S] [-ttl-max S] [-net 规则,...] [-count N]| 选项 | 默认 | 说明 |
|---|---|---|
-backend | sim | microvm、container、fncall、fullvm、sim。默认 sim 只模拟,实际使用必须指定 |
-image | — | 镜像,例如 root/py:3.12 |
-cpu | 1 | CPU 核数 |
-mem | 1024 | 内存 MB |
-disk | 0 | 可写盘 MB,0 为后端默认 |
-gpus | 0 | GPU 个数 |
-task | — | 任务名 |
-ttl-idle | 0 | 空闲超时(秒),0 为集群默认 |
-ttl-max | 0 | 最长寿命(秒),0 为集群默认 |
-net | — | 网络规则,逗号分隔;!规则 表示收回集群默认里的一项,例如 -net 'pypi,github.com:443,!npm' |
-count | 1 | 批量创建的个数 |
-count 1 时输出 sandbox 的 JSON;-count 大于 1 时每行输出一个结果(序号<TAB>id,失败的是 序号<TAB>error<TAB>原因: 说明),最后一行是汇总:
$ opendsecctl sandbox create -backend microvm -image root/py:3.12 -count 3 -task job-1
0 node-a1.4k2m…
1 node-b1.9xq1…
2 node-a1.p0zz…
created 3/3 in 412ms; failures: map[]在脚本里取 id:
ID=$(opendsecctl sandbox create -backend microvm -image root/py:3.12 | grep -m1 '"id"' | cut -d'"' -f4)sandbox get | stop | pause | resume | touch <id>
查看、停止、暂停、恢复、刷新空闲计时。输出更新后的 sandbox。
sandbox list [-task T] [-all]
列出 -project 及其子项目里的 sandbox;-task 只列这个任务的,-all 包括最近结束的。
sandbox fork <id> [-count N] [-task T] [-ttl-idle S] [-ttl-max S]
把运行中的 sandbox 复制成 N 个(1 到 256),输出格式同批量创建。
sandbox network <id> <规则>... [-replace]
修改网络规则:pypi 放行,!pypi 收回。默认合并进现有规则,-replace 整体替换。
opendsecctl sandbox network $ID pypi github.com:443
opendsecctl sandbox network $ID '!github.com:443'
opendsecctl sandbox network $ID '*' -replace # 只放行全部公网exec <id> [-session S] [-user U] [-timeout S] [--] <命令...>
在 sandbox 里执行命令,实时输出 stdout 和 stderr,以命令的退出码退出。
- 只有一个参数时,它是一整条 shell 命令,由 sandbox 里的 shell 解释:
opendsecctl exec $ID 'cd /srv && make test | tail'。 - 多个参数时,像
ssh和docker exec一样,每个参数各自加引号后拼成命令:opendsecctl exec $ID python3 -c 'print(6*7)'在 sandbox 里执行的就是python3 -c 'print(6*7)'。 - 参数里有以
-开头的(例如ls -la),在命令前加--,避免被当成 opendsecctl 的选项:opendsecctl exec $ID -- ls -la /。 -session:会话名,默认default;-user:会话第一次执行时的用户;-timeout:秒,超时后打印opendsecctl: command timed out。
0.11 之前的版本把多个参数直接用空格连接,不加引号。当时为了绕开这个问题多加的一层引号(例如
"'print(6*7)'")现在要去掉。
cp <id>:<路径> <本地文件> / cp <本地文件> <id>:<路径>
在本机和 sandbox 之间复制单个文件。一次最多复制 64 MB;更大的文件用 SDK 分段读写。
任务
opendsecctl task pause|resume|stop <任务名>对 -project 里这个任务的所有 sandbox 执行操作,输出成功和失败的个数。
镜像
image import <来源> -as <项目>/<名字>:<标签> -store <镜像库>
把镜像导入共享镜像库并登记。要在挂载了镜像库的机器上以 root 运行,并且需要目标项目上的 layer.publish。
来源可以是:
| 来源 | 例子 |
|---|---|
| 公共仓库 | docker.io/library/python:3.12、python:3.12、ghcr.io/org/image:tag |
| 私有仓库 | harbor.example.com/team/app:1.0 |
| 不带 TLS 的仓库 | 加 -plain-http |
| OCI layout 目录或 tar | ./python-3.12.oci.tar |
docker save 生成的 tar | ./app.tar;文件里有多个镜像时用 文件#名字 选一个 |
本地文件路径要以 / 或 . 开头,文件不存在时直接报错(不会去仓库下载)。
私有仓库的凭据,按以下顺序查找:
-username U -password-stdin:密码或访问令牌从标准输入读,例如echo "$TOKEN" | opendsecctl image import ... -username 'robot$ci' -password-stdin;-registry-auth FILE:docker 格式的凭据文件;$REGISTRY_AUTH_FILE、$DOCKER_CONFIG/config.json、~/.docker/config.json(docker login保存的凭据)。
导入不设总时限(大镜像可能要很久),进度打印到标准错误。
image save <来源> -out <文件>
把仓库里的镜像保存为 OCI tar,供不能上网的机器用 image import ./文件 导入。不需要连接集群。支持 -plain-http、-username、-password-stdin。
image compose <新镜像> <part>... [-overwrite]
把多个镜像从底到顶叠成一个,不复制数据:
opendsecctl image compose root/rl/swe-4821:v1 root/rl/python:3.12 root/rl/django-ws:a1b2 root/tools/agent-kit:3image list [-project P]、image get <名字>、image delete <名字>
列出项目及其子项目的镜像;查看一个镜像;删除镜像的登记(层由 image gc 回收)。
image pack <sandbox-id> <新镜像> [-scrub a,b] [-overwrite]
即 pack_diff:把 container sandbox 相对它启动镜像的改动保存为新镜像,默认清理 /tmp、缓存和 shell 历史,-scrub 追加路径(相对 / 的 glob)。
image snapshot <sandbox-id> <新镜像> [-memory] [-overwrite]
把 sandbox 原样保存为镜像。microVM 必须加 -memory(连同内存)。
image gc -store <镜像库> [-grace 24h] [-dry-run]
删除没有任何镜像引用的层和快照。比 -grace 新的不删(默认 24 小时),避免删掉正在导入或刚创建的数据。先用 -dry-run 看会删什么。需要设置连接参数,但只在镜像库上操作。
image store-check -store <目录>
检查一个文件系统(例如新挂的 NAS)能否用作镜像库:权限、硬链接、重命名、xattr、稀疏文件等。必需项全部为 ok 才能使用。不需要连接集群。
$ opendsecctl image store-check -store /mnt/opendsec-images
ok write, sync and read back a file
ok files a root process creates are root's (no root squash)
ok chown to another user (image files keep their owners)
ok exclusive create (one edge builds a VM disk at a time)
ok rename a file over another (manifests, records)
ok rename a directory (layers are published so)
ok hard links (snapshots link their disks)
ok symbolic links
ok finds the holes of sparse files (snapshots move only their data; NFS needs vers=4.2)
ok 0:0 character devices (layer whiteouts)
ok overlay over layers kept here, whiteouts honored
ok trusted.* xattrs
ok user.* xattrs
/mnt/opendsec-images can hold the image store不是必需的项(例如稀疏文件的空洞、trusted.* xattr)失败时只给出提示,仍然可以使用;必需项失败时不能用作镜像库。
项目、身份、权限与 token
| 命令 | 说明 |
|---|---|
project create <上级> <名字> [-quota k=v,...] | 建子项目,例如 project create root team-a -quota sandboxes=1000,cpu_cores=4000,memory_mb=4096000 |
project get <路径> | 项目详情:配额、当前用量、各身份的权限、子项目 |
project delete <路径> | 删除空项目 |
principal create <项目> <id> [-kind agent|user|service] [-ttl S] | 建身份,输出里的 token 只显示这一次 |
principal delete <id> | 删除身份及其全部 token |
grant <项目> <身份> <权限>[,<权限>...] | 授予权限,例如 grant root/team-a trainer sandbox.create,sandbox.operate |
revoke <项目> <身份> [<权限>,...] | 收回权限,不写权限时收回全部 |
token create [<身份>] [-ttl S] [-desc D] | 签发 token,默认给自己 |
token list [<身份>] | 列出 token(不含密钥) |
token revoke <身份> <token-id> | 撤销,约 1 秒内全集群生效。primary 指旧格式的主 token |
whoami | 当前 token 对应的身份 |
usage [<项目>] [-from YYYY-MM-DD] [-to YYYY-MM-DD] [-daily] [-csv] | 用量:默认每个项目在这段时间的合计;-daily 按天、按项目;-csv 输出 CSV |
配额的键:sandboxes、cpu_cores、memory_mb、gpus。权限的含义见项目、身份与权限。
集群
| 命令 | 说明 | 需要 |
|---|---|---|
status | 集群快照:每个 edge 的健康、排空、容量、已分配、sandbox 数、内存和磁盘余量、压力 | — |
edge drain <edge-id> [-undo] | 停止(-undo 恢复)往这台 edge 调度新 sandbox,已有的照常运行 | root 上的 project.admin |
iam backup -out FILE | 备份 IAM(gzip 的 JSON,权限 0600):身份、项目、权限、配额、token 哈希 | root 上的 project.admin |
iam restore FILE | 用备份替换 IAM 的内容(正在运行的 sandbox 的配额租约保留) | 同上 |
iam members | 列出 IAM 的 Raft 副本 | 同上 |
iam member add <id> -raft-addr H:P -iam-addr H:P | 加入一个以 opendsec-iam -join 启动的副本 | 同上 |
iam member remove <id> | 移除一个副本(例如机器已经不在了) | 同上 |
version | 本程序的版本 | — |
证书
不需要连接集群。
| 命令 | 说明 |
|---|---|
pki init -config opendsec.json -out DIR [-days 365] [-ca-days 3650] [-hosts h1,h2] | 生成集群 CA 和配置里每个组件的证书。-hosts 给每张证书加上额外的主机名或 IP |
pki ca -out DIR [-days N] | 只生成新 CA(用于轮换 CA) |
pki issue -ca DIR -role <角色> -id <id> [-hosts ip1,ip2] -out DIR [-days 365] | 给一个组件签证书。角色:edge、apiserver、watcher、iam、fleet、node、ops |
生产集群一般用 opendsecops certs,它会调用这些命令,见多机集群部署。
本地集群与基准
| 命令 | 说明 |
|---|---|
cluster up | 在当前进程里运行一整个集群,用于开发和测试 |
bench | 在进程内的模拟集群上做调度基准;-compare 对比随机放置和 power-of-2 |
cluster up 的选项:
| 选项 | 默认 | 说明 |
|---|---|---|
-config | 生成的模拟集群 | 集群配置文件 |
-sim-edges | 4 | 没有 -config 时模拟的 edge 个数 |
-apiservers | 1 | 没有 -config 时 apiserver 的个数 |
-runtime | sim | 生成的集群里 container 后端的运行时:sim 或 linux(真实容器,需要 root) |
-microvm-kernel | — | 同时提供 microvm 后端,使用这个 guest 内核 |
-image-store | — | 共享镜像库目录(启用镜像库、pack_diff) |
-state-dir | /var/lib/opendsec | sandbox 状态目录(linux 运行时) |
-host-image | true | 提供开发用的 host 镜像(宿主机的 / 作为只读底层,会暴露宿主机文件,只用于开发) |
-disk-reserve-mb | 512 | 状态目录剩余空间低于此值时拒绝创建,-1 关闭 |
-tls | false | 生成 CA 和证书,以 mTLS 运行 |
-audit-dir | — | apiserver 审计日志目录 |
-metrics | — | Prometheus 指标地址,例如 :9464 |
-write-config | — | 把实际使用的配置(含绑定的地址)写到这个文件 |
-log | info | 日志级别 |
./bin/opendsecctl cluster up -sim-edges 1 -runtime linux -image-store /mnt/opendsec-images \
-microvm-kernel /opt/opendsec/vm/vmlinux-6.1.167-opendsec
# 按输出设置 OPENDSEC_ADDR、OPENDSEC_TOKEN、OPENDSEC_PROJECTfleet:集群版本和配置
经 apiserver 访问,需要 root 上的 fleet.view(查看)或 fleet.operate(操作);project.admin 两者都包括。所有操作都写入审计日志。
| 命令 | 说明 |
|---|---|
fleet nodes [-state S] [-role R] [-domain D] | 列出机器:状态、故障域、角色、期望版本、实际版本、单元就绪数、最后心跳 |
fleet node get <名字> | 一台机器的详情 |
fleet node accept <名字> -roles edge=<id>[,...] [-domain D] [-addr-ip IP] [-labels k=v,...] | 接纳新上报的机器,下发当前版本和配置并启动 |
fleet node set <名字> [-roles ...] [-domain D] [-addr-ip IP] [-labels k=v,k=] | 修改角色、故障域、标签(k= 删除标签)。只改记录,不部署 |
fleet node sync <名字> | 把这台机器同步到它应有的版本、配置和角色 |
fleet node cordon | uncordon <名字> | 暂停、恢复往它调度 |
fleet node evacuate <名字> [-deadline 1h] | cordon,然后等它上面的 sandbox 全部结束 |
fleet node retire <名字> | 下线:停止并禁用它的组件 |
fleet node pin <名字> [-reason R]、unpin <名字> | 锁定、解锁:锁定的机器不参与 rollout |
fleet import -inventory FILE -release V [-config-gen G] [-domain D] | 登记已经在运行版本 V 的机器(从 opendsecops 迁移时用) |
fleet releases | 已上传的版本 |
fleet release pack -bin DIR -units DIR [-deps DIR] -out DIR | 打包版本目录(通常用 opendsecops release) |
fleet release push <版本目录> [-notes N] | 上传版本到 fleet 的所有副本 |
fleet config put <cluster.json> [-note N] | 上传新的集群配置,生成新的配置代数 |
fleet config get [-gen N] [-out FILE] | 取出某一代配置 |
fleet rollout create [-release V] [-config-gen G] [...] | 发起升级或配置变更,见下表 |
fleet rollout status [<id>] [-steps] | 查看进度,默认最新的一次;-steps 列出每台机器 |
fleet rollout pause | resume | abort | rollback <id> | 暂停、继续、中止、回滚 |
fleet rollouts | 历次 rollout |
fleet rollout create 的选项:
| 选项 | 说明 |
|---|---|
-release V、-config-gen G | 目标版本、目标配置代数(至少一个) |
-roles、-domains、-nodes、-labels | 只对这些角色、故障域、机器、标签的机器做 |
-canary N | 先单独升级的试点台数,默认 1;-1 表示不要试点 |
-bake S | 试点和每批升级后的观察时间(秒),默认 300;-1 表示不观察 |
-batch N | 每批的台数,默认非控制面机器数的 5%(至少 1,最多 100) |
-max-per-domain N | 每批里同一故障域最多几台,默认每批台数的一半(至少 1) |
-pause S | 批与批之间的间隔(秒),默认 60;-1 表示不间隔 |
-max-failures N | 允许失败的台数,超过就暂停;默认 0,即第一台失败就暂停 |
-step-timeout S | 单台机器的超时(秒),默认 600 |
-note N | 备注 |
apiserver 全部不可用时,在运维机上用 ops 证书直连 fleet:
opendsecctl fleet nodes -direct -fleet 10.0.0.1:7300,10.0.0.2:7300 -pki $OPENDSEC_OPS/pki -ops-id ops完整的发版流程见运维手册 §6。