进阶 docs.cubesandbox.com 2026-10-08 23:44:25 · 0 阅读

第30章 服务管理与日志

服务管理与日志 ​本页面面向已经把 CubeSandbox 装好、想要在日常运维中管好这套服务的用户。读完本页你会知道:这台机器上具体跑了哪些 systemd 服务,它们之间的依赖关系改了配置之后,要重启哪几个服务才能让它生效服务跑挂了应该怎么排查业务日志、启动期日志、容器内日志各在哪里,以及它们的边界完整下线 / 重启整机栈的姿势适用范围本页对应新版(systemd 托管)的一键安装包。如果你的机器上还能看到 up-with-deps.sh / down-with-deps.sh 这类脚本作为日常入口,那是 pre-systemd 老版本,重新执行最新一键安装包即可平滑升级(安装器内置了对老部署的接管逻辑)。TL;DR 一分钟备忘 ​bash# 1. 看整台机器上 cube 系列服务都还活着吗 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/,不在 journal 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 的 tail + 配置 + dmesg + 进程快照) sudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh业务日志在 /data/log/,不在 journalctl这是新用户最容易踩的一点:CubeSandbox 各组件只把启动期 stdout/stderr 留给 journal,请求 / 调度 / 统计 / 审计 / VMM 创建过程等业务日志全部直接写到 /data/log//。如果你想看「最近一小时谁创建了沙箱」,要去 /data/log/,不要去 journalctl。服务总览 ​新版一键安装会把 14 个 systemd 单元注册到 /etc/systemd/system/,并按节点角色聚合到两个 target 之下。角色聚合 target ​Target作用节点角色cube-sandbox-control.target控制节点(默认 all-in-one)的全部服务controlcube-sandbox-compute.target计算节点的最小子集compute这是怎么生效的Target 通过 Wants= 列出自己要拉起的 service;service 通过 PartOf= 反向声明属于哪个 target。所以 systemctl stop cube-sandbox-control.target 会把所有 PartOf=cube-sandbox-control.target 的 service 一起停掉,不需要你逐个写名字。服务清单 ​单元进程形态端口 / 监听出现在上游依赖cube-sandbox-mysql.serviceDocker 容器3306controldockercube-sandbox-redis.serviceDocker 容器6379controldockercube-sandbox-cubemaster.service宿主机进程8089controlmysql, rediscube-sandbox-cube-api.service宿主机进程3000(E2B 兼容 API)controlcubemastercube-sandbox-cubelet.service宿主机进程9999(gRPC)、HTTP 诊断接口control / compute内置 network runtime + /data/cubelet(XFS)cube-sandbox-coredns.serviceDocker 容器127.0.0.54:53 或 169.254.254.53:53controldockercube-sandbox-cube-proxy.serviceDocker 容器443(TLS)/ 80 / 9090(gRPC)controldocker, rediscube-sandbox-dns.serviceoneshot(无常驻进程)—controlcoredns(BindsTo)cube-sandbox-webui.serviceDocker 容器12088controldocker, cube-api启动依赖关系(控制节点) ​textdocker.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(内置 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改完之后,重启直接读这份配置的那个服务:bash# 改了 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 unit 文件本身的情况如果你直接动了 /etc/systemd/system/cube-sandbox-*.service 文件本身,需要先 reload,systemd 才会读到新内容:bashsudo systemctl daemon-reload sudo systemctl restart cube-sandbox-.service但如果你只是改了 helper 脚本(/usr/local/services/cubetoolbox/scripts/systemd/*.sh),不需要 daemon-reload,下一次 restart 就会重新拉起脚本生效。Cubelet 工件路径 ​Cubelet 会把由 Docker/OCI 镜像构建的模板根文件系统保存为只读 ext4 工件。可以在 Cubelet/config/config.toml 的 [plugins."io.cubelet.internal.v1.images"] 段中配置工件目录和模板运行时使用的内核源文件:toml[plugins."io.cubelet.internal.v1.images"] image_base_path = "/usr/local/services/cubetoolbox/cubebox_os_image" shared_kernel_path = "/usr/local/services/cubetoolbox/cube-kernel-scf/vmlinux"image_base_path 是 cubebox 模板工件的最终缓存目录,每个工件位于 //.ext4,并包含对应的 .vm 文件。shared_kernel_path 是模板工件以及无模板沙箱使用的 vmlinux 源文件。两个路径都必须是绝对路径。省略时,Cubelet 保留历史 toolbox 路径;cubetool_base_dir 仍作为旧配置的兼容 fallback。设置任一新路径后,该路径以新配置为准,旧配置不会覆盖它。如果旧 cbri 配置自定义了 base_path,应显式将 shared_kernel_path 设为该安装目录下匹配的内核路径;base_path 仍控制无模板沙箱使用的 guest 和 agent 镜像,但不再选择 vmlinux。配置的内核路径必须与节点当前选中的 bm/pvm 内核变体和 digest 一致;修改这个路径不会为节点或模板上报选择另一套 kernel identity。工件目录和内核路径相互独立。修改任一路径后都需要重启 Cubelet。Cubelet 不会自动搬迁已有工件;切换到新路径前,需要先让受影响的缓存或内核文件在新路径可用。已有 snapshot 还必须继续让历史工件路径可访问(例如通过部署层软链),或者重建相关 snapshot,因为 snapshot 元数据保存了 kernel 和 ext4 工件的绝对路径。旧 cbri 插件中的 image_base_path 和 kernel_base_path 不再作为工件路径来源,请改在 images 插件段配置工件路径。如果旧字段中有自定义值,应先把需要保留的值复制到 images 插件段,再删除或更新旧字段。cubelet config dump 和 cubelet config migrate 会把解析后的工件路径写成显式的 image_base_path 和 shared_kernel_path。使用导出的配置文件后,如需调整路径,应修改这两个显式字段;只修改 cubetool_base_dir 不会覆盖它们。CubeMaster 配置项 ​路径:/usr/local/services/cubetoolbox/CubeMaster/conf.yaml(one-click 包内来自 configs/single-node/cubemaster.yaml)。cubelet_conf 段中的主要超时字段:配置项说明default_timeout_insec客户端不传 timeout 时,集群默认的沙箱空闲 TTL(秒)。未配置或 <= 0 表示不设集群级空闲超时(沙箱不会因空闲被自动回收,除非客户端显式传 timeout)。仓库默认为 -1,即“无集群默认”。生产环境若需自动回收未带 TTL 的沙箱,可改为正数(如 300)。create_timeout_insec仅限制创建/调度 RPC 的截止时间,不是沙箱空闲 TTL。未配置时默认 600。common_timeout_insecCubeMaster 访问 Cubelet 的通用 RPC 超时(非 create 专用)。create_image_timeout_insecCubeMaster 调用单个计算节点下载镜像的超时时间。它包含下载、校验和保存 rootfs artifact 的时间。大镜像、低带宽或磁盘较慢时可适当调大。默认值 300(秒)。app_snapshot_timeout_insecCubeMaster 调用单个计算节点创建模版的超时时间。它包含制作模版时启动临时虚拟机、等待 readiness probe、保存内存和磁盘状态、清理临时虚拟机并返回结果的总时间。未配置或配置为非正数时,使用默认值 300(秒)。网络较差或模版较大时可适当调大。下载镜像和创建模版的 timeout 相互独立,分别从对应 RPC 发起时开始计时。配置示例:yamlcubelet_conf: create_image_timeout_insec: 300 app_snapshot_timeout_insec: 600修改上述任一 CubeMaster 配置后,需要重启 CubeMaster:bashsudo systemctl restart cube-sandbox-cubemaster.service相关说明见沙箱生命周期 — 设计与运维要点。场景 B:服务挂了 / 反复重启 ​每个 service 都配了 Restart=on-failure,进程崩一次会自动重启。但如果反复 fail,需要先看清楚原因再重启。1. 先看一眼当前状态 ​bashsudo systemctl status cube-sandbox-cube-proxy.service --no-pager重点看:Active: failed / Active: activating (start-post) 是不是还在尝试Restart Counter 是否反复增长(卡在重启循环)输出末尾自动带的最近 10 条 journal2. 看启动期日志 ​bashsudo journalctl -u cube-sandbox-cube-proxy.service -n 200 --no-pager适合定位:脚本写法问题、ExecStart 报错、容器拉不到镜像、apk / apt 网络问题、ExecStartPost 健康检查超时。3. 看业务日志 ​如果服务能起来但行为异常,业务日志在 /data/log/,不在 journal:bashsudo 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. 重置 failed 计数后再启 ​bashsudo systemctl reset-failed cube-sandbox-cube-proxy.service sudo systemctl restart cube-sandbox-cube-proxy.service场景 C:整套重启 / 整机维护后复位 ​bash# 控制节点 sudo systemctl restart cube-sandbox-control.target # 计算节点 sudo systemctl restart cube-sandbox-compute.target或者发布包目录下:bashsudo ./down.sh sudo systemctl start cube-sandbox-control.target重启 target 等于按依赖顺序重启所有 PartOf 服务target 本身没有进程,restart target 时 systemd 会顺序重启所有 PartOf=cube-sandbox-control.target 的 service。这条命令是替代「逐个写一长串 service 名」的快捷方式。场景 D:完整下线(停止整套服务) ​bash# 推荐:用发布包内的脚本(自动按角色走) sudo /root/cube-sandbox-one-click-/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 有多种日志来源,其中也包括各组件自己的容器内日志。宿主机侧主要有以下两个入口:来源包含什么在哪里看业务行为日志(推荐入口)请求、调度决策、stat、audit、VMM 启动过程/data/log//启动期日志systemd 拉起 / hook / ExecStartPost / 退出码 / 容器 build 输出journalctl -u /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(每次创建沙箱都会写 VMM 日志)cube-proxy/data/log/cube-proxy/error.log、access.log(见下文)常用命令:bash# 跟踪 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 分钟轮转事件 reopen。VMM 控制线程自己持有 monotonic timerfd,每小时发出已有的 LOG_CTRL_REOPEN 控制记录。reopen 由固定周期驱动:宿主机执行“rename + create”后,会在下一次计划中的 reopen 时切换到新文件,而不是在任意一次写入时立即检测。该定时器由 VMM 控制线程持有,不依赖延迟 logger 初始化,也不会由 vCPU/API 线程创建。因此宿主机侧仍应按小时执行轮转,并使用“rename + create”方式,不要使用 copytruncate。例如,将下面内容保存为 /etc/logrotate.d/cubesandbox,并确保宿主机每小时执行一次 logrotate:text/data/log/CubeVmm/vmm.log /data/log/CubeShim/*.log { hourly rotate 24 missingok notifempty compress delaycompress create 0640 root root }rotate 24 表示保留 24 个小时文件,可按实际保留周期调整。delaycompress 会将最新的轮转文件延迟一个周期压缩,因为 writer 在下一次计划中的 reopen 之前可能仍使用旧 fd。CubeShim 每 30 分钟触发一次内部事件,VMM 控制线程每小时发送一次 reopen 控制事件。不需要 postrotate 信号或重启服务;该策略保证宿主机侧 retention 有界,但不承诺对任意手工轮转立即响应,也不支持 copytruncate。示例使用 root root,因为随附的一键部署 systemd 服务以 root 运行。如果 CubeShim 或 VMM 使用其他账号运行,请把 create 的 owner 和 group 改成对应账号;否则新建文件可能无法被 reopen。 示例中的 0640 只适用于 logrotate 创建的文件;CubeShim 和 VMM writer 本身仍遵循进程的 umask。journalctl 启动期日志 ​journalctl 看的是进程被 systemd 拉起到稳定运行(或失败退出)期间的 stdout/stderr,主要用于:启动失败的退出码 / 异常信息ExecStart / ExecStartPost / ExecStop 各 hook 的输出容器拉镜像、docker build / apk update 等失败信息服务被自动重启的次数与原因bash# 最近 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 -bjournalctl 里没有业务请求日志进程跑稳之后的 stdout/stderr 输出非常少,因为各组件都把业务日志直接写到 /data/log//。如果你想看「最近一小时谁创建了沙箱」,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 到容器内同一路径,容器重启后日志仍然保留,可以直接从宿主机读取:bashsudo tail -200 /data/log/cube-proxy/error.log sudo tail -200 /data/log/cube-proxy/access.log容器内仍使用同一个 /data/log/cube-proxy/ 路径,不需要重新构建镜像。一键打包诊断信息 ​如果要拿一整套日志去问社区或提 issue,用内置的诊断收集脚本:bashsudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh它会把以下内容统一收集到 cube-diag-<时间戳>/ 目录下:/data/log/CubeMaster|Cubelet|CubeAPI|CubeShim|CubeVmm/ 的 tail/data/log/cube-proxy/ 下的 access/error 日志dmesg / 进程列表 / 端口 / 挂载 / cgroup / cpuinfo 等环境快照主要配置文件(敏感信息已脱敏)打包后整体上传:bashtar czf cube-diag-.tar.gz cube-diag-/支持选择性收集,例如只取 cubelet + dmesg:bashsudo /usr/local/services/cubetoolbox/scripts/cube-diag/collect-logs.sh \ --module cubelet --module dmesg --lines 500完整选项见 --help。常用运维动作速查 ​我想干什么命令列出当前角色全部 cube 服务systemctl --no-legend list-units 'cube-sandbox-*'查看某个服务状态systemctl status cube-sandbox-.service查看某个 target 的依赖图systemctl list-dependencies cube-sandbox-control.target启动 / 停止 / 重启单个服务systemctl {start|stop|restart} cube-sandbox-.service启动 / 停止 / 重启整组systemctl {start|stop|restart} cube-sandbox-{control,compute}.target看启动失败原因journalctl -u cube-sandbox-.service -n 200 --no-pager实时跟踪启动期日志journalctl -u cube-sandbox-.service -f重置 failed 计数systemctl reset-failed cube-sandbox-.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 是否 activebashsudo systemctl status cube-sandbox-control.target跑一轮健康检查bashsudo /root/cube-sandbox-one-click-*/smoke.shCubeAPI 是否收到请求bashsudo tail -F /data/log/CubeAPI/cube-api-$(date +%F).logCubeMaster 调度链路bashsudo tail -F /data/log/CubeMaster/cubemaster-req.log节点(Cubelet)是否在线、是否收到调度bashcurl http://127.0.0.1:3010/internal/v1/nodes sudo tail -F /data/log/Cubelet/Cubelet-req.logVMM 启动是否报错bashsudo tail -200 /data/log/CubeVmm/vmm.log服务一直 activating (start-post) 起不来 ​bashsudo systemctl status cube-sandbox-.service sudo journalctl -u cube-sandbox-.service -n 200 --no-pager常见根因:容器镜像构建依赖外网(如 cube-proxy 的 apk update)暂时不可达 → 检查网络,或参阅部署相关排障ExecStartPost 健康端口超时(端口被占用 / 上游服务还没起来)对 cube-sandbox-cube-proxy.service,CUBE_PROXY_HTTP_PORT 与 CUBE_PROXY_GRPC_PORT 是 systemd 启动后 TCP 检查所关注的 nginx 监听端口。CUBE_PROXY_HOST_PORT 已废弃且会被忽略;如果需要改 HTTP 检查端口,请改 CUBE_PROXY_HTTP_PORT。/data/log 或 /data/cubelet 目录不存在 / 权限不对 / XFS 挂载错位Dashboard / API 无法访问 ​bash# 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 unit 安装位置/etc/systemd/system/cube-sandbox-*systemd helper 脚本/usr/local/services/cubetoolbox/scripts/systemd/*.sh业务日志(核心入口)/data/log//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✅✅相关文档 ​快速开始 — 安装入口多机集群部署 — 计算节点的服务子集CubeMaster 调度器配置参考 — 节点选择、quota、label、评分和 template redo部署相关排障 — XFS / 网段冲突等环境问题模板相关排障 — 模板创建相关问题

评论 (0)