Kibotos

node 与 VMM 进程

本页解释 node、VMM、数据面进程与出口进程在 systemd 中的进程模型,以及替换 node 程序前的两个检查命令。 升级与卸载的完整步骤见重装与升级。

概述

  • 宿主机需要 systemd、cgroup v2 和 KVM。node 以 root 运行。
  • 每个 Instance 的 VMM 由 node 启动为一个独立的 systemd transient service。Firecracker 与 KiboVM 两个后端都这样运行。
  • exec、terminal、文件传输和端口转发的连接由数据面进程持有,它也是 node 启动的独立服务。停止、重启或升级 node 时,VMM 与数据面进程都继续运行。

进程模型

node 服务

  • node 的服务单元使用 Restart=on-failure、RestartSec=5s、KillMode=control-group 和 SendSIGKILL=yes。systemd 停止旧 node 的 cgroup、清理它的辅助进程之后,新 node 才能启动。
  • node 的服务单元设置 OOMScoreAdjust=-900:宿主内存耗尽时,内核先杀 VMM,不杀 node。node 自己启动的短期工具(mkfs、guestfish 等)继承这个值。不使用打包的服务单元时,自己写的单元文件也要加上它。
  • node 启动时先检查自己的 MainPID、cgroup 和有没有残留进程,然后获取状态目录的独占锁。
  • 文件系统工具 guestfish 与 virt-ls 固定使用 LIBGUESTFS_BACKEND=direct,它们的辅助 VM 留在 node 服务的 cgroup 内,不经外部 libvirt 启动。

VMM 服务

  • VMM 的服务单元使用 Type=exec、Restart=no、KillMode=control-group、OOMPolicy=kill,位于 kibotos-vmm.slice(父 slice 为 kibotos.slice)。OOMPolicy=kill 让内核在杀掉单元里任一进程时一并杀掉整个单元,与 VMM 共享 guest 内存的辅助进程不会拖住内存。升级前已经在运行的 VMM 保持原设置,下次启动时生效。
  • VMM 服务与 node 服务之间没有停止依赖:停止或重启 node 不影响 VMM。宿主机关机时 VMM 由 systemd 的默认关机顺序终止。
  • Firecracker 的服务以 root 启动 jailer,jailer 再切换到 VMM 账户。KiboVM 的服务直接以非 root 的 VMM 账户运行,并带 kvm 附加组。
  • KiboVM 的服务设置 LimitMEMLOCK=infinity。较新的内核(如 7.0)把 io_uring 的 ring 内存计入所属用户的锁定内存,而所有 VMM 都以同一个 VMM 账户运行;沿用 systemd 默认的 8 MiB 时,整台宿主只能启动二十几台 VM,之后的 VM 启动失败,kibovm.log 报 Out of memory (os error 12)。这项限制由 node 在服务单元上设置,宿主的 limits.conf 与 systemd 的 DefaultLimitMEMLOCK 不需要修改。Firecracker 不使用 io_uring,保持默认值。
  • 服务使用 node 预先创建的网络命名空间,并设置 PrivateMounts=no。文件与设备隔离由各后端自己的沙箱完成;jailer 不再创建或迁入其他 cgroup。

数据面进程

数据面进程(data-plane process)监听 node 配置的数据面地址,持有全部数据面连接。它运行同一个 kibotos-node 可执行文件,由 node 启动,每次启动得到一个递增的代号。

  • 服务单元名是 kibotos-dataplane-<作用域>-<代号>.service,位于 kibotos-dataplane.slice,使用 Restart=no、KillMode=control-group 与 OOMScoreAdjust=-900。它与 node 服务之间没有停止依赖。作用域由 node 的 runtime 目录决定,同一台宿主上的多个 node 互不影响。

  • 列出全部数据面进程:

    systemctl list-units 'kibotos-dataplane-*'
  • 数据面进程以 root 运行:两个后端的 guest socket 只对 root 与 VMM 账户开放。

  • 它的本地 socket 在 socket 目录(默认 /run/kibotos/node)的 dataplane/ 下,不读写 node 的状态目录。target、验证公钥与 TLS 证书都由 node 下发。

  • node 先把新的 target 与验证公钥交给数据面进程,再回复 ctrl,所以 ctrl 签发的会话凭证一拿到就能用。数据面进程 5 秒内没有确认时,node 照常回复,并记一条警告 data-plane generation did not take the node's state before the reply。在 node 下一次重发之前(至多 15 秒),用到新 target 或新公钥的请求会被拒绝。

  • node 的 /metrics 合计各个数据面进程的指标。一个数据面进程退出后,它的计数仍计入 counter,counter 不会变小。

