谨慎
本文引用 CentOS,这是支持终止(EOS)状态的 Linux 分发版。 请相应地考虑使用和规划。 有关详细信息,请参阅 CentOS 生命周期结束指南。
适用对象:✔️ Linux VM ✔️ 灵活规模集
如果创建通用自定义映像并使用 cloud-init 进行预配,则 VM 可能无法正确生成。 在这种情况下,请对映像进行故障排除以查找问题。
预配问题的一些示例:
- 计算资源提供程序 API 返回错误,cloud-init 报告生成的失败。
- VM 停滞在“正在创建”状态达 40 分钟,并且 VM 创建操作被标记为失败。
- 不会处理自定义数据 或 用户数据 。
- 临时磁盘无法装载(对应于 SCSI 资源磁盘随附的 VM SKU)。
- 用户未创建,或者存在用户访问问题。
- 未正确设置网络。
- 交换文件或分区故障。
本文逐步讲解如何对 cloud-init 进行故障排除。 如需更深入的详细信息,请参阅深入探讨 cloud-init。
排查 cloud-init 报告的故障并将其记录为错误
Cloud-init 在资源预配期间向 Azure 报告失败时会生成结构化错误信息。 这些错误消息包括原因和支持数据(例如时间戳、VM 标识符、文档 URL 等),以帮助调查失败。
原因 | DESCRIPTION | 行动 |
---|---|---|
找不到 DHCP 接口 | 找不到网络接口。 | 删除并重新创建 VM。 如果问题仍然存在,请确保已安装网络驱动程序或 Azure 专用内核,并检查启动诊断以确认 eth0 是否被正确枚举。 |
未能获取 DHCP 租约 | DHCP 服务因暂时性平台问题而无法响应。 | 删除并重新创建 VM。 |
找不到主 DHCP 接口 | 找不到主 DHCP 接口。 | 检查启动诊断,确保主网络接口已命名 eth0 ,且未重命名。 |
查询 IMDS 时连接超时 | 与 IMDS 的连接可能会因暂时性平台问题、NSG 或操作系统防火墙配置而超时。 | 删除并重新创建 VM。 如果问题仍然存在,请验证 NSG 或 OS 防火墙是否未阻止访问 IMDS。 |
查询 IMDS 时读取超时 | 与 IMDS 的连接可能会因暂时性平台问题或操作系统防火墙配置而超时。 | 删除并重新创建 VM。 如果问题仍然存在,请验证 OS 防火墙不会阻止访问 IMDS。 |
分析 ovf-env.xml 时出现意外的元数据 |
ovf-env.xml 中的 VM 元数据格式不正确。 |
使用提供的链接将问题提交到 cloud-init 跟踪器。 |
等待主机关闭时出错 | 主机关闭处理期间出现故障。 | 使用提供的链接将问题提交到 cloud-init 跟踪器。 |
找不到 Azure-proxy-agent | 缺少 azure-proxy-agent 二进制文件。 |
确保映像中安装了 Azure 代理程序。 有关更多故障排除,请查看 MSP 故障排除指南。 |
Azure-proxy-agent 状态失败 | 代理程序报告了状态错误。 | 根据需要查看代理日志并更新。 有关更多故障排除,请查看 MSP 故障排除指南。 |
未经处理的异常 | cloud-init 内部发生意外错误。 | 使用提供的链接将问题提交到 cloud-init 跟踪器。 |
有关启用和检查启动诊断的帮助,请参阅 启动诊断。
如果在预配时后续尝试中仍然存在这些问题,则这是因为映像中配置错误。 如果有理由相信存在 cloud-init 问题,请将其报告给 cloud-init GitHub 问题跟踪器。
排查 cloud-init 未报告的其他故障
根据失败情况,请考虑以下步骤。
步骤 1:在不使用 customData
的情况下测试部署
创建 VM 时,Cloud-init 可以接受 customData
传递给它的云。 首先,应确保此配置不会导致部署出现问题。 尽量在不传入任何配置的情况下预配 VM。 如果 VM 无法预配,请按照建议的故障排除步骤作。 如果未应用配置,请参阅 步骤 4。
步骤 2:查看映像要求
VM 预配失败的主要原因是 OS 映像不满足在 Azure 上运行的先决条件。 尝试在 Azure 中预配映像之前,请确保已正确准备好映像。
以下文章演示了准备 Azure 中支持的各种 Linux 发行版的步骤:
对于受支持的 Azure cloud-init 映像,Linux 发行版已准备好所有必需的包和配置,方便用户在 Azure 中正确预配映像。 如果发现无法基于你自己的特选映像创建 VM,请尝试使用一个受支持的、已使用你的可选 customData
为其配置了 cloud-init 的 Azure 市场映像。 如果 Azure customData
市场映像正常工作,则特选映像可能存在问题。
步骤 3:收集和查看 VM 日志
当 VM 预配失败时,Azure 会显示“创建”状态,20 分钟,然后重新启动 VM,再等待 20 分钟,然后最后将 VM 部署标记为失败,最后将其标记为 OSProvisioningTimedOut
错误。
在 VM 运行时,需要 VM 中的日志来了解预配失败的原因。 若要了解 VM 预配失败的原因,请不要停止 VM。 让 VM 保持运行状态。 需要使失败的 VM 保持运行状态才能收集日志。 若要收集日志,请使用以下方法之一:
运行 AZ VM 修复 以附加和装载 OS 磁盘(lvm, 无 lvm),这样就可以收集和检查这些日志:
/rescue/var/log/waagent* /rescue/var/log/syslog* /rescue/var/log/rsyslog* /rescue/var/log/messages* /rescue/var/log/kern* /rescue/var/log/dmesg* /rescue/var/log/boot* /rescue/ /var/log/cloud-init.log /rescue//var/log/cloud-init-output.log
> [!NOTE]
> Alternatively, you can create a rescue VM manually by using the Azure portal. For more information, see [Troubleshoot a Linux VM by attaching the OS disk to a recovery VM using the Azure portal](https://learn.microsoft.com/troubleshoot/azure/virtual-machines/troubleshoot-recovery-disks-portal-linux).
To start initial troubleshooting, begin with the serial logs and cloud-init logs to understand where the failure occurred. Then use the other logs for a deeper dive to help provide additional insights.
* /var/log/cloud-init.log
* /var/log/cloud-init-output.log
* [Serial/boot logs](/virtual-machines/boot-diagnostics#boot-diagnostics-view)
In all logs, start searching for "Failed," "WARNING," "WARN," "err," "error," and "ERROR." Setting configuration to ignore case-sensitive searches is recommended.
Alternatively, use command `cloud‑init collect‑logs` to collect all necessary logs.
Azure’s latest cloud-init versions (≥ 18.2) include the collect‑logs command, which:
Gathers essential logs: /var/log/cloud-init*.log, instance metadata, system info.
Packages everything into a timestamped .tar.gz archive.
Saves the archive locally (for example, `/tmp/cloud-init-logs-timestamp.tar.gz`).
> [!TIP]
> If you're troubleshooting a custom image, you should consider adding a user during the image. If the provisioning fails to set the admin user, you can still log in to the OS.
#### Analyzing the logs
Here are more details about what to look for in each cloud-init log.
#### /var/log/cloud-init.log
By default, all cloud-init events with a priority of debug or higher, are written to `/var/log/cloud-init.log`. This log provides verbose logs of every event that occurred during cloud-init initialization.
For example:
```console
2019-10-10 04:51:25,321 - util.py[DEBUG]: Failed mount of '/dev/sr0' as 'auto': Unexpected error while running command.
Command: ['mount', '-o', 'ro,sync', '-t', 'auto', u'/dev/sr0', '/run/cloud-init/tmp/tmpLIrklc']
Exit code: 32
Reason: -
Stdout:
Stderr: mount: unknown filesystem type 'udf'
2020-01-31 00:21:53,352 - DataSourceAzure.py[WARNING]: /dev/sr0 was not mountable
找到错误或警告时,在 cloud-init 日志中向后读取,以了解在遇到错误或警告之前尝试的 cloud-init。 在许多情况下,cloud-init 在发生错误之前运行 OS 命令或执行预配步骤。 这些作有助于解释错误为何出现在日志中。 以下示例显示 cloud-init 在遇到问题之前尝试直接装载设备。
2019-10-10 04:51:24,010 - util.py[DEBUG]: Running command ['mount', '-o', 'ro,sync', '-t', 'auto', u'/dev/sr0', '/run/cloud-init/tmp/tmpXXXXX'] with allowed return codes [0] (shell=False, capture=True)
还可以在 /etc/cloud/cloud.cfg.d/05_logging.cfg 中重新配置 /var/log/cloud-init.log
的日志记录。 有关 cloud-init 日志记录的详细信息,请参阅 cloud-init 文档。
/var/log/cloud-init-output.log
可以在 stdout
获取 stderr
和 中的信息。 此数据通常涉及路由表信息、网络信息、ssh 主机密钥验证信息以及 stdout,
stderr
cloud-init 的每个阶段以及时间戳。 如果需要,可以通过 stderr
重新配置 stdout
和 /etc/cloud/cloud.cfg.d/05_logging.cfg
日志记录。
串行/启动日志
Cloud-init 具有多个依赖项。 这些依赖项记录在 Azure 上的映像所需的先决条件中,例如网络、存储、装载 ISO 以及装载和格式化临时磁盘。 这些依赖项中的任何一个都可能会引发错误并导致 cloud-init 失败。 例如,如果 VM 无法获取 DHCP 租约,cloud-init 将失败。
如果仍然无法隔离 cloud-init 未能预配的原因,则需要了解什么是 cloud-init 阶段,以及何时运行模块。 有关详细信息,请参阅 深入了解 cloud-init。
步骤 4:调查未应用配置的原因
并非 cloud-init 中的每次失败都会导致严重的预配故障。 例如,如果在 cloud-init 配置中使用 runcmd
模块,则命令中的非零退出代码会导致 VM 预配失败。 发生此行为的原因是模块在 cloud-init 的前三个阶段的核心预配步骤之后运行。 若要排查配置未应用的原因,请手动查看步骤 3 中的日志和 cloud-init 模块。 例如:
-
runcmd
- 脚本在运行时是否未出错? 为了确保它们按预期运行,请从终端手动运行配置。 - 安装包 - VM 是否有权访问包存储库?
-
customData
检查提供给 VM 的配置。 此文件位于/var/lib/cloud/instances/<unique-instance-identifier>/user-data.txt
.
后续步骤
如果 cloud-init 跳过配置,请检查每个 cloud-init 阶段以及模块执行的时间以确定原因。 有关详细信息,请参阅 更深入地了解 cloud-init 配置。