从镜像启动一次,并不能让一台 Pi 成为可重建的设备。真正需要的是可以反复套用的一小组输入:一个持续维护的基础系统、一份声明式配置、应用自己的持久数据,以及只属于这块板卡的身份。漏掉最后一项,每次更换都会变成凭据的复制品。

下面的步骤是工作顺序,而不是工具推荐。任何能表达这些内容的配置系统都可以。

先列出四类输入

基础镜像及其软件包决定了操作系统、架构和更新来源;镜像构建工具只有在它所指定的工具仍为你的发行版维护时才有用。声明式配置是人要审查的部分:网络角色、服务设置,以及每项服务所需的生命周期操作。应用的持久数据是服务无法重新生成的一切,其位置与备份方式属于该应用,而不属于镜像。设备身份与密钥是第四项输入,也正是人们在克隆一张能用的存储卡时最容易忘记的东西。

在重建任何东西之前,先写下这四类清单。留有空白行的清单,等于一项你还没做的决定。

把密钥留在仓库之外,并说明它们存放在哪里

仓库适合存放经过审查的模板和非机密配置,不适合存放 VPN 私钥、可重复使用的管理员凭据和诊断归档。如果某个密钥必须存在于设备上,就记录它从哪来、谁能读取、如何轮换。只存在一张 SD 卡上的密钥是单点故障,而复制到每块板卡上的密钥则是没有归属的整批设备凭据。两者都不是恢复方案。

检验方法很简单:如果仓库明天泄露,攻击者能得到什么?模板和拓扑笔记尚可承受。能用的身份不行。

让自动化掌握它可以重复执行的部分

Ansible 的模型把受管节点清单与 play、任务、角色,以及任务报告变更时触发的 handler 分开。用这套结构 为每项服务指定唯一的配置负责人,而不是重放 shell 历史。优先选择可以安全执行两次的操作,并有意识地决定改动后的文件如何到达运行中的进程。一个确保服务已启动的任务,并不一定让它重新加载你刚改写的配置。

也要把管理阶段分开。初始连通性、日常配置和依赖 VPN 的管理是三个不同的窗口,如果重建重置了它下面的网络,第三个窗口可能把你自己的访问权限一并移除。请保留一条独立的进入路径。

有意识地恢复数据与身份

容器卷独立于容器生命周期而存在,而容器内的可写层不会,因此从镜像重建容器不会重建应用当时使用的状态,卷文档对此有说明。记录设备依赖的卷、绑定挂载和外部服务,并使用应用自身的备份与恢复流程。容器能无错误启动,并不能证明它的数据库与文件彼此一致。

至于身份,要决定你是在恢复同一台设备,还是在登记一台替代设备,因为这是两种不同的操作,清理方式也不同。

在别处启用身份之前,先处理好旧对端的访问权限,然后才在隔离环境或恢复环境中测试重建后的设备。检查所需数据、正确身份、有负责人的更新路径,以及预期的网络策略。

可启动的镜像只是四项输入之一,而且是最容易复制的一项。

相关文章