node 启动时按正在运行的数据面进程决定怎么做:

正在运行的数据面进程node 的做法已有连接
与 node 是同一构建,监听地址与 TLS 设置相同直接接管不受影响
同一发布线上的其他构建,或 TLS 设置变了启动新的数据面进程,新进程接过监听 socket;旧进程不再接受新连接,等已有连接结束后退出不受影响。交接期间新连接也不被拒绝
同一发布线上,但监听地址变了新进程绑定新地址;旧进程在原地址上不再接受新连接,等已有连接结束后退出不受影响
不在同一发布线上(跨 MINOR,或涉及 -alpha.N、-beta.N 与未发布构建)结束旧进程,再启动新进程,由新进程绑定监听地址断开,可以重新建立
没有启动新进程—

注意:

  • 等待已有连接结束的旧进程最多保留一个。再换一次时,node 结束更早的那一个,它上面剩下的连接断开。
  • node 停着时,数据面进程按 node 最后下发的 target 继续服务,也接受新连接。这期间 ctrl 的停止、删除与撤销送不到 node,已签发的会话凭证在有效期内仍然可用,node 恢复后这些操作才生效。要立刻切断访问,停止全部数据面进程。
  • 数据面 TLS 证书由 node 续期。node 停机期间证书过期时,新连接握手失败,已建立的连接不受影响。
  • 数据面进程意外退出时,它持有的连接断开,node 在几秒内启动新的数据面进程。node 停着时没有人启动新的,等 node 恢复。
  • 停止数据面进程时,它先给已有连接 10 秒自行结束,再关闭剩下的连接,并在日志里记下关闭了多少条。

出口进程

