6. cloud-init 故障排除
cloud-init 故障排除¶
在任何复杂的自动化系统中,事情最终都会出错。当 cloud-init
配置失败时,知道如何系统地诊断问题是一项基本技能。本章是您进行 cloud-init
取证的指南,涵盖虚拟机内和主机端故障排除技术。
1. 虚拟机内故障排除工具¶
当您可以访问正在运行的实例时,cloud-init
提供了几个命令和日志来向您展示发生了什么。
支柱 1:状态命令 (cloud-init status
)¶
这是您的第一站。它提供了 cloud-init
状态的高级摘要。
-
检查
cloud-init
的完成状态:cloud-init status
(成功运行将显示status: done
) -
等待
cloud-init
完成:cloud-init status --wait
(这在脚本中很有用,可以暂停执行直到cloud-init
完成)
支柱 2:主日志 (/var/log/cloud-init.log
)¶
此文件是真相的黄金来源:详细的、按时间顺序记录的每个阶段和模块的记录。当您需要确切地知道发生了什么时,请在此处查看。搜索此文件中的 ERROR
或 WARNING
通常会直接将您引向问题。
支柱 3:输出日志 (/var/log/cloud-init-output.log
)¶
此日志捕获 cloud-init
执行的所有脚本(例如,来自 runcmd
)的完整 stdout
和 stderr
。如果某个模块运行了,但其中的脚本失败了,错误消息将在此文件中。
实践:调试失败的 runcmd
-
创建一个带有细微错误的
runcmd
的user-data.yml
cat <<EOF > user-data.yml #cloud-config runcmd: - [ ls, /non-existent-dir ] EOF
-
使用此数据启动虚拟机。
cloud-init status
将报告status: done
,因为runcmd
模块本身已成功执行。 -
但是,
/var/log/cloud-init-output.log
将包含来自ls
命令的实际错误,向您展示了什么地方出了问题。ls: cannot access '/non-existent-dir': No such file or directory
2. 使用 libguestfs-tools
进行主机端故障排除¶
有时,虚拟机将无法完全启动,这使得虚拟机内工具无效。在这些情况下,您可以使用强大的 libguestfs-tools
套件(使用 sudo dnf install libguestfs-tools
安装)从主机直接检查 VM 的磁盘映像来诊断问题。
virt-cat
:从客户机磁盘读取文件¶
virt-cat
允许在不挂载的情况下从 VM 的磁盘映像内部读取文件。这非常适合从无法启动的实例中获取日志文件。
# From the host, read the cloud-init.log from the VM's disk
sudo virt-cat -a /path/to/your-vm-disk.qcow2 /var/log/cloud-init.log
virt-inspector
:深入的系统检查¶
virt-inspector
生成 VM 操作系统、应用程序和配置的详细 XML 报告。这对于自动化分析非常强大。
-
获取完整报告
sudo virt-inspector -a your-vm-disk.qcow2 > report.xml
-
执行定向查询: 您可以将 XML 管道到
xmllint
以提取特定信息。此示例检查映像中已安装的cloud-init
版本sudo virt-inspector -a your-vm-disk.qcow2 | xmllint --xpath "//application[name='cloud-init']/version/text()" -
3. 常见陷阱及规避方法¶
陷阱 1:YAML 和架构错误¶
无效的 YAML 是最常见的故障来源。一个更高级的问题是语法上有效的 YAML 文件,但它违反了 cloud-init
的预期结构(例如,模块名称中的拼写错误)。
-
解决方案: 在启动 之前 使用
cloud-init schema
命令来验证您的配置。它将捕获 YAML 错误和结构错误。# Validate your user-data file against the official schema cloud-init schema --config-file user-data.yml
如果文件有效,它将打印
Valid cloud-config: user-data.yml
。否则,它将提供详细的错误。
陷阱 2:依赖网络的模块失败¶
如果网络未能启动,诸如 packages
之类的模块将失败。检查您的网络配置和 /var/log/cloud-init.log
中的 Network
阶段。
4. 控制 cloud-init
的执行¶
- 强制重新运行: 要在正在运行的 VM 上测试更改,请运行
sudo cloud-init clean --logs
,然后运行sudo reboot
。 - 禁用
cloud-init
: 要阻止cloud-init
在后续启动时运行,请创建一个哨兵文件:sudo touch /etc/cloud/cloud-init.disabled
。 - 在每次启动时运行 (
bootcmd
): 对于必须在每次启动时运行的脚本,请使用bootcmd
模块。这很少见,但对于某些诊断很有用。
下一步¶
您现在已经配备了一套强大的工具,可用于虚拟机内和主机端的故障排除。在最后一章中,我们将检查 cloud-init
项目本身,为您准备好探索其源代码并为社区做出贡献。
作者:Wale Soyinka
贡献者:Steven Spencer