linux系统通过cloud-init实现虚拟机首次启动自动初始化,依赖cloud-init服务启用、user-data符合#cloud-config规范、平台正确注入配置三环节协同;需验证服务状态与执行结果,严格遵循yaml格式及环境注入要求。

Linux 系统通过 Cloud-init 初始化虚拟机,核心是让系统在首次启动时自动读取并执行预置的配置(如主机名、用户、软件包、网络等),而不是手动逐台配置。它不是“写个脚本就完事”,而是依赖三个关键环节协同工作:系统已装且启用 cloud-init 服务、user-data 符合 #cloud-config 规范、平台能正确注入配置数据。
✅ 先确认 cloud-init 是否真正就绪
很多问题其实卡在服务根本没跑起来。尤其在本地虚拟化环境(如 VirtualBox、KVM、Proxmox)或自定义镜像中,cloud-init 往往未启用。
-
查状态:
systemctl status cloud-init
正常应显示
active (exited)(注意:它是一次性服务,成功后退出,不是常驻进程)。 -
查详细执行结果:
sudo cloud-init status --long
输出中
status: done且各阶段(init、modules:config、modules:final)均为success才算走通。 -
若命令不存在,先安装:
- Ubuntu/Debian:
sudo apt install cloud-init - Rocky/Alma/RHEL:
sudo dnf install cloud-init - Alpine:
apk add cloud-init
- Ubuntu/Debian:
-
装完必须启用并重启:
sudo systemctl enable cloud-init sudo reboot
⚠️ 注意:cloud-init 依赖
systemd-networkd或NetworkManager。若你禁用了这两个服务,网络相关初始化会跳过或失败。
? 编写合法的 user-data 文件
Cloud-init 不执行任意 shell 脚本——它只认特定格式的 user-data,最常用的是 #cloud-config YAML 格式。
基本要求:
- 首行严格为
#cloud-config(不能有空格、注释、空行) - YAML 缩进用空格,禁止 Tab
- 换行符必须是 LF(Unix 格式),Windows 的 CRLF 会导致解析失败
- 字段名大小写敏感(如
users下用name,不是username;ssh_authorized_keys是列表)
最小可用示例(设主机名、建用户、写欢迎文件):
#cloud-config
hostname: web01
manage_etc_hosts: true
users:
- name: deploy
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2E... user@host
write_files:
- path: /etc/motd
content: |
Welcome to cloud-init initialized system.
? 在不同环境中注入配置
公有云(AWS/Azure/阿里云/腾讯云):
通常默认支持,上传镜像时勾选“启用 cloud-init”,创建实例时通过--user-data或控制台上传user-data即可。-
KVM/QEMU(如 Proxmox、libvirt):
需挂载 NoCloud 数据源 ISO 或磁盘镜像:- 创建 FAT32 镜像
seed.img,放入meta-data(可为空)和user-data - 启动时作为只读光驱挂载
- 确保内核参数含
cloud-init=enabled或 datasource 自动识别为NoCloud
- 创建 FAT32 镜像
VirtualBox / VMware Workstation:
无原生元数据服务,需借助NoCloud+ 手动挂载 ISO,或使用cloud-localds工具生成 seed ISO。
? 常见问题快速定位
-
Invalid yaml format→ 检查缩进、冒号后空格、是否混用 Tab/LF、首行是否干净 -
No user data provided→ 查journalctl -u cloud-init | grep DataSource,若输出None,说明没读到数据源 - 主机名没生效 → 确认
manage_etc_hosts: true,并检查/etc/hosts是否被其他服务覆盖 - SSH 密钥不生效 →
ssh_authorized_keys必须是列表格式,每行一个 key,末尾不能有多余换行
不复杂但容易忽略。只要服务启了、格式对了、数据源通了,一次启动就能完成初始化。