出口进程(egress process)转发 guest 经调用方 SOCKS5 出口发出的 TCP 连接,并替引用了调用方 Resolver 的 Workspace 把 DNS 查询转给那个上游。它与数据面进程一样运行同一个 kibotos-node 可执行文件,由 node 启动,按代号换代。

  • 服务单元名是 kibotos-egress-<作用域>-<代号>.service,位于 kibotos-egress.slice,使用 Restart=no 与 KillMode=control-group,与 node 服务之间没有停止依赖。

  • 只在这台 node 上有 Workspace 的网络策略引用 Egress 或 Resolver 时运行。不引用 Resolver 的 Workspace 的 DNS 查询由内核转给部署 resolver,不经过它。策略不再引用 Egress 后,它继续持有仍在排空的连接,最后一条结束或到期后 node 结束它。

  • 它以系统用户 kibotos-egress 运行,不带任何 capability,也不能提权:文件系统只读,只能写自己的 socket 目录,看不到 node 的状态目录。需要特权的 socket 由 node 创建后交给它,出口凭证也由 node 经本地 socket 下发,只留在内存里。

  • socket 目录是 socket 目录旁边加 -egress 后缀的目录,默认 /run/kibotos/node-egress,属主 kibotos-egress、模式 0700。代号计数在 <storage.root>/state/egress-generation。

  • 出口凭证由 node 用自己的身份向 ctrl 按 Egress revision 取回,每个 revision 一个文件,放在 <storage.root>/state/egress-credentials/,目录 0700、文件 0600,只有 root 能读。Workspace 切到新 revision 或离开这台 node 后,不再被引用的文件随即删除。node 重启时只用这些文件恢复出口,不访问 ctrl。

  • 列出全部出口进程:

    systemctl list-units 'kibotos-egress-*'
  • 直出的 Resolver 上游由出口进程从宿主的网络命名空间以 kibotos-egress 用户连接,按宿主路由离开。部署方在宿主上限制 node 自身出站时,这些连接一并受限。上游写成主机名时,出口进程用 node 配置的 resolver 列表依次解析,不使用宿主的 /etc/resolv.conf。

  • node 重启时接管正在运行的出口进程,已有连接不受影响。node 换成同一发布线上的其他构建时,启动新的出口进程接受新连接与新查询;旧进程不再接受新连接、不再读取新查询、丢弃凭证,已经收到的查询在 4 秒内答完,已有连接按 node 下发的截止时间继续或关闭,全部结束后退出。跨发布线时旧进程被结束,连接断开。

  • 同时最多有两代出口进程。上一次换构建留下的旧进程还在排空时再换一次构建,最老的那一代被结束,它持有的连接随即断开,日志 egress generation ended 的 reason 是 a newer generation is about to drain。要连续换构建又不断开连接,先用上面的命令确认只剩一个出口进程。

  • guest 的连接由透明 listener 接受。listener 是 node 创建的,属于 node 服务单元的 cgroup,这个归属在 listener 存续期间不变。所以给 kibotos-node.service 加的 systemd IP 访问限制(IPAddressDeny=、IPAddressAllow=)也作用于经出口转发的连接,会把它们一起挡住。需要这类限制时,放行 ipv4_pool 与 ipv6_pool;不要用它来切断 node 与 ctrl 的连接。

  • 出口进程意外退出时,经出口的连接断开,node 在几秒内启动新的出口进程。其间被引到出口的新连接失败,不改为直出;引用 Resolver 的 Workspace 的查询得不到应答,其余 Workspace 的解析不受影响。

启动记录与接管

  • 启动 VMM 之前,node 在 Instance 目录中写入 systemd.json,记录本次启动的唯一标识、服务单元名和预期命令。启动之后补上 InvocationID、MainPID、进程启动时间、可执行文件身份、cgroup 和网络命名空间。
  • 服务启动成功后,还要通过后端与 guest 的就绪检查,Instance 才算可用。node 记下这时认领的 guest:它的启动标识与声明的能力。
  • 启动记录还固定了 VMM 使用的 runtime 安装(runtime installation)的身份。runtime 安装位于 <storage.root>/installations/sha256-<身份>/,目录里的 installation.json 描述它自己。
  • node 重启时把这些记录与实际运行的服务逐一比对,接管匹配的 Instance。启动响应丢失时查询原来的启动记录;记录与实际不符,或存在没有记录的服务时,node 停止启动。
  • 接管运行中的 Instance 不等 guest 回应。存储、网络与 VMM 接回后 Instance 就照常运行,数据面按记下的 guest 继续服务:
    • node 在后台把启动时的配置与本次的 DNS 再交给 guest。guest 暂时不回应就按退避一直重试,期间 Workspace 仍是 AVAILABLE,guest 按不再回应报告。
    • node 离线期间重启过的 guest,按启动时的配置重新配置。
    • guest 回应但拒绝,例如协议版本不在本版本支持的范围内,Instance 标为 FAILED,VMM 继续运行。
  • 网络接回时,node 按记录的网络策略用当前版本重新生成该 Instance 的防火墙规则,在一次 nftables 事务中整体替换,已建立的连接不断开。上一版 node 启动的 Instance 的规则可能与当前版本不同,接管时一并改写,日志 slot table rewritten from the recorded network policy 记下 Instance、命名空间与差异。
  • 下列情况 node 不改写规则,而是隔离该 Instance 的网络并把它标为 FAILED,VMM 继续运行:
    • Instance 的网络命名空间里没有 node 的规则表,或有不属于 node 的 nftables 表;
    • 规则表里的地址集合与记录或当前配置不符,resolver 地址除外。例如改了 management_cidrs,或上联地址变了;
    • 有手工添加的规则或链;
    • 当前版本无法执行记录的策略,例如 node 不再提供公网出口。
  • 重启时还没创建完的 Instance 例外:它的 guest 从没通过就绪检查,接管时仍等它就绪,超时即创建失败。
  • 新启动的 Instance 总是使用当前版本自带的 runtime 安装。上一版 node 启动的 Instance 可能记录着更早的安装,node 照常接管它,接管时使用它记录的那个安装。条件是:
    • 该安装目录完整,文件摘要与 installation.json 一致;
    • 它的 runtime 版本在当前 node 仍能驱动的范围内。范围是当前版本固定的 runtime,加上同一发布线上更早版本和上一个 MINOR 固定的 runtime。
  • 条件不满足时 node 无法接管该 Instance:Instance 被标记为 FAILED,它的 VMM 继续运行。处理方法见排查。
  • Workspace 停止后再次启动,就换到当前版本的 runtime。node 每次启动时删除没有任何 Instance 使用的旧安装目录;接管失败的 Instance 仍然记录着的安装目录会保留。
  • 删除 Instance 时先停止对应的服务,确认整个 cgroup 已空,再回收挂载、网络和文件。
  • 删除一个未被接管、但服务仍在运行的 Instance 时,node 先核对归属:启动记录、服务绑定、node 自己的 Instance 记录和实际服务必须指向同一个进程。全部一致时 node 停止该服务再回收;任何一项不一致,删除失败,服务保持运行。
  • 停止 node 不等于删除 Instance,也不会设置或取消 drain。

