runcmd 与 Cloud-Init 中的包顺序
Source: Dev.to
问题
如何让在 runcmd 中指定的命令 在 通过 Cloud‑Init 的 packages 模块安装相关软件包之前执行?哪个模块会先运行?
示例
#cloud-config
package_update: true
package_upgrade: true
runcmd:
- systemctl enable --now qemu-guest-agent.service
packages:
- qemu-guest-agent
这种模式在为虚拟机(例如使用 Terraform 的 libvirt 提供程序在 QEMU/KVM 上)进行配置时很常见。runcmd 条目尝试启用并启动 qemu-guest-agent.service,即使 qemu-guest-agent 软件包尚未安装。guest agent 通常需要在较早阶段就可用,以便像 Ansible 动态清单这样的工具能够查询主机信息。
为什么它会工作
混淆来源于 Cloud‑Init 模块阶段的文档描述方式:
- Config 阶段 – 列出
runcmd的位置。 - Final 阶段 – 安装
packages,并运行scripts_user模块。
虽然 runcmd 出现在 Config 阶段,但 runcmd 下的命令 并不会立即执行。Cloud‑Init 将 runcmd 列表视为一组脚本,这些脚本会在稍后由 Final 阶段的 scripts_user 模块调度执行。
因此,执行顺序是:
- 软件包安装(
packages模块) – Final 阶段。 - 用户脚本(
scripts_user模块) – Final 阶段,运行来自runcmd的命令。
当 scripts_user 执行 systemctl enable --now qemu-guest-agent.service 时,qemu-guest-agent 软件包已经安装,服务文件已存在,命令即可成功运行。