花拾录
← 返回知识库

检查 cloud-init 却看到默认模板:dump 命令根本不读你的自定义配置

云计算 / 运维导入2026/09/220 阅读0 评论

你按上一篇文章的方法,用自定义 snippet 接管了 cloud-init 配置,也确确实实写进了文件。可为了放心,你用平台的 dump 命令去看"虚拟机实际用的 cloud-init 内容",看到的却是那份默认模板——你自定义的东西一点不见。你开始怀疑:是不是我的自定义配置根本没生效?

现象

用平台提供的命令 dump 某个虚拟机的 cloud-init 内容:

qm cloudinit dump <VMID> user

输出的内容,是平台模板生成的那一份,看不到你 snippet 里的自定义设置(比如你写的用户、ssh_pwauth、package_upgrade 等)。你反复确认 snippet 路径配置正确、文件也读得到,但 dump 出来的就是不对。

根因

原因很直白,却也很容易让人钻牛角尖:那条 dump 命令不读取你的自定义配置,它照样只打印平台模板生成的版本。

也就是说,这个命令的语义是"给我看看按平台模板生成的 cloud-init 长什么样",而不是"给我看看这台虚拟机上真正生效的 cloud-init"。当你用 snippet 完整接管了配置之后,真正生效的是 snippet 那份,但命令展示的仍是模板那份——两者不是同一个东西。

于是你陷入一个"验证工具本身在骗你"的局面:你看的是最方便看的那份,而不是真正生效的那份。

解决

要看真实生效的内容,去看虚拟机实际挂载的那块 cloud-init 介质(平台会把它做成一个 ISO 挂给虚拟机)。方法:

方法一:在虚拟机内部看。

进了系统之后:

# cloud-init 生成并使用的配置文件
sudo cat /var/lib/cloud/instance/user-data.txt

# 用 cloud-init 自己的命令查它实际吃进去的 user-data
sudo cloud-init query userdata

这两条读到的是这台机器真正吃进去的 user-data。

方法二:把 cloud-init 的 ISO 挂到宿主机上看。

在宿主机上,把该虚拟机对应的 cloud-init ISO(通常是 vm-<VMID>-cloudinit.iso)挂载成环回设备,进去看里面的 user-data 和 meta-data:

mkdir -p /mnt/ci
mount -o loop /var/lib/vz/images/<VMID>/vm-<VMID>-cloudinit.iso /mnt/ci
ls -la /mnt/ci
cat /mnt/ci/user-data
umount /mnt/ci

(具体 ISO 路径随存储位置而变,用 qm config <VMID> 看 ide2/sata0 指向哪里。)

还要注意一个细节:如果你自定义的 snippet 只覆盖了"用户数据"部分,那么网络配置仍然由平台生成。也就是说,你看到的"网络配置"来自平台,别把它当成你的 snippet 生效与否的证据。判断时要分清楚"这一项是谁写的"。

延伸与预防

这条坑的价值,远超 cloud-init 本身,它讲的是一条通用的验证原则:

验证配置,要看"真正生效的那份",而不是"最方便看的那份"。

现实里,"能 dump 出点东西"的命令,往往只是"打印自己那份"的展示器,而不是"读取实际状态"的探针。二者的区别在排错时至关重要——用错了,你会在一个错误的事实基础上反复推理,越走越偏。

同类场景还有:

  • 容器里改了配置,却在宿主机上看旧文件(因为看到的是镜像里那份);
  • 应用读了某个配置文件,你却去看另一个路径下的同名文件;
  • nginx 有一堆 include 和站点配置,你只看 nginx.conf 主文件。

预防办法是记住一条判别法:问自己"这个命令读的是我的文件,还是它自己生成/缓存的那份?" 拿不准时,换一个"绕不开真相"的路径去验证——比如直接读文件系统里真正被加载的文件、用 strace 看程序到底打开了哪个文件、或者在系统内部用程序自己的查询命令打印运行时状态。多花这三十秒,能避免几个小时的南辕北辙。

评论(0)

  • 还没有评论,来抢沙发~

相关文章