排查启动失败时,保留原有记录,查看 systemctl show <unit>、journalctl -u <unit> 和保留的控制台与 VMM 日志。不要删除绑定记录、修改 PID 或按名称批量结束进程,这些操作会让 node 失去判断进程归属的依据。

已结束 Instance 的记录

Instance 结束后,node 在 <storage.root>/runtime/registry/ 留着它的记录,直到 ctrl 确认不再需要。

  • ctrl 每分钟检查一次每台 node 上的记录。Instance 的 Allocation 已释放、所属 Workspace 没有处理中的命令、Workspace 也不再以它为当前 Instance 时,ctrl 先存下 node 观测到的清理结论,再让 node 删除记录,每台 node 每次最多 100 条。
  • 记录删除之后,kibo workspace cleanup-status 读 ctrl 存下的结论。运行时几项的状态不变,观测时间是 node 观测到清理完成的那一刻。
  • Volume、可写层与 Template 准备命令记在同一目录的 volume-commands.json,每条保留 24 小时。

不要手工删除记录:清理结论存下之前删掉,这个 Workspace 的清理状态里运行时几项会显示为未知。

中断的写入留下的临时文件

node 先把记录、块文件与 Transfer 归档写到临时文件,写完再改名。中途退出时临时文件留在原处,任何版本都不读取它们。池里的临时文件名以写入它的 node 的 ID 开头,v0.1.x 写的不带:

位置例子
node 本地目录registry/.record-2826134621.tmp
池里volumes/data/.node-a.import-1438876543.tmp、volumes/transfer-staging/.node-a.download-import-3170412187.tar,以及从另一个池复制对象时的 volumes/data/.node-a.move-vol-06gdxke0wxw4xezwfa185wp24w-2004318071.tmp
池里,v0.1.x 写的volumes/data/.import-1438876543.tmp

node 启动时删除这些文件:

位置删除哪些
node 本地目录全部
独立池全部。启动时不可用的池,等它变为可用时删除
共享池只删以本 node 的 ID 开头的。别的 node 的可能正在写

共享池里另外两种要手工删除:

  • 不带 node ID 的:先停止声明这个池的所有 node。
  • 以已永久移除的 node 的 ID 开头的:那台 node 不再运行之后。

