
CubeSandbox 服务管理与日志排障实战指南systemd 体系下的日常运维手册【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox本指南面向已完成 CubeSandbox 一键安装、需要在日常运行中维护整个集群健康的运维人员。通过本文你将掌握宿主机上各 systemd 服务之间的依赖关系与角色聚合机制、编辑配置后该重启哪个服务、服务反复失败时的定位思路以及运行时日志/data/log/与启动日志journalctl的边界——最终能够安全地停止、重启整条链路并快速定位故障。适用范围与 TL;DR 速查本文描述的是systemd 托管的一键安装版。如果你仍在使用旧版up-with-deps.sh/down-with-deps.sh作为日常入口那属于 pre-systemd 版本——重新运行最新一键安装脚本即可自动迁移安装器会检测旧布局并接管。日常运维高频命令先记住这一页# 1. 检查所有 cube-sandbox 服务是否存活 sudo systemctl --no-legend list-units cube-sandbox-* # 2. 改了配置 - 重启对应的服务 sudo systemctl restart cube-sandbox-cube-api.service sudo systemctl restart cube-sandbox-cubemaster.service sudo systemctl restart cube-sandbox-cubelet.service # 3. 运行时日志请求 / 统计 / 审计 / VMM在 /data/log/ 下不在 journalctl 里 sudo tail -F /data/log/Cubelet/Cubelet-req.log sudo tail -F /data/log/CubeMaster/cubemaster-req.log sudo tail -F /data/log/CubeAPI/cube-api-$(date %F).log sudo tail -F /data/log/CubeVmm/vmm.log # 沙箱 VMM 生命周期 sudo tail -F /data/log/cube-proxy/error.log # 代理错误 # 4. 启动失败 / 进程退出原因 - journalctl sudo journalctl -u cube-sandbox-cube-api.service -n 200 --no-pager # 5. 一键诊断包/data/log 尾部 配置 dmesg 进程快照 sudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh⚠️运行时日志在/data/log/不在journalctl这是新运维最容易踩的坑。每个组件只把启动阶段的 stdout/stderr 送给 journal而请求、调度、统计、审计、VMM 创建日志是直接写入/data/log/Module/的。要查过去一小时谁创建了沙箱请去/data/log/而不是journalctl。服务体系总览一键安装器会在/etc/systemd/system/下注册一批 systemd 单元并聚合为两个角色级 target。以当前仓库为准deploy/one-click/systemd/目录下共包含 18 个单元文件除了下表的 9 个核心服务外还有cube-sandbox-cube-egress.service、cube-sandbox-cube-egress-net.service、cube-sandbox-cube-lifecycle-manager.service、cube-sandbox-cubeops.service、cube-sandbox-cube-templatecenter.service、cube-sandbox-minio.service、cube-sandbox-s3lvol.service等扩展服务。角色 targetTarget用途角色cube-sandbox-control.target全部控制面服务默认 all-in-onecontrolcube-sandbox-compute.target纯计算节点的最小子集compute聚合机制target 通过Wants声明子服务每个服务通过PartOf声明归属。因此systemctl stop cube-sandbox-control.target会一次性停止所有PartOfcube-sandbox-control.target的服务——无需罗列一长串单元名。从源码可以印证这一点例如 cube-sandbox-control.target 中Wantscube-sandbox-mysql.service cube-sandbox-redis.service cube-sandbox-minio.service Wantscube-sandbox-cubemaster.service cube-sandbox-cube-api.service cube-sandbox-cubeops.service Wantscube-sandbox-cube-templatecenter.service Wantscube-sandbox-cubelet.service Wantscube-sandbox-cube-lifecycle-manager.service Wantscube-sandbox-cube-proxy.service cube-sandbox-coredns.service Wantscube-sandbox-dns.service cube-sandbox-webui.service Wantscube-sandbox-cube-egress-net.service cube-sandbox-cube-egress.service而 cube-sandbox-compute.target 只保留计算侧的最小集合Wantscube-sandbox-cubelet.service Wantscube-sandbox-cube-egress-net.service cube-sandbox-cube-egress.service服务目录单元进程形态端口 / 监听存在于上游依赖cube-sandbox-mysql.serviceDocker 容器3306controldockercube-sandbox-redis.serviceDocker 容器6379controldockercube-sandbox-cubemaster.service宿主机进程8089controlmysql, rediscube-sandbox-cube-api.service宿主机进程3000E2B 兼容 APIcontrolcubemastercube-sandbox-cubelet.service宿主机进程9999gRPCHTTP 诊断control / compute内置网络运行时 /data/cubeletXFScube-sandbox-coredns.serviceDocker 容器127.0.0.54:53或169.254.254.53:53controldockercube-sandbox-cube-proxy.serviceDocker 容器443TLS/80/9090gRPCcontroldocker, rediscube-sandbox-dns.serviceoneshot无守护进程—controlcorednsBindsTocube-sandbox-webui.serviceDocker 容器12088controldocker, cube-api源码细节可对照 cube-sandbox-cubelet.service它使用Typeforking通过ExecStartPreprepare-compute-role.sh准备角色环境RequiresMountsFor/data/cubelet /data/cube-shim /data/snapshot_pack强制要求这些挂载点就绪PID 文件落在/run/cube-sandbox-systemd/cubelet.pid并声明PartOfcube-sandbox-control.target cube-sandbox-compute.target所以同一单元同时归属于两个角色 target。启动依赖图控制节点docker.service ├─ mysql.service ─┐ ├─ redis.service ─┼─ cubemaster.service ─ cube-api.service ─ webui.service │ └─ cube-proxy.service └─ coredns.service ─ dns.service (oneshot, BindsTo coredns) network-online.target └─ cubelet.service (embedded network runtime)重要依赖只表达启动顺序通过After/Wants。如果上游服务在运行期崩溃下游不会被自动重启——cubelet 不会因为 cube-api 挂了就被重启反之亦然。重启服务场景 A改了配置想让配置生效两个最常见的配置入口顶层环境变量/usr/local/services/cubetoolbox/.one-click.env各组件配置Cubelet/config/config.toml、Cubelet/dynamicconf/conf.yaml、CubeMaster/conf.yaml、cubeproxy/global.conf、coredns/Corefile重启消费该配置的那个服务# Cubelet 配置 sudo systemctl restart cube-sandbox-cubelet.service # CubeMaster 配置 sudo systemctl restart cube-sandbox-cubemaster.service # .one-click.env 中的 CUBE_API_* sudo systemctl restart cube-sandbox-cube-api.service # cubeproxy/global.conf sudo systemctl restart cube-sandbox-cube-proxy.service # coredns/Corefile sudo systemctl restart cube-sandbox-coredns.service⚠️如果你改了 systemd 单元文件本身修改/etc/systemd/system/cube-sandbox-*.service后必须执行daemon-reload让 systemd 读取新内容sudo systemctl daemon-reload sudo systemctl restart cube-sandbox-service.service如果只改了辅助脚本/usr/local/services/cubetoolbox/scripts/systemd/*.sh则无需daemon-reload——下次restart会重新调用脚本。以 cube-sandbox-cubemaster.service 为例其ExecStart和ExecStartPost分别指向cubemaster-start.sh与cubemaster-postcheck.sh并显式通过EnvironmentCUBE_MASTER_CONFIG_PATH/usr/local/services/cubetoolbox/CubeMaster/conf.yaml指定配置路径——这正是改 conf.yaml 后重启 cubemaster 才生效的机制来源。CubeMaster 超时设置 {#cubemaster-settings}路径/usr/local/services/cubetoolbox/CubeMaster/conf.yaml一键包来源于 configs/single-node/cubemaster.yaml。cubelet_conf下的关键键键作用default_timeout_insec当客户端省略timeout时服务端默认的沙箱空闲 TTL秒。不设置或 0表示无集群级空闲超时除非客户端显式设置timeout否则沙箱不会因空闲而被回收。仓库默认-1即无默认行为。生产环境如需自动回收未显式指定 TTL 的沙箱可设为正值如300。create_timeout_insec仅针对 create/调度 RPC 的截止时间——不是沙箱空闲 TTL。未设置时默认600。common_timeout_insec非 create 路径上通用的 CubeMaster→Cubelet RPC 超时。create_image_timeout_insecCubeMaster 指示单个计算节点下载镜像的超时覆盖下载、校验、存储 rootfs 制品的全过程。大镜像、低带宽或慢磁盘时应调大。默认300秒。app_snapshot_timeout_insecCubeMaster 指示单个计算节点创建模板的超时覆盖启动临时 VM、等待就绪探针、保存内存与磁盘状态、清理临时 VM、返回结果。未设置或非正值时默认300秒。网络差或模板大时应调大。镜像下载与模板创建的超时相互独立各自从对应 RPC 开始时计时。示例配置cubelet_conf: create_image_timeout_insec: 300 app_snapshot_timeout_insec: 600修改后重启 CubeMaster 生效sudo systemctl restart cube-sandbox-cubemaster.service对照仓库 CubeMaster/conf.yaml实际出厂配置与文档一致common_timeout_insec: 30、create_image_timeout_insec: 300、app_snapshot_timeout_insec: 300、default_timeout_insec: -1、create_timeout_insec: 600同时还有create_concurrent_limit: 100、destroy_concurent_limit: 100、enable_exposed_port、exposed_port_list等调度并发与端口暴露相关参数。更多细节可参考 Sandbox lifecycle — Operational Notes集群级默认空闲超时default_timeout_insec。场景 B服务失败 / 反复重启每个服务都设置了Restarton-failure单次崩溃会被自动拉起。如果单元陷入 restart-loop先找根因。1. 查看当前状态sudo systemctl status cube-sandbox-cube-proxy.service --no-pager重点观察Active: failed/Active: activating (start-post)仍在尝试Restart Counter快速攀升重启循环底部最后 10 行 journal 输出2. 读启动日志sudo journalctl -u cube-sandbox-cube-proxy.service -n 200 --no-pager适合定位脚本 bug、ExecStart失败、docker pull报错、apk/apt网络错误、ExecStartPost健康检查超时。3. 读运行时日志如果服务能起来但行为异常运行时日志在/data/log/不在 journal 里sudo tail -200 /data/log/Cubelet/Cubelet-req.log sudo tail -200 /data/log/CubeMaster/cubemaster-req.log sudo tail -200 /data/log/CubeAPI/cube-api-$(date %F).log4. 复位失败计数并重启sudo systemctl reset-failed cube-sandbox-cube-proxy.service sudo systemctl restart cube-sandbox-cube-proxy.service场景 C整栈重启 / 维护后恢复# 控制节点 sudo systemctl restart cube-sandbox-control.target # 计算节点 sudo systemctl restart cube-sandbox-compute.target或从发布包目录执行sudo ./down.sh sudo systemctl start cube-sandbox-control.target重启 target 按依赖顺序重启所有 PartOf 服务。target 本身没有进程重启它会令 systemd 按依赖顺序循环所有PartOfcube-sandbox-control.target的服务——是重启全部的简写。场景 D全量停机# 推荐使用自带脚本自动识别角色 sudo /root/cube-sandbox-one-click-version/down.sh # 等价写法 sudo systemctl stop cube-sandbox-control.target # 控制节点 sudo systemctl stop cube-sandbox-compute.target # 计算节点down.sh不会删除数据MySQL / Redis 卷、/data/cubelet、/data/log/...全部保留下次start时自动恢复。日志体系CubeSandbox 有多个日志来源包括各组件容器内日志。宿主机侧的两个主要入口来源内容读取方式运行时日志首选入口请求、调度决策、统计、审计、VMM 创建/data/log/Module/启动日志systemd 启动 / 钩子 / ExecStartPost / 退出码 / 容器构建输出journalctl -u unit/data/log/运行时日志首选⚠️ Cubelet / CubeMaster / CubeAPI / CubeShim / VMM 都把业务请求 统计 审计 VMM 生命周期日志写到/data/log/。它们不会出现在journalctl中——请直接读文件。模块目录主要文件Cubelet/data/log/Cubelet/Cubelet-req.log请求Cubelet-stat.log指标/统计CubeMaster/data/log/CubeMaster/cubemaster-req.logCubeAPI/data/log/CubeAPI/cube-api-YYYY-MM-DD.log按日轮转CubeShim/data/log/CubeShim/cube-shim-req.log、cube-shim-stat.logHypervisor (VMM)/data/log/CubeVmm/vmm.log每次沙箱创建一条记录cube-proxy/data/log/cube-proxy/error.log、access.log见下文常用命令# 跟随 Cubelet 请求 sudo tail -F /data/log/Cubelet/Cubelet-req.log # 跟随按日轮转的 CubeAPI 日志E2B 兼容层 sudo tail -F /data/log/CubeAPI/cube-api-$(date %F).log # 沙箱启动慢 / 失败看 VMM 日志 sudo tail -200 /data/log/CubeVmm/vmm.logCubeShim 与 VMM 日志轮转CubeShim 和 VMM 运行期间会一直持有日志文件描述符。CubeShim 每 30 分钟触发一次内部轮转重开文件VMM 控制线程持有一个单调timerfd每小时发出一次LOG_CTRL_REOPEN控制记录。重开是调度驱动的外部的renamecreate会在下一次调度重开时被拾取而不是任意一次写入时立即被感知。该定时器归属 VMM 控制线程不归属延迟日志初始化或 vCPU/API 线程。因此宿主机侧策略应当每小时执行一次使用renamecreate不要用copytruncate。示例安装为/etc/logrotate.d/cubesandbox并确保宿主机按小时调用logrotate/data/log/CubeVmm/vmm.log /data/log/CubeShim/*.log { hourly rotate 24 missingok notifempty compress delaycompress create 0640 root root }rotate 24保留 24 个按小时的归档文件按需调整保留周期。delaycompress让最新一份轮转文件保持未压缩一个周期——因为写入方在下次调度重开前可能仍持有旧描述符。CubeShim 内部事件每 30 分钟一次VMM 控制线程每小时发送一次重开控制事件。无需postrotate信号或服务重启。该策略保证宿主机上有界保留但不承诺对任意手动轮转的即时处理也不支持copytruncate。示例使用root root是因为一键安装的 systemd 服务以 root 运行。如果 CubeShim 或 VMM 运行在其他账号下请把create的属主属组改为该账号否则新建文件可能无法被重开。0640权限适用于logrotate创建的文件CubeShim 与 VMM 写入方本身仍使用进程 umask。journalctl启动日志journalctl 捕获的是systemd 启动进程后、直到进程稳定或退出期间的 stdout/stderr适合排查启动失败退出码 / 错误信息ExecStart/ExecStartPost/ExecStop钩子的输出docker pull/docker build/apk update失败自动重启计数与原因# 最后 200 行 sudo journalctl -u cube-sandbox-cubelet.service -n 200 --no-pager # 实时跟随 sudo journalctl -u cube-sandbox-cubemaster.service -f # 上次开机以来的全部记录 sudo journalctl -u cube-sandbox-cube-api.service -b⚠️journalctl 里没有业务请求日志进程稳定后其 stdout/stderr 流量极小因为各组件把业务日志直接写到/data/log/Module/。要查过去一小时创建了哪些沙箱journalctl 找错地方了——请去/data/log/CubeMaster/cubemaster-req.log或/data/log/Cubelet/Cubelet-req.log。cube-proxy宿主机日志cube-proxy是 OpenResty/nginx 容器。一键部署把宿主机目录/data/log/cube-proxy/bind-mount 到容器内的相同路径因此容器重启后日志依然可用可直接在宿主机读取sudo tail -200 /data/log/cube-proxy/error.log sudo tail -200 /data/log/cube-proxy/access.log同一目录在容器内同样挂载于/data/log/cube-proxy/无需重建镜像。一键诊断包向社区反馈问题或提交 issue 时使用内置诊断收集器sudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh脚本源码位于 deploy/one-click/scripts/cube-diag/collect-logs.sh收集结果汇总到cube-diag-timestamp//data/log/CubeMaster|Cubelet|CubeAPI|CubeShim|CubeVmm/的日志尾部默认每个文件 2000 行/data/log/cube-proxy/的 access/error 日志dmesg含 KVM/PVM/cube 过滤视图、OOM/硬件错误视图/ 进程列表 / 端口 / 挂载 / cgroup / cpuinfo主要配置文件密钥自动脱敏脱敏规则见脚本内_redact()会匹配password|secret|token|key等键打包分享tar czf cube-diag-ts.tar.gz cube-diag-ts/按需选择性收集——例如只要 cubelet dmesgsudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh \ --module cubelet --module dmesg --lines 500脚本支持的模块名cubemaster、cubelet、cube-api、cubeshim、cubevmm、cube-proxy、runtime、dmesg、env、configs。其他可用参数--all-lines拷贝完整日志注意部分日志超过一百万行、--dir dir指定输出目录目标目录不允许已存在且非空、--help完整帮助。输出目录已存在且非空时脚本会报错退出这是刻意设计防止覆盖已有诊断结果。运维速查表目标命令列出本节点所有 cube 服务systemctl --no-legend list-units cube-sandbox-*查看单个服务状态systemctl status cube-sandbox-service.service查看 target 依赖树systemctl list-dependencies cube-sandbox-control.target启动 / 停止 / 重启单个服务systemctl {start\|stop\|restart} cube-sandbox-service.service启动 / 停止 / 重启整个栈systemctl {start\|stop\|restart} cube-sandbox-{control,compute}.target服务为何失败journalctl -u cube-sandbox-service.service -n 200 --no-pager实时跟随启动输出journalctl -u cube-sandbox-service.service -f复位失败计数systemctl reset-failed cube-sandbox-service.service运行健康检查sudo /root/cube-sandbox-one-click-*/smoke.sh或sudo /usr/local/services/cubetoolbox/scripts/one-click/quickcheck.sh全量停机sudo /root/cube-sandbox-one-click-*/down.sh收集诊断包sudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh典型排障流程沙箱创建失败 / 超时按层级依次排查角色 target 是否激活sudo systemctl status cube-sandbox-control.target跑健康检查sudo /root/cube-sandbox-one-click-*/smoke.shCubeAPI 是否收到请求sudo tail -F /data/log/CubeAPI/cube-api-$(date %F).logCubeMaster 调度链路sudo tail -F /data/log/CubeMaster/cubemaster-req.log节点Cubelet是否在线并被调度curl http://127.0.0.1:3010/internal/v1/nodes sudo tail -F /data/log/Cubelet/Cubelet-req.logVMM 启动错误sudo tail -200 /data/log/CubeVmm/vmm.log服务卡在activating (start-post)sudo systemctl status cube-sandbox-service.service sudo journalctl -u cube-sandbox-service.service -n 200 --no-pager常见根因容器构建需要网络如cube-proxy的apk update而上游镜像源不稳定——参见 Deployment TroubleshootingExecStartPost健康探测超时端口被占用、上游未就绪对于cube-sandbox-cube-proxy.serviceCUBE_PROXY_HTTP_PORT和CUBE_PROXY_GRPC_PORT是 post-start TCP 探测检查的 nginx 监听端口CUBE_PROXY_HOST_PORT已废弃并被忽略如需非默认 HTTP 检查端口请设置CUBE_PROXY_HTTP_PORT/data/log或/data/cubelet缺失 / 权限错误 / XFS 未挂载从源码看cube-sandbox-cube-proxy.service 把TimeoutStartSec设为180s注释明确说明原因首次运行路径要通过 compose 构建 cube-proxy 镜像同时把TimeoutStopSec设为30s规避部分发行版如 OpenCloudOS默认DefaultTimeoutStopUSec5s过紧、导致优雅停机路径留下孤儿 Exited 容器的问题。而 cube-sandbox-dns.service 因 standalone-dnsmasq 后端可能串联多个有界等待上游快照最长 20s 端口空闲重试 dnsmasq bind 30s CoreDNS 20s最坏情况超过 60s故把TimeoutStartSec放宽到120s。这些单位文件中的注释本身就是极好的排障线索。Dashboard / API 不可达# WebUI 容器 sudo systemctl status cube-sandbox-webui.service sudo ss -lntp sport :12088 # CubeAPI 监听 sudo systemctl status cube-sandbox-cube-api.service sudo ss -lntp sport :3000附录路径速查用途路径安装根目录/usr/local/services/cubetoolbox/运行时环境变量文件/usr/local/services/cubetoolbox/.one-click.envsystemd 单元安装目录/etc/systemd/system/cube-sandbox-*systemd 辅助脚本/usr/local/services/cubetoolbox/scripts/systemd/*.sh运行时日志首选/data/log/Module/Cubelet 容器层XFS/data/cubelet/沙箱镜像 / 快照/data/cube-shim/disks/、/data/snapshot_pack/disks/systemd PID 文件/run/cube-sandbox-systemd/角色 / 服务矩阵服务control节点compute节点mysql/redis✅—cubemaster✅—cube-api✅—webui✅—cube-proxy/coredns/dns✅—cubelet✅✅关联文档Quick Start — 安装入口Multi-Node Cluster — 计算节点上的服务子集CubeMaster Scheduler Configuration — 节点选择、配额、标签、打分与模板重做Deployment Troubleshooting — XFS、CIDR 冲突等部署问题Templates Troubleshooting — 模板构建问题【免费下载链接】CubeSandboxInstant, Concurrent, Secure Lightweight Sandbox for AI Agents.项目地址: https://gitcode.com/GitHub_Trending/cu/CubeSandbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考