你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

对使用 cloud-init 的 VM 预配进行故障排除

注意

本文引用了 CentOS,这是一个处于生命周期结束 (EOL) 状态的 Linux 发行版。 请相应地考虑你的使用和规划。 有关详细信息,请参阅 CentOS 生命周期结束指南

适用于:✔️ Linux VM ✔️ 灵活规模集

如果你已在创建通用化自定义映像(使用 cloud-init 进行预配),但发现 VM 未正确创建,则需对自定义映像进行故障排除。

预配问题的一些示例:

  • cloud-init 报告计算资源提供程序 API 在出错时返回的故障。
  • 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 市场映像。 如果 customData 可以在 Azure 市场映像中正常使用,则可能是特选映像出现问题。

步骤 3:收集和查看 VM 日志

当 VM 无法预配时,Azure 会显示“正在创建”状态 20 分钟,然后重启 VM,再等待 20 分钟,最后才会将 VM 部署标记为失败,并使用 OSProvisioningTimedOut 错误来标记它。

你需要在 VM 处于运行状态的情况下使用其中的日志来了解预配为何失败。 若要了解 VM 预配为何失败,请不要停止 VM。 让 VM 保持运行状态。 为了收集日志,你需要使发生故障的 VM 保持运行状态。 若要收集日志,请使用以下方法之一:

sudo cat /rescue/var/log/cloud-init*
sudo cat /rescue/var/log/waagent*
sudo cat /rescue/var/log/syslog*
sudo cat /rescue/var/log/rsyslog*
sudo cat /rescue/var/log/messages*
sudo cat /rescue/var/log/kern*
sudo cat /rescue/var/log/dmesg*
sudo cat /rescue/var/log/boot*

注意

或者,可以使用 Azure 门户手动创建救援 VM。 有关详细信息,请参阅通过使用 Azure 门户将 OS 磁盘附加到恢复 VM 来对 Linux VM 进行故障排除

若要开始进行初始故障排除,请从 cloud-init 日志着手,了解发生故障的位置,然后使用其他日志深入了解情况并获取更多见解。

  • /var/log/cloud-init.log
  • /var/log/cloud-init-output.log
  • 串行/启动日志

在所有日志中,开始搜索“Failed”、“WARNING”、“WARN”、“err”、“error”、“ERROR”。 建议将配置设置为忽略区分大小写的搜索。

提示

如果对自定义映像进行故障排除,应考虑在映像操作过程中添加用户。 如果预配无法设置管理员用户,你仍然可以登录到 OS。

分析日志

下面更详细地介绍了要在每个 cloud-init 日志中查找什么内容。

/var/log/cloud-init.log

默认情况下,所有优先级为“调试”或更高级别的 cloud-init 事件都会写入到 /var/log/cloud-init.log 中。 这样就可以提供在 cloud-init 初始化期间发生的每个事件的详细日志。

例如:

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)

如果拥有对串行控制台的访问权限,可以尝试重新运行 cloud-init 试图运行的命令。

还可以在 /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 中的信息。 这通常涉及 cloud-init 的每个阶段的路由表信息、网络信息、ssh 主机密钥验证信息、stdoutstderr,以及每个阶段的时间戳。 如果需要,可以通过 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 个阶段中执行)后运行。 若要排查为何未应用配置,请手动查看步骤 3 中的日志和 cloud-init 模块。 例如:

  • runcmd - 脚本在运行时是否未出错? 请从终端手动运行配置,以确保它们按预期运行。
  • 安装包 - VM 是否有权访问包存储库?
  • 还应检查提供给 VM 的 customData 数据配置,该配置位于 /var/lib/cloud/instances/<unique-instance-identifier>/user-data.txt 中。

后续步骤

如果仍然无法厘清 cloud-init 未运行配置的原因,则需更细致地了解每个 cloud-init 阶段发生的情况,以及运行模块的时间。 有关详细信息,请参阅更深入地了解 cloud-init 配置