控制台与 VMM 日志

Instance 结束时,node 在删除运行时目录之前,把 guest 控制台与 VMM 日志的末尾复制到 <storage.root>/machine-logs/<instance_id>/,node 日志只写一条 instance machine exited。保留的范围、配额与读取方法见日志。

替换程序前的检查:check-maintenance

替换 node 程序不需要停止 Workspace:VMM 独立运行,新的 node 启动后按记录接管它们。目标版本换了 VM runtime 时也一样,按旧 runtime 启动的 Instance 继续使用旧的安装。只有目标版本驱动不了的 Instance 需要先停止,由目标版本的 check-upgrade 逐个列出。

停止 node 服务后,用当前已安装的 node 执行维护检查:

sudo kibotos-node check-maintenance --config /etc/kibotos/node/config.toml --operation upgrade
sudo kibotos-node check-maintenance --config /etc/kibotos/node/config.toml --operation remove
操作允许的状态
upgrade允许 Instance 继续运行,前提是每个 Instance 的记录都能与实际服务对上:服务单元、InvocationID、PID、启动时间、可执行文件的路径与 dev:ino、cgroup、网络命名空间全部一致,且没有进行到一半的网络切换、目标轮换或停机。允许保留已解绑的 Volume 和保留的可写层,包括扩容还没有完成的 Volume
remove要求没有运行中的 Instance,也没有已解绑的 Volume 和保留的可写层

两种操作都不检查、也不结束数据面进程。卸载 node 包时,包脚本在 --operation remove 的检查通过之后结束全部数据面进程。

两种操作对宿主机残留的要求相同:Instance 目录、后端状态目录、沙箱目录、网络记录和挂载中的每一项都必须属于某个已被接管的 Instance。找不到归属的残留会导致检查失败,因为新程序既不能理解它们,也没有人负责清理它们。

注意:

  • 配置、PKI、已安装的 runtime 和可重建的缓存可以保留。Firecracker 的共享沙箱根目录只有在它是 root 所有、权限 0700 的 tmpfs,且其下只有已接管 Instance 的目录时,才算可保留的缓存。
  • 中断的写入留下的临时文件不算残留,检查不因此失败,见中断的写入留下的临时文件。
  • 检查只读取配置、独占锁、持久记录和进程信息,不修复状态、不递增启动序号、不创建目录。
  • 配置缺失、记录损坏、辅助进程仍在运行或归属不明,都返回非零退出码。
  • 存储池里持有者记录写着别的 node 的对象不让检查失败,不论池是否共用。换过宿主的池因此可以正常升级,见池换宿主。
  • 这个检查只回答「当前资源是否静止且有归属」。新版本能否读取这些记录,由新版本自己的 check-upgrade 回答。

替换前用目标程序检查

check-maintenance 由当前版本执行,它不知道新版本能否读取磁盘上的记录。按准备目标版本的程序把新版本解到安装目录之外,所有服务停止后,用新版本的二进制执行:

sudo /tmp/kibotos-next/usr/bin/kibotos-node check-upgrade --config /etc/kibotos/node/config.toml --runtime-dir /tmp/kibotos-next/usr/lib/kibotos/node

它使用与 upgrade 相同的静止判据,并额外检查四件事:

  • node 身份、注册记录和启动记录的格式版本都在新版本能读取的范围内。
  • 目标 runtime 目录中有新版本要求的 VM runtime 可执行文件。
  • 每个仍在运行的 Instance 使用的 runtime 安装,新版本都能保留并驱动:要么就是新版本将使用的安装,要么该安装目录完整,且 runtime 版本在新版本能驱动的范围内。
  • 每个仍在运行的 guest 通过自己的 VMM 响应 GuestInfo,其协议版本在新版本接受的范围内。

报告逐项列出阻塞对象与原因;有阻塞项时返回非零退出码。

