使用 cloud-init 初始化 CVM 失败报错 exit code 1 怎么排查?

文章导读
遇到 cloud-init 初始化报错 exit code 1,最稳妥的办法是先查看日志定位具体失败模块,再根据错误类型决定是修复配置还是重置初始化状态。谨慎重启实例,优先尝试重置初始化状态。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

遇到 cloud-init 初始化报错 exit code 1,最稳妥的办法是先查看日志定位具体失败模块,再根据错误类型决定是修复配置还是重置初始化状态。谨慎重启实例,优先尝试重置初始化状态。

先说结论:exit code 1 是通用错误码,必须结合日志才能确定是网络问题、脚本错误还是配置语法问题。

  • 先确认:检查 /var/log/cloud-init.log/var/log/cloud-init-output.log 里的报错堆栈,先备份日志。
  • 先处理:修复 user-data 语法或网络连通性,必要时使用 cloud-init clean 重置状态。
  • 再验证:重新触发初始化或重启实例,确认状态变为 done 且无报错。

命令速用版

# 查看 cloud-init 版本(排查兼容性问题)
cloud-init `--version`

# 查看当前初始化状态
cloud-init status `--long`

# 查看详细日志(关注 ERROR 关键字)
tail -n 100 /var/log/cloud-init.log

# 查看脚本执行输出日志
tail -n 100 /var/log/cloud-init-output.log

# 备份日志(重置前必做)
sudo cp /var/log/cloud-init.log /var/log/cloud-init.log.bak
sudo cp /var/log/cloud-init-output.log /var/log/cloud-init-output.log.bak

# 重置初始化状态(慎用,不会自动删除日志)
sudo cloud-init clean

# 手动清理日志(如需彻底重置)
sudo rm /var/log/cloud-init.log
sudo rm /var/log/cloud-init-output.log

为什么会这样

cloud-init 是云服务器实例首次启动时自动运行的初始化服务,负责配置主机名、注入 SSH 密钥、运行用户脚本等任务。exit code 1 是 Linux 进程的标准退出码,表示“通用错误”,它本身不指代具体原因,只说明过程中某个环节失败了。

常见导致该错误的原因包括:

  • user-data 语法错误:提交的云初始化脚本 YAML 缩进不对或格式非法,导致解析失败。
  • 元数据服务不可达:实例无法访问云厂商的元数据服务器(通常是 169.254.169.254),导致获取配置超时。
  • 脚本执行失败:用户自定义的脚本中包含错误命令或依赖缺失,导致 subprocess 返回非零状态。
  • 权限问题:cloud-init 进程没有权限写入特定文件或修改网络配置。
  • 版本兼容性:不同 Linux 发行版或 cloud-init 版本对配置的支持程度不同。

分步处理

按照以下顺序排查,避免盲目操作导致问题复杂化。

1. 检查初始化状态

登录实例后,首先运行状态命令,确认当前处于什么阶段。不同版本输出可能略有差异。

使用 cloud-init 初始化 CVM 失败报错 exit code 1 怎么排查?
cloud-init status `--long`

如果显示 status: errorstatus: running 但长时间卡住,说明初始化未正常完成。记录下 detail 字段中的提示信息。

2. 定位具体报错日志

cloud-init 有两个主要日志文件,分工不同:

  • /var/log/cloud-init.log:记录 cloud-init 内部模块的运行细节,适合排查模块加载、元数据获取失败等问题。
  • /var/log/cloud-init-output.log:记录用户脚本(user-data)的标准输出和错误输出,适合排查自定义脚本报错。

使用 grep 快速过滤错误行:

grep -i "error\|failed\|traceback" /var/log/cloud-init.log

如果看到 UrlErrorConnectionTimeout,通常是网络问题;如果看到 YamlError,则是配置语法问题。

3. 修复配置或网络

如果是 user-data 语法错误,需要在云控制台重新提交正确的 YAML 配置。注意 YAML 对缩进非常敏感,确保使用空格而非 Tab。

使用 cloud-init 初始化 CVM 失败报错 exit code 1 怎么排查?

如果是网络问题,检查实例安全组是否放行了出方向流量,以及是否能 ping 通元数据服务器地址。

curl -m 5 http://169.254.169.254/latest/meta-data/

如果无法连通,可能需要检查实例内部路由或联系云厂商排查底层网络。部分新实例要求使用 IMDSv2(需要 Token),旧版 cloud-init 可能不支持。

4. 重置初始化状态(谨慎操作)

如果修复了配置或网络,需要让 cloud-init 重新运行。直接重启实例可能不会触发重新初始化,因为状态文件标记为已完成。可以使用 clean 命令重置:

# 1. 备份日志(重要)
sudo cp /var/log/cloud-init.log /var/log/cloud-init.log.bak

# 2. 重置状态
sudo cloud-init clean

# 3. 重新触发初始化阶段
sudo cloud-init init
sudo cloud-init config
sudo cloud-init final

注意:cloud-init clean 会清除状态文件但不会自动删除日志文件,如需彻底清理需手动 rm 日志。生产环境执行前务必确认业务影响,避免 user-data 脚本重复执行引发副作用。

怎么验证是否生效

完成处理后,通过以下方式确认问题已解决:

  • 状态检查:运行 cloud-init status,确保返回 status: donedetail: no errors
  • 日志检查:再次查看 /var/log/cloud-init.log 末尾,确认没有新的 ERROR 级别日志。
  • 功能验证:检查预期配置是否生效,例如指定用户是否创建、SSH 密钥是否写入 ~/.ssh/authorized_keys、主机名是否变更等。

常见坑

  • YAML 缩进错误:这是最常见的原因。cloud-init 的 user-data 严格遵循 YAML 规范,缩进不一致会导致解析失败从而报 exit code 1。
  • 重复初始化风险:在生产环境随意运行 cloud-init clean 可能导致实例标识重置或重复执行脚本,引发业务副作用。操作前务必确认业务影响。
  • 元数据服务地址差异:不同云厂商的元数据服务地址或版本可能不同,部分新实例要求使用 IMDSv2(需要 Token),旧版 cloud-init 可能不支持,导致获取配置失败。
  • 版本与发行版差异:不同 Linux 发行版(如 CentOS vs Ubuntu)或 cloud-init 版本间的命令支持可能存在差异,操作前建议先运行 cloud-init `--version` 确认。
  • 日志被轮转:如果实例运行时间较长,日志可能已被轮转删除。排查时应尽量在问题发生后立即查看日志。

参考来源

  • cloud-init 官方文档 - 日志与故障排查:https://cloudinit.readthedocs.io/
  • 腾讯云文档 - cloud-init 简介与常见问题:https://cloud.tencent.com/document/product/213/17814
  • 阿里云文档 - cloud-init 使用指南:https://help.aliyun.com/document_detail/59239.html