语法
选项
lager update 每次调用只作用于一台 Box。若要更新多台,请在您的 shell 中循环 ——
--all 标志及其多 Box 循环已在 v0.18.2 中移除。预构建的 Box 镜像
发布标签会向 GitHub Container Registry 发布一个 Box 容器镜像。启用拉取时,客户端会做三件事:- 把标签解析为不可变的摘要。
- 按 Box 自己的架构拉取该摘要对应的镜像。
- 验证该镜像报告的版本正是您所请求的版本。
对
lager update 来说,拉取默认是关闭的。它改变了整个机群中最关键的命令获取所运行代码的方式,因此先在 Lager 自己的 Box 上磨合。传入 --pull 可以让某一次运行启用它。若要在整个 shell 中启用,请把 LAGER_BOX_IMAGE_PULL 设为 1、true 或 yes(大小写不限)。其他任何值都保持拉取关闭。这与 lager install 不同,后者对发布标签默认就使用预构建镜像。--no-pull 在两者上的作用相同。它是让机群绕开有问题的已发布镜像的开关,并且不需要发布新的 CLI 版本。--force从不拉取,它总是在 Box 上构建镜像。- 同时传入
--pull和--no-pull属于用法错误。 - 拉取在更新停止容器之前进行,因此下载期间 Box 仍在提供服务。不匹配时,Box 保持在原来的版本。
- 更新会把镜像来源记录到
/etc/lager/image-source:拉取的镜像记为ghcr:<digest>,本地构建记为local:<build-hash>。
版本固定
自 lager 0.22.0 起,传给--version 的 semver 值会解析为发布标签
vX.Y.Z。开头的 v 可写可不写(例如 0.26.0 或 v0.26.0),常见的预发布后缀(-rc1、-beta2、-alpha、-preview)同样接受。发布标签是固定版本的唯一权威来源。
--version main 每次运行都会重新对
origin/main 解析,因此几分钟后它可能指向另一个提交。提交没有预构建镜像,因为只有发布标签才会发布镜像,所以 SHA 会像分支一样在 Box 上构建。该提交还必须能从远端的某个分支或标签到达。
其他任何值(main、staging 或某个功能分支名)都像以前一样解析为
origin/<name>。
默认版本
不指定--version 时,更新以与 CLI 相匹配的发布标签为目标。例如,lager 0.52.0 会把 Box 更新到 v0.52.0。若要把 Box 移到更新的发布版本,请先升级 CLI,再运行 lager update。若要获取最新的开发代码,请传入 --version main。早期版本的 CLI 以 main 作为默认值。
默认更新从不回滚 Box。如果 Box 领先于 CLI 的发布标签,更新不做任何改动并以 0 退出,使用 --check 时也是如此。Box 可能处于更新的发布版本,也可能处于某个分支。消息会给出把 Box 移到 CLI 发布版本的命令。对于处于分支上的 Box,消息还会给出沿该分支更新 Box 的命令。
用法
基本更新
更新多台 Box
没有内置的多 Box 更新。请在您的 shell 中循环;如果想先看看哪些 Box 确实落后,可以先用--check:
v0.18.2 之前存在一个
--all 标志,它和它驱动的多 Box 循环一起被移除了。普通的 shell 循环在某台失败时会继续处理下一台,因此一台不可达的 Box 不会中断整轮更新。检查模式
--check 不会改动 Box 上的任何内容。它打印一份预览:
Current: 来自 /etc/lager/version。预览不显示已部署的 ref,查看 ref 请用 lager hello。
退出码
1 并不总是表示 Box 落后。检查本身失败时同样退出 1,例如 SSH 超时、探测 Box 状态失败,以及 Box 目录不是 git 检出。
git fetch 失败也会给出 1,其中包括 Box 无法拉取的提交 SHA。被其他持有者锁定的 Box 同样给出 1。把 1 当作”需要更新”之前,请先读输出。
更新过程
update 命令执行以下步骤(在进度条中显示):- SSH 检查 - 确认对 Lager Box 的基于密钥的 SSH 访问
- 检查并拉取 - 读取 Box 状态,然后拉取目标版本
- 应用更新 - 在 Box 上检出目标版本
- 主机配置 - 检查 udev 规则、modprobe 黑名单、sudoers 文件、主机软件包(BlueZ)和主机 CLI。缺少的主机软件包会在不提示输入密码的情况下安装。如果无法安装,更新会打印需要在 Box 上运行的命令,然后继续
- 拉取镜像 - 使用
--pull并且目标是发布标签时,拉取预构建镜像 - 停止容器并构建 - 停止正在运行的容器;如果本次更新没有拉取镜像,则在 Box 上构建镜像
- 目录 - 建立容器要挂载的目录,例如自定义二进制程序目录
- 更新版本 - 把版本记录到
/etc/lager/version,把已部署的 ref 记录到/etc/lager/ref - 启动容器 - 启动新容器
- 状态验证 - 等待各服务,然后确认它们可以响应
- J-Link - 如果 Box 上没有 J-Link 则安装它(这一步失败不是致命错误)
- 主机 CLI - 由于代码已变化,在 Box 宿主机的
~/.lager_venv中重新安装lagerCLI
Host CLI on the box host was NOT updated: ...。Box 宿主机需要 python3 3.10
或更高版本,否则更新会跳过这一步并给出警告。即使 Box 已是最新,只要它的副本缺失、损坏或过旧,也仍会安装主机 CLI。
lager update 不会改动主机防火墙。
版本跟踪
Lager Box 把它当前的版本记录在/etc/lager/version 中。
lager boxes 列表会查询每台已配置的 Box,并在 version 列显示它的当前版本:
/etc/lager/ref 中,格式为
<ref>@<short-sha>(例如 main@85c1b64)。如果更新无法读取该提交,文件中只保存裸的 <ref>。lager update 在每次成功运行时都会写这个文件,包括 Box 本来就是最新的那种运行。lager install 也会写它。
仅凭版本号无法区分分支部署和发布部署,因此有两条命令会显示 ref:
- 对于 Box 版本的发布标签,
lager hello显示(release);对于其他任何 ref,显示完整的 ref。不是发布标签的 ref 会附加-- not a release build。 - 对不是发布标签的 ref,
lager boxes显示<version> (<ref-name>)。
SSH 密钥认证
update 命令在改动任何内容之前,会先检查是否有可用的 SSH 密钥:- 有可用密钥时:更新过程不会出现密码提示。
- 没有可用密钥时:更新会主动提出配置
lager_box密钥。该配置会要求输入一次 Box 密码。 - 密钥配置失败时:更新会询问是否改用密码认证继续。
- 使用
--yes时:更新会同时接受这两个提示。 - 使用
--check时:更新不会配置密钥。没有可用密钥时它以2退出。
防火墙
lager update 不会安装、更改或运行主机防火墙。防火墙由 lager install 配置。若要重新运行防火墙脚本,请在 Box 上执行:
lagernet 网络上,这些规则不会过滤容器发布的端口。请参阅
lager install 以及
SECURITY.md
的 Security Model 部分。
示例
故障排除
更新在 git pull 处失败
容器构建失败
防火墙问题
Box 前面的网关
有些 Box 在 lager 前面有一个网关:它是lagernet Docker 网络上的另一个容器,发布 lager 的主机端口,并把请求转发给 lager 容器。控制平面可以运行这样的网关。
- 当这样的容器已经发布了端口 5000、8080、8765 或 9000 时,lager 容器以
--no-publish模式启动,只能通过网关访问。之后的启动会保持这个模式。 - 在停止任何容器之前,该命令会检查是否有其他容器占用了 lager 要发布的主机端口。如果有,命令会停止并指出该端口和容器,Box 保留当前的 lager 容器。
- 如果
lagernet上仍有容器在运行,但/etc/lager/control_plane.json已不存在,命令会显示警告。在您从控制平面重新关联该 Box 之前,该网关会拒绝所有连接。Lager 无法恢复该文件。
说明
- 使用
--verbose时会关闭进度条 - 容器构建使用 BuildKit 层缓存。
--force会先删除缓存镜像以及 cargo/npm 卷 - 不指定时版本默认为本 CLI 的发布标签
- 更新会在容器重启之后自动验证其健康状态
--check报告将会改变什么而不改动 Box,因此它是判断某台 Box 是否落后的安全方式--force即使在 Box 报告已是最新时也会更新,并清除缓存镜像和 cargo/npm 卷(在代码有较大变化之后很有用)