注意:

  • 运行中的 guest 缺少新版本新增的能力不算阻塞。这样的 Instance 照常被接管,只是用到该能力的操作在它重启前会失败;报告会列出这些能力。
  • guest 协议版本超出范围算阻塞。对应的 Workspace 必须先正常停止。
  • 运行中的 Instance 使用旧的 runtime 安装本身不算阻塞。报告写明 Instance、它使用的安装和 runtime 版本,以及它下次启动时换到的安装。
  • 旧的安装目录损坏或缺失,或者它的 runtime 版本超出新版本能驱动的范围,才算阻塞。对应的 Workspace 必须先正常停止;再次启动时使用新的 runtime。
  • 检查是只读的:不创建目录、不递增启动序号、不迁移数据、不修改 guest。
  • 检查结果只描述当次停机时刻的状态。任何写状态的进程重新启动过,就需要重新停机、重新检查。

停机之前先用 --preview 问一遍

上面那条命令要求 node 已经停止:它和 check-maintenance 一样要取 node 的独占锁,服务还在跑时只会报「runtime 已被占用」。加 --preview 时,它在仍在运行的 node 上判定与宿主是否静止无关的几项:本地记录的格式版本、目标 runtime 目录、运行中 Instance 使用的 runtime 安装,以及运行中 guest 的协议版本与能力。判据与停机后逐条相同,所以预检就能回答需要先正常停止哪些 Workspace。何时、怎样执行见停机前预检的 node 一节。

报告分三类:

前缀含义
ok:已取得答案且满足要求
blocked:已取得答案但不满足要求。退出码非零,对应的 Workspace 要在窗口之前处理
pending:因为 node 还在工作而拿不到答案:记录正在改写、Instance 正在启动或停止、guest 未应答。不影响退出码,停机后重新判定

预检不取独占锁、不写任何文件,可以随时重复执行。它不判定静止与归属——辅助进程、无主残留、宿主挂载、staging 目录、Volume 与可写层的归属都不在结论里,报告末尾会重复这一点。它不替代停机后的完整检查:替换之前仍然要在停止服务后执行不带 --preview 的同一条命令。

排查

