好的,我会为你整理一份关于如何使用 Cloud-Init 初始化 KVM 虚拟机的中文文档,内容包括适用于 Windows 和 Linux 系统的配置差异、完整的 user-data 和 meta-data 范例、网络与 SSH 设置、以及如何通过 libvirt/virt-install 等方式将这些文件挂载到虚拟机中。 我整理好后会第一时间告诉你。
使用 Cloud-Init 初始化 KVM 虚拟机指南
在 KVM 环境中,通过 Cloud-Init 可以自动完成虚拟机实例的初始化配置,包括网络设置、用户和密码、SSH 密钥注入、主机名配置等。Cloud-Init 通常使用一个称为 NoCloud 的数据源(也称为 seed ISO 配置盘)将初始化数据提供给虚拟机 (第 4 章 配置 cloud-init | Red Hat Product Documentation) (第 4 章 配置 cloud-init | Red Hat Product Documentation)。以下将详细说明 Cloud-Init 的配置文件范例、Linux 与 Windows 系统的差异、常见初始化参数设置方法,以及如何使用 libvirt/virt-install/virsh 等工具将 Cloud-Init 配置挂载到 KVM 虚拟机中。最后提供一个完整的配置流程示例(包含使用 cloud-localds
创建 seed ISO 的方法),供系统管理员或运维人员参考。
Cloud-Init 配置文件范例(Linux 和 Windows)
Cloud-Init 使用两个主要的配置文件来传递初始化信息:
user-data
: 用户数据文件,包含虚拟机初始化时要执行的配置(例如创建用户、设置密码或 SSH 公钥、安装软件包、运行脚本等) (第 4 章 配置 cloud-init | Red Hat Product Documentation)。通常采用 YAML 格式的 cloud-config 数据(以#cloud-config
开头)。meta-data
: 元数据文件,包含实例的元信息(例如实例ID、主机名等) (第 4 章 配置 cloud-init | Red Hat Product Documentation)。该文件用于提供实例的标识和基本信息。
这两个文件会被打包到一个 ISO 镜像中并挂载给虚拟机。虚拟机启动时,Cloud-Init 服务会从挂载的介质(NoCloud 数据源)读取这些文件,从而应用相应的配置。
下面分别给出 Linux 和 Windows 云镜像的 Cloud-Init 配置示例。
Linux 系统 Cloud-Init 配置示例
user-data(Linux)示例:使用 cloud-config YAML 格式定义配置。该示例创建一个新用户并添加 SSH 密钥、设置主机名和安装软件包等:
#cloud-config
hostname: mylinux-vm # 设置主机名
manage_etc_hosts: true # 更新 /etc/hosts
users:
- name: devops # 创建名为 devops 的用户
gecos: DevOps User
groups: [sudo] # 将用户添加到 sudo 组
sudo: "ALL=(ALL) NOPASSWD:ALL" # 无需密码即可使用 sudo
shell: /bin/bash
ssh-authorized-keys: # 注入 SSH 公钥用于无密码登录
- ssh-rsa AAAAB3NzaC1yc2E...your_public_key_here...
chpasswd:
list: |
devops:password123 # 为用户设置密码(明文将被加密保存)
expire: false # 密码不过期
package_update: true # 更新包索引
packages:
- git
- curl
runcmd:
- [ "echo", "Cloud-Init setup complete." ] # 引导后运行命令
上述 user-data 配置做了以下事项:设置主机名(hostname
)、创建了一个 devops 用户并赋予sudo权限,设置了该用户密码和SSH公钥,安装了Git和Curl软件包,并在引导完成后输出一条消息作为验证。 (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium) (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium)。文件必须以#cloud-config
开头并采用 YAML 格式 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)。
meta-data(Linux)示例:提供实例标识和主机名等元数据:
instance-id: i-00001
local-hostname: mylinux-vm
典型情况下,meta-data
至少包含一个唯一的实例ID(可任意指定)和本地主机名。Cloud-Init 会读取其中的 local-hostname
来设置虚拟机的主机名(如果未在 user-data 中另行指定) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。上述示例将实例ID设为 i-00001
,主机名设为 mylinux-vm。
Windows 系统 Cloud-Init 配置示例
Windows 虚拟机需要使用 Cloudbase-Init(Cloud-Init 的 Windows 实现)来支持类似功能 (Cloud-Init Support - Proxmox VE)。在准备 Windows 云镜像时,需要预先在镜像中安装并配置 Cloudbase-Init 服务,否则 Cloud-Init 配置数据将不会被处理 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。Cloudbase-Init 能解析 NoCloud 配置盘中的数据,但其支持的 cloud-config 指令略有不同,且功能上有所限制(不支持Linux特有功能) (Userdata — cloudbase-init 1.1.7 documentation) (Cloud-Init Support - Proxmox VE)。例如,Linux 中的软件包安装指令在 Windows 上不适用,但账户、密码、主机名、SSH密钥注入等常用配置仍受支持。
user-data(Windows)示例:使用 Cloudbase-Init 解析的 cloud-config YAML,创建/配置用户并设置主机名等:
#cloud-config
users:
- name: Administrator # 指定要配置的用户(内置管理员账户)
groups: [Administrators] # 确保属于管理员组
passwd: "P@ssw0rd!" # 设置登录密码(Windows 下需明文)
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2E...your_public_key_here...
set_hostname: win-vm # 设置主机名
runcmd:
- cmd.exe /c echo Cloudbase-Init OK > C:\cloud-init-result.txt
上述 user-data 将内置的 Administrator 用户密码设置为 "P@ssw0rd!" 并添加一个 SSH 公钥(如果 Windows 安装了 OpenSSH 服务器,则可用于密钥登录)。同时设置主机名为 win-vm,并通过 runcmd
执行了一条简单命令在 C:盘写入文件,作为初始化完成的标识。
**注意:**Cloudbase-Init 在处理 users
部分时,对于 Windows 用户密码需要明文提供;而 Linux 中通常使用加密哈希 (Userdata — cloudbase-init 1.1.7 documentation)。如果未提供密码,Cloudbase-Init 会为该用户随机生成密码 (Userdata — cloudbase-init 1.1.7 documentation)。另外,改变 Windows 主机名通常需要重启才能生效,Cloudbase-Init 会在必要时执行此操作 (Userdata — cloudbase-init 1.1.7 documentation)。
meta-data(Windows)示例:Windows 的 meta-data 文件格式与 Linux 相同,也可如下:
instance-id: i-00002
local-hostname: win-vm
对于 Windows 虚拟机,Cloudbase-Init 同样会读取 local-hostname
来设置计算机名(如果未在 user-data 中使用 set_hostname
) (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud) (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。instance-id
用于标识实例,可用任意唯一值。
Linux 与 Windows Cloud-Init 支持差异
虽然 Linux 和 Windows 都可以利用 Cloud-Init 框架完成初始化配置,但二者在支持范围和实现方式上存在一些差异:
Cloud-Init 软件提供方式:在 Linux 平台,大多数主流发行版云镜像预装了 cloud-init 服务(Ubuntu、CentOS、Fedora 等都有官方的 Cloud-Init 镜像)。即使自行安装操作系统,也可以通过软件包管理器安装 cloud-init 并启用 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)。Windows 平台则没有原生的 Cloud-Init;需要安装 Cloudbase-Init(由 Cloudbase Solutions 提供的 Windows 移植版)来实现类似功能 (Cloud-Init Support - Proxmox VE)。许多公共云提供的 Windows 镜像已预装 Cloudbase-Init (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud),但如果使用自定义 Windows 镜像,需要手动安装并配置该服务 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。
支持的数据源:Linux Cloud-Init 默认支持多种数据源,例如 NoCloud(本地配置盘)、Config Drive(配置光盘),EC2 metadata服务等 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)。KVM 本地环境下通常使用 NoCloud 或 Config Drive 数据源,其中 NoCloud 数据源通过挂载一个标签为 cidata 的盘(ISO镜像或磁盘文件)提供
user-data
和meta-data
文件 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。Windows Cloudbase-Init 同样支持读取 Config Drive/NoCloud 类型的数据源(通常也通过识别 cidata 卷来获取配置)。在 Proxmox 等平台上,需将虚拟机的ostype
设置为 Windows 并使用 ConfigDrive 模式,以确保 Cloudbase-Init 正确读取配置盘 (Cloud-Init Support - Proxmox VE)。简单来说,Linux 和 Windows 虚拟机在 KVM 中都可以使用 NoCloud seed ISO 来传递 Cloud-Init 配置。初始化功能差异:大部分 基础配置(如用户和密码、SSH密钥、主机名等)两者均支持。但 Linux Cloud-Init 提供了更丰富的模块,例如软件包安装更新(apt/yum)、网络配置、分区扩展等 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)。Windows Cloudbase-Init 不支持 Linux 特有的功能,如直接安装软件包(没有 apt/yum),配置管理Linux服务等 (Userdata — cloudbase-init 1.1.7 documentation)。在 Windows 上主要支持的操作有:设置管理员密码、创建新用户 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)、注入 SSH 密钥 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)、设置主机名 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)、执行本地脚本或命令等 (Userdata — cloudbase-init 1.1.7 documentation)。另外,Linux 默认使用加密哈希保存用户密码,而 Windows 则要求提供明文密码由 Cloudbase-Init 设置 (Userdata — cloudbase-init 1.1.7 documentation)。
网络配置支持:Linux Cloud-Init 支持通过 network-config 文件或 cloud-config 中的网络配置语法来设置静态网络(例如为虚拟机配置固定 IP、网关、DNS 等) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。然而 Windows Cloudbase-Init 通常并不直接应用静态网络配置 —— 大多数 Windows 云场景依赖 DHCP 获取网络,Cloudbase-Init 本身没有针对静态 IP 的内置配置模块(仅支持配置MTU等少数网络选项 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud))。因此,在 Windows 虚拟机上,如果需要设置固定 IP,通常需要通过其它方式(比如在模板中预设、使用 Sysprep 应答文件或后续脚本)来实现,而非通过 Cloudbase-Init。
服务启用与执行时机:Linux 上 cloud-init 在首次引导时分多个阶段运行(引导前/引导后)来应用配置,并在
/var/lib/cloud/
目录做状态记录,防止重复执行。Windows 上 Cloudbase-Init 安装为系统服务,通常在系统启动后运行一次并配置相应内容,然后可以选择在完成后禁用首次登录强制修改密码等策略 (virt-install --cloud-init support | Cole Robinson)。在制作为模板时,Windows 常需要运行 Sysprep 通用化系统,Cloudbase-Init 提供无人参与(unattend)脚本来确保 Sysprep 后继续正常工作 (Cloud-Init Support - Proxmox VE) (Cloud-Init Support - Proxmox VE)。这些过程都与各自操作系统的初始化机制相关,在使用 Cloud-Init 时需要注意。
**小结:**总体而言,如果使用官方的云镜像,Linux 平台的 Cloud-Init 开箱即用,而 Windows 则需确保 Cloudbase-Init 安装配置正确 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。Linux Cloud-Init 功能更全面,Windows Cloudbase-Init 提供核心必要功能。管理上要注意两者在密码和网络等配置上的差异,合理地编写 user-data 脚本以兼容对应操作系统。
常见初始化参数的配置方法
利用 Cloud-Init,我们可以在虚拟机首次引导时定制各种参数。以下列出常见初始化项在 Cloud-Init(主要指 NoCloud cloud-config)中的配置方式:
网络配置: 可以通过提供 网络配置文件或在 user-data 中指定网络参数(取决于发行版对 network-config 的支持)。最常见做法是提供一个独立的
network-config
文件(在 seed ISO 中与 user-data/meta-data 并存)来设置静态网络。 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)例如,创建一个network-config
文件内容如下,配置静态IP地址:#cloud-config version: 2 ethernets: ens3: dhcp4: false addresses: [192.168.122.100/24] gateway4: 192.168.122.1 nameservers: addresses: [8.8.8.8, 8.8.4.4]
上述配置使用了 Cloud-Init 的 Network Config v2 格式,将接口
ens3
配置为静态 IP。version: 2
指定网络配置的版本格式。这一文件需要在制作 seed ISO 时一并打包,并确保 Cloud-Init 数据源启用了对 NoCloud 网络配置的支持。如果不使用独立文件,也可以尝试将网络配置包含在 user-data 的 YAML 中,但并非所有发行版都默认启用从 user-data 解析网络设置。因此更可靠的是使用network-config
文件方式。 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)对于 Windows 而言,如前述,Cloudbase-Init 通常依赖 DHCP 获得网络配置。如果一定要预置网络,可考虑通过 Windows 自身的方法(例如 Sysprep 的应答文件)实现;Cloudbase-Init 并没有直接的 network-config 格式支持。
创建用户和设置密码: 在 Linux cloud-config 中,可以使用
users
字段创建新用户并设定其属性,或者使用chpasswd
模块批量设置账户密码。比如,在 user-data 中:users: - name: alice groups: [sudo] sudo: "ALL=(ALL) NOPASSWD:ALL" ssh_authorized_keys: - ssh-rsa AAAA... alice_key chpasswd: list: | alice:Password123 expire: false
上述配置将创建用户 alice(加入sudo组且免密码sudo),并设置其密码为 “Password123” 且不强制过期,同时添加一把 SSH 公钥到其账户。 (第 4 章 配置 cloud-init | Red Hat Product Documentation)如果只想修改已有用户(如默认用户或 root)的密码,可直接在
chpasswd
列出,例如root:newpass
。还可以通过ssh_pwauth: true
来允许 SSH 使用密码登录 (第 4 章 配置 cloud-init | Red Hat Product Documentation)(默认某些云镜像可能只允许密钥登录)。在 Windows Cloudbase-Init 中,同样可以使用
users
列表定义用户(或已存在用户)。需注意 Windows 下passwd
字段应提供明文密码 (Userdata — cloudbase-init 1.1.7 documentation)。例如:users: - name: Administrator passwd: "Secret123!"
这将把内置管理员 Administrator 的密码设置为 "Secret123!"。如果希望创建额外的新用户,也可以像 Linux 那样提供额外的用户条目,Cloudbase-Init 会使用 CreateUserPlugin 创建用户并用 SetUserPasswordPlugin 设置密码 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud) (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。
SSH 公钥注入: 要将 SSH 公钥添加到虚拟机,用于无密码登录,可以通过两种方式:
- 在 user-data 的 users 条目中为特定用户指定
ssh_authorized_keys
列表(如上例为 alice 用户所示),Cloud-Init 会将公钥写入该用户的~/.ssh/authorized_keys
。 (第 4 章 配置 cloud-init | Red Hat Product Documentation) - 针对默认用户,在某些云镜像中,可以使用顶层的
ssh_authorized_keys
设置将公钥注入默认账号。例如:
并确保ssh_authorized_keys: - ssh-rsa AAAA... your_key
users
包含- default
来引用镜像自带的默认用户 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。不同发行版的 Cloud-Init 对此支持可能略有不同,但例如在 Ubuntu/CentOS官方云镜像中,此方法通常会将公钥加入默认用户(如 ubuntu 或 ec2-user)的授权钥匙列表。
对 Windows 而言,Cloudbase-Init 也支持注入 SSH 公钥 (Installing and Configuring Cloudbase-Init_Image Management Service_Huawei Cloud)。它会将公钥添加到指定用户的
authorized_keys
文件(通常位于%APPDATA%\.ssh\authorized_keys
)。不过Windows默认通过远程桌面登录,更常用密码方式;若需要SSH登录,需确保系统安装并启用了 SSH 服务(例如 Windows 自带的 OpenSSH 服务器)才能利用该密钥。- 在 user-data 的 users 条目中为特定用户指定
主机名(hostname)设置: Cloud-Init 有两种方式设置主机名:
- 在 meta-data 文件中指定
local-hostname
。Cloud-Init读取配置盘时会优先将此值作为实例的主机名。 - 在 user-data 中使用 cloud-config 的
hostname
字段或set_hostname
指令来设置主机名 (Userdata — cloudbase-init 1.1.7 documentation)。两者作用相似,hostname:
通常用于Linux,Cloudbase-Init也支持set_hostname
。
一般来说,在 Linux 云镜像中,通过 meta-data 提供主机名就足够了 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。而在 Windows 上,由于 Cloudbase-Init 默认也会尝试将 meta-data 的主机名应用,所以同样在 meta-data 中填写即可。如果需要在 user-data 内执行更复杂的命名逻辑,可以使用相关指令。需要注意,修改主机名在Windows上可能触发重启 (Userdata — cloudbase-init 1.1.7 documentation),Cloudbase-Init 会处理这个过程;在 Linux 上则通常即时生效并更新 /etc/hostname 和 /etc/hosts(如果
manage_etc_hosts: true
)。- 在 meta-data 文件中指定
其他常用配置:Cloud-Init 非常灵活,还支持许多其他初始化配置。例如:
- 文件写入:使用
write_files
指令可以将指定内容写入虚拟机上的文件中(Linux/Windows均支持,Windows下路径需使用 Windows 路径格式) (Userdata — cloudbase-init 1.1.7 documentation) (Userdata — cloudbase-init 1.1.7 documentation)。 - 时区设置:使用
timezone
或 Cloudbase-Init 下的set_timezone
来配置系统时区 (Userdata — cloudbase-init 1.1.7 documentation)。 - NTP服务器:使用
ntp
配置NTP同步服务器 (Userdata — cloudbase-init 1.1.7 documentation) (Userdata — cloudbase-init 1.1.7 documentation)。 - 初始化脚本:除了 cloud-config 的 YAML,还可以在 user-data 中提供脚本形式的用户数据。例如以 Shell脚本(首行
#!/bin/bash
)或 PowerShell脚本(首行#ps1
)开始,Cloud-Init/Cloudbase-Init 会将其执行 (Userdata — cloudbase-init 1.1.7 documentation) (Userdata — cloudbase-init 1.1.7 documentation)。这对运行自定义命令非常有用。不过脚本和 cloud-config 二者只能择其一作为 user-data 内容,或使用 多部分用户数据 来同时提供(advanced用法)。
- 文件写入:使用
综上,运维人员可以根据需求,在 Cloud-Init 的配置文件中组合以上模块,实现对虚拟机初始化环境的全面定制。在编写配置时请遵循 YAML 语法,注意缩进和格式正确,并参考相关发行版的 Cloud-Init 文档获取支持的所有字段选项 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。
使用 libvirt/virt-install/virsh 挂载 Cloud-Init 配置盘
将编写好的 Cloud-Init 配置提供给 KVM 虚拟机的常用方法,是生成一个 种子ISO镜像(seed ISO) 或 配置驱动盘 并将其作为光驱或额外磁盘附加到虚拟机。下面介绍使用 libvirt 工具集(包括 virt-install
和 virsh
)实现这一过程的几种方式:
使用
cloud-localds
工具创建种子镜像:cloud-localds
是 Cloud-Init 提供的便捷工具,可以根据给定的 user-data 和 meta-data 文件生成合规的 ISO 镜像文件(卷标为cidata
,Cloud-Init 会自动识别此卷) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。首先确保安装了该工具(通常在包 cloud-utils 或 cloud-image-utils 中)。使用示例:# 安装cloud-localds (如未安装) sudo apt-get install -y cloud-image-utils # 生成seed ISO镜像 cloud-localds seed.iso user-data meta-data
上述命令将当前目录下的
user-data
和meta-data
文件打包进seed.iso
。cloud-localds
会自动添加必要的卷标和目录结构,使得生成的 ISO 符合 NoCloud 数据源要求 (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium)。若需要包括网络配置文件,可使用类似命令:cloud-localds seed.iso --network-config=network-config user-data meta-data
,或直接将 network-config 文件也作为参数提供(具体取决于 cloud-localds 版本)。生成的 ISO 可以认为是一个配置光盘。除了 cloud-localds,也可以使用通用的工具如 mkisofs/genisoimage 手动创建。例如:
genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
该命令与 cloud-localds 效果类似,
-volid cidata
指定卷名为 cidata (第 4 章 配置 cloud-init | Red Hat Product Documentation)。无论采用哪种方式,确保 ISO 内包含正确命名的user-data
和meta-data
文件(以及可选的network-config
)。在定义虚拟机时附加配置 ISO: 可以在 VM 创建或启动前,将上一步生成的
seed.iso
附加为光驱(CD-ROM)设备。使用 virt-install 创建虚拟机时,可以直接指定附加 ISO,例如:virt-install --name myvm --memory 2048 --vcpus 2 --cpu host \ --disk path=/var/lib/libvirt/images/myvm.qcow2,format=qcow2 \ --disk path=/path/to/seed.iso,device=cdrom,readonly=on \ --import --os-type linux --os-variant ubuntu20.04 \ --network network=default,model=virtio --graphics none
上述命令假设已有一个准备好的系统磁盘
myvm.qcow2
(例如从云镜像获取),使用--disk
第二次指定时附加了我们生成的 seed.iso 作为只读光驱。--import
选项表示直接导入现有镜像而不走安装流程。这样,虚拟机引导时会检测到附加的光盘,并由 cloud-init 将其中配置应用于系统。**注意:**需要保证虚拟机模板中已安装 Cloud-Init/Cloudbase-Init 服务,否则附加配置盘也不会被处理。如果使用 virsh 定义或编辑已存在的虚拟机,也可以通过修改XML添加光驱设备。例如,在域XML的
<devices>
下添加:<disk type='file' device='cdrom'> <driver name='qemu' type='raw'/> <source file='/path/to/seed.iso'/> <target dev='hdd' bus='ide'/> <readonly/> </disk>
这会将 seed.iso 作为IDE总线的光盘设备附加(许多云镜像预配置cloud-init会检查IDE光驱)。或者按照上一示例,也可用
<target dev='vdX' bus='virtio'/>
将其作为VirtIO磁盘附加 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)——Cloud-Init 同样能够在VirtIO磁盘上识别 cidata 卷。 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)附加后,使用virsh start myvm
启动虚拟机。**小提示:**如果使用 Virt-Manager 图形界面管理 KVM,也可以在“添加硬件”中选择添加光盘,指向 seed.iso 文件。
virt-install 的
--cloud-init
简化选项: 新版本的 virt-install 提供了--cloud-init
参数,可以自动生成并附加 NoCloud 配置盘,无需手动调用 cloud-localds (virt-install --cloud-init support | Cole Robinson)。例如:virt-install --name demo --memory 1024 --disk size=10,backing_store=cloudimg.qcow2 \ --cloud-init user-data=./user-data,meta-data=./meta-data
virt-install 将根据提供的 user-data/meta-data 内容自动创建临时 ISO,并在首次引导时使用 (virt-install --cloud-init support | Cole Robinson) (virt-install --cloud-init support | Cole Robinson)。还可以通过
--cloud-init ssh-key=<pubkey>
等子选项快速注入SSH密钥或指定自定义密码等 (virt-install --cloud-init support | Cole Robinson)。这个方法适合快速测试,但在不了解 virt-install 版本支持的情况下,手动生成 ISO 更通用。
无论采用上述哪种方式,成功附加配置盘后,Cloud-Init 在虚拟机 首次启动 时应该能够检测到 cidata 卷并加载其中的配置。Proxmox 等平台也是类似的原理:为启用 Cloud-Init 的VM自动创建并挂载一个ISO。 (Cloud-Init Support - Proxmox VE)
验证挂载: 如果希望确认配置盘内容是否被正确挂载,可在引导后的虚拟机内检查。例如Linux虚拟机中,可能会看到 /dev/sr0
(光驱)或 /dev/vdb
等设备作为 cidata 盘。可以尝试挂载该设备到某目录查看里面的 user-data
是否与预期一致。如果 Cloud-Init 正常执行,配置盘不需要人工挂载,Cloud-Init 已经读取并应用了配置。同时,Cloud-Init 会在日志(如 /var/log/cloud-init.log
)中记录数据源检测和应用的详情,可查阅以诊断问题。
示例:Cloud-Init 初始化 KVM 虚拟机的完整流程
本节通过一个具体示例演示如何使用 Cloud-Init 配置一个基于云镜像的 KVM 虚拟机,从准备配置文件到成功登录配置完成的系统。
**环境假设:**KVM 已安装并运行在宿主机上,宿主机已安装 libvirt
和相关工具(virt-install/virsh 等),网络使用 libvirt 默认的 NAT 网络。目标虚拟机操作系统为 Ubuntu Server 22.04 (Jammy) 云镜像。我们希望虚拟机启动后自动配置一个用户并通过SSH公钥登录。
步骤 1:下载云镜像 – 获取 Ubuntu 官方云镜像(QCOW2 格式):
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img -O ubuntu-22.04-cloudimg.qcow2
Ubuntu 提供了预装 Cloud-Init 的标准镜像。下载后得到 ubuntu-22.04-cloudimg.qcow2
。
步骤 2:准备虚拟机磁盘 – 基于下载的镜像创建虚拟机的磁盘映像文件。为了不破坏原始镜像,我们创建一个增量QCOW2(backing file):
qemu-img create -f qcow2 -b ubuntu-22.04-cloudimg.qcow2 -F qcow2 myvm.qcow2 10G
上述命令创建了一个名为 myvm.qcow2
的 10GB 增量磁盘,它以下载的 cloudimg 作为后端。 (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium)这样我们的虚拟机磁盘既包含基础系统,又有自己的写入空间,大小上限为10GB。(如果不熟悉增量盘,也可以简单地 cp
一份镜像文件并使用 qemu-img resize
调整大小)。
步骤 3:编写 Cloud-Init 配置文件 – 新建两个文件 user-data
和 meta-data
:
user-data
文件内容:#cloud-config hostname: example-vm ssh_pwauth: false users: - name: devops groups: sudo sudo: "ALL=(ALL) NOPASSWD:ALL" ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADA...example_key...
说明:将主机名设为 "example-vm",关闭SSH密码登录,仅创建用户 devops(属于sudo组)并注入预先指定的公钥(替换为你的实际公钥)。这里不设置密码,表示该用户仅能通过密钥认证登录,提高安全性。
meta-data
文件内容:instance-id: iid-12345 local-hostname: example-vm
说明:指定一个实例ID(任意唯一字符串即可)以及本地主机名,与 user-data 中的 hostname 保持一致。
确保这两个文件编码为纯文本UTF-8,无BOM,缩进正确。编写完成后,可以使用YAML工具验证 user-data 的格式无误。
步骤 4:生成 Cloud-Init 配置种子镜像(seed ISO) – 使用 cloud-localds
工具:
sudo apt-get install -y cloud-image-utils # 如果尚未安装
cloud-localds seed.iso user-data meta-data
执行后将在当前目录生成一个 seed.iso
文件 (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium)。这就是 NoCloud 数据源的镜像,里面包含我们刚才的 user-data 和 meta-data(可以使用 isoinfo -i seed.iso -R -l
检查其内容,应该能看到两个文件)。
提示:
cloud-localds
默认会给镜像设置卷标 cidata 并遵循 NoCloud 格式要求 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。如果没有 cloud-localds,可用genisoimage
命令替代,效果相同。
步骤 5:创建并启动虚拟机 – 使用 virt-install
基于已有磁盘和 seed.iso 创建虚拟机:
virt-install \
--name example-vm \
--ram 2048 --vcpus 2 --cpu host \
--disk path=./myvm.qcow2,format=qcow2 \
--disk path=./seed.iso,device=cdrom,readonly=on \
--import --os-variant ubuntu22.04 \
--network network=default,model=virtio \
--graphics none --console pty,target_type=serial
参数说明:
--name
指定虚拟机名称为 example-vm。--ram 2048 --vcpus 2
分配2GB内存和2个CPU。- 第一处
--disk
将我们准备的系统盘myvm.qcow2
加入虚拟机。 - 第二处
--disk
加入 seed.iso 作为光驱(只读)。 (Cloud-Init Support - Proxmox VE) --import
表示直接使用现有盘启动(而非通过ISO安装操作系统)。--os-variant
提供操作系统类型信息以优化配置(Ubuntu 22.04)。--network network=default
连接到默认虚拟网络(NAT)。--graphics none
禁用图形输出,--console pty,target_type=serial
启用一个tty控制台,方便查看输出(云镜像通常使用串行控制台)。
运行上述命令后,virt-install 会创建并启动虚拟机。如果未禁止控制台输出,终端可能会附着到虚拟机的串行控制台,您可以看到 Ubuntu 引导日志。Cloud-Init 在首次启动时会运行配置,此过程可能耗时数秒到几十秒。在日志中可以留意 Cloud-Init 的消息,例如 “Applying networking” 或 “Running modules for final” 等。
步骤 6:验证初始化结果 – 待虚拟机启动完成后,我们来验证 Cloud-Init 是否按预期工作:
尝试使用我们创建的用户通过 SSH 登录虚拟机。例如:
ssh devops@<宿主机IP> -p 2222
(如果在 virt-install 时未映射端口,可以改用 virsh 控制台或直接登录宿主机网络中 IP。上述命令假设做了 hostfwd 将2222端口转发到来宾22端口,如没有请调整登录方式。)
使用SSH公钥认证应能够直接登录而无需密码。如果成功登录,说明用户和SSH密钥注入生效。
登录后检查主机名:运行
hostname
应显示 example-vm,与配置一致。检查 Cloud-Init 日志:
sudo cat /var/log/cloud-init.log | grep -i "Finished"
,应该看到 cloud-init 完成各阶段的日志记录,没有错误。如有需要,可以Mount光驱查看内容:在虚拟机内执行:
sudo mount /dev/sr0 /mnt ls /mnt
预期应列出
user-data
和meta-data
文件 (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)。这进一步证明我们的配置盘已成功挂载并可被读取(Cloud-Init 已经自动读取过了)。
如果以上验证都通过,那么恭喜您,Cloud-Init 已成功为虚拟机应用初始化配置!以后对于批量部署多个类似虚拟机,只需准备不同的 user-data/meta-data(比如修改主机名、用户密钥等),即可重复这一流程快速创建。
至此,我们完成了在 KVM 环境下使用 Cloud-Init 初始化虚拟机的全过程。从编写配置文件到挂载 seed ISO,再到虚拟机引导应用配置,每一步都至关重要。在实际运维中,建议妥善保存常用的 Cloud-Init 配置模板,根据不同操作系统调整细节(例如 Windows 需安装 Cloudbase-Init 且密码明文等差异 (Userdata — cloudbase-init 1.1.7 documentation)),并在部署前进行测试验证。
通过 Cloud-Init 的自动化初始化,可以极大提高批量部署虚拟机的效率和一致性,为后续配置管理打下良好基础 (Cloud-Init Support - Proxmox VE)。有关 Cloud-Init 更详细的配置选项和高级用法,可参考官方文档和各发行版的说明 (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)。希望本指南能帮助您顺利地在 KVM 中运用 Cloud-Init 完成虚拟机初始化配置。 (完)
参考资料:
- Arian Fm, “Create VM with cloud image and cloud-init (QEMU/KVM)”, Medium, 2025 (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium) (create a virtual machine with cloud image and cloud-init config using qemu/kvm | by Arian Fm | Feb, 2025 | Medium)
- Amazon AWS 文档, “NoCloud seed.iso 配置 (KVM)” (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023) (NoCloud (seed.iso) cloud-init configuration for Amazon Linux 2023 on KVM and VMware - Amazon Linux 2023)
- Red Hat 文档, “为 NoCloud 数据源创建包含 cloud-init 的虚拟机” (第 4 章 配置 cloud-init | Red Hat Product Documentation) (第 4 章 配置 cloud-init | Red Hat Product Documentation)
- Cloudbase-Init 官方文档, “Userdata - Cloud config on Windows” (Userdata — cloudbase-init 1.1.7 documentation) (Userdata — cloudbase-init 1.1.7 documentation)
- 腾讯云社区, “在本地KVM中安装使用Cloud-Init” (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云) (在本地KVM中安装使用Cloud-init-腾讯云开发者社区-腾讯云)
- Proxmox Wiki, “Cloud-Init Support”
评论区