现象原因处理
升级后 Instance 变为 FAILED,错误为 recover instance process: ... compatible runtime installation unavailable,VMM 服务仍在运行Instance 按旧的 runtime 安装启动,而新 node 保留不了这个安装:目录损坏或缺失,或 runtime 版本超出新 node 能驱动的范围。node 启动日志里的 earlier runtime installation cannot be retained 写明了具体原因用 kibo workspace stop --force <workspace> 回收:node 核对归属一致后先停止旧的 VMM 服务,再释放资源。Workspace 进入 STOPPED,Volume 与可写层保留,之后可以再次 start。升级前执行 check-upgrade 可以提前发现这种情况
回收上述 Instance 失败,错误包含 stop instance process this node did not take over启动记录、服务绑定、node 记录与实际服务至少有一项对不上,node 无法确认该服务属于这个 Instance保留 Instance 目录中的记录,用 systemctl show 与 journalctl -u 查看错误里提到的服务。确认它就是该 Instance 的 VMM 后,只停止这一个单元,再用同一个 --command-id 重试原来的命令
node 重启后一批 Instance 变为 FAILED,失败阶段为 PREPARING_RETAINED_LAYER 或 ATTACHING_VOLUME,错误包含 storage pool is unavailable,VMM 服务仍在运行接管时存储池不可用。node 启动时先等这些 Instance 所在的池完成首次打开,最多等 5 分钟;池在这段时间里没有打开,或打开后报告不可用,接管就失败。启动日志里对应有 storage pool not opened for takeover,或这个池的 storage pool availability changed 变为 unavailable。每个 Instance 只接管一次,池之后恢复也不会重试先按 storage pool availability changed 的 reason 修好存储。再从 instance takeover failed 记录取出 instance_id,用 kibo workspace list --instance <instance_id> 找到 Workspace,执行 kibo workspace stop --force <workspace> 后再 start。存储修好后 ctrl 最多 1 分钟才看到池恢复,在此之前 start 报 no admitted node is ready,稍后重试即可。guest 内的进程与内存状态不保留,Volume 与可写层保留
node 重启后日志反复出现 instance guest sync pending,Workspace 仍是 AVAILABLE,guest 显示为不再回应node 接管了 Instance,但 guest 不回应,还没能按本次重启重新配置它。重启前就已卡住的 guest 常见这种情况,例如内存耗尽或 CPU 被占满不用处理:guest 恢复回应后 node 自动完成,同名记录带 recovered=true。一直不恢复时用 kibo workspace stop --force 收回,再启动
Workspace 停止失败并停在 FAILED,错误以 prepare guest stop: 开头,例如 deadline_exceeded、retained filesystem sync failed 或 retained filesystem freeze failed,VMM 服务仍在运行guest 没有在期限内结束受管进程,或者同步、冻结可写层与 Volume 失败,node 不能确认数据已经落盘,所以不停止 VM。同步或冻结失败后,guest 让这些文件系统保持冻结,不再接受写入用 kibo workspace stop --force <workspace> 停止它:node 请 guest 做一次短时间同步后停止这个 VMM 并释放资源,Workspace 进入 STOPPED,Volume 与可写层保留。结果标为未经落盘确认。node 上已经没有这条 Instance 时(例如 node 重启后没有接管它),ctrl 会自行释放资源,Workspace 仍是 FAILED,可以直接 start
VMM 意外退出(被杀、崩溃等)后 Workspace 停在 FAILED,错误为 node reports the Instance as no longer running;start 被拒绝,提示状态不允许。宿主 OOM 杀掉的 VMM 不属于这种情况:它的 Workspace 由 ctrl 自行停止,直接 start 即可;只有 OOM 发生在 node 停机期间、systemd 已经清掉了那个 VMM 单元时,才会停在这里node 保留了这条已失败的 Instance,它仍占着 Volume、网络与资源预留,只有销毁才释放。旧 Instance 可能还占着存储时,ctrl 不启动新的执行用 kibo workspace stop --force <workspace>:ctrl 让 node 销毁这条 Instance、释放资源,Workspace 进入 STOPPED,Volume 与可写层保留,然后再 start。结果标为未经落盘确认
停止或删除后 Instance 长期停在 STOPPING 或 DESTROYING,node 日志反复出现 instance cleanup pendingVMM 进程卡在不可中断的等待里,systemd 的停止任务超时后 unit 已经结束而它的 cgroup 仍有进程。多数情况下它在等存储:块文件所在的挂载不响应不用管 node,它会一直重试;先修存储。进程消失后 node 自己完成释放并进入终态。kibo workspace cleanup-status <workspace> 显示释放从哪一刻起欠着、哪些部分仍被持有
check-maintenance 或卸载 node 包被 is active or requires cleanup 拒绝,而那条 Instance 停在 FAILED 且仍挂着 Volume旧版本把一次没做完的释放判成了失败,从此不再重试先用控制面删除对应的 Workspace,让旧 node 完成释放,再执行检查或卸载。换到本版本之后这类记录会自行收敛,不再需要这一步
node 停着时新的数据面连接 TLS 握手失败,已有连接正常node 停机期间数据面证书过期,数据面进程没有新证书可用启动 node。node 续期证书后下发给数据面进程,新连接恢复
systemctl list-units 'kibotos-dataplane-*' 里有两个数据面进程一个在服务,另一个在等已有连接结束不用处理。等待的那个在连接都结束后退出,再换一次时会被结束
升级 node 包时 dpkg 报 old kibotos-node package pre-removal script subprocess returned error exit status 1,随后 trying script from the new package instead,最后安装成功旧版本的包在升级时用旧二进制做资源检查。它拒绝后,dpkg 改调新包的脚本,新包升级时只要求服务已停止这是预期行为,不是检查被绕过。新版本能否接管,看替换前目标版本 check-upgrade 的结论

本页内容