“硬盘加上去了,UUID 抄错了,机器起不来……”
如果你在使用 Proxmox VE 虚拟机模板时,曾通过手动修改 /etc/fstab 来挂载第二块硬盘,很可能踩过这个坑。今天,我们将通过配置 cloud-init,将“加盘→分区→格式化→挂载”的流程自动化,实现克隆100台虚拟机也能0失误。
一、cloud-init 能帮我们干多少活?
- 自动扩容第一分区(系统盘)。
- 自动识别第二块空盘,完成格式化并挂载到指定目录(如
/data)。
- 若目标硬盘已存在分区或文件系统,则自动跳过,避免误伤数据。
- 全程无需重启,克隆开机后数秒内即可完成。
二、PVE 端:为模板挂载“第二块空盘”
- 选中模板虚拟机,进入“硬件”选项卡,点击“添加”选择“SCSI 存储”。
- 设置容量(例如 50G),建议勾选“SSD仿真”与“Discard”。
- 在总线/设备位置中,务必选择
scsi1,以确保系统识别为 /dev/sdb(后续脚本配置会更省心)。
- 关键步骤:在将虚拟机转为模板前,务必“分离” Cloud-Init 驱动(CD-ROM),否则在克隆时会生成重复的驱动器。
三、编写 user-data:用 mounts 和 bootcmd 指令搞定
将以下配置粘贴到 PVE 中对应虚拟机的 “Cloud-Init” → “自定义 user-data” 字段,或存放在 /snippets/ 目录下。
#cloud-config
mounts:
# 格式:[ 设备, 挂载点, 文件系统, 挂载选项, dump备份频率, fsck检查顺序 ]
- ["/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2-part1", "/data", "ext4", "defaults,nofail,discard", "0", "2"]
bootcmd:
# 如果磁盘未被分区,则创建GPT分区表并格式化整个磁盘为ext4
- |
test -e /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2 || exit 0
test -e /data && exit 0
parted -s /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2 mklabel gpt mkpart primary ext4 0% 100%
while [ ! -e /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2-part1 ]; do sleep 0.5; done
mkfs -t ext4 -F /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2-part1
mkdir -p /data
此配置实现了运维自动化的典型场景:bootcmd 模块在启动早期执行,负责创建分区和文件系统;mounts 模块随后将格式化好的分区挂载到 /data 目录,适合作为应用数据或数据库存储的挂载点。
四、如何解决盘符漂移问题?
切勿在配置中使用 /dev/sdb1 这类易变的设备名。应使用 /dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2-part1 这种基于唯一ID的路径。
在 Proxmox VE 环境中,SCSI 磁盘的固定序列号默认为 “QEMU HARDDISK”,因此总线位置 scsi1 对应的ID后缀永远是 2,即使经过克隆也不会改变。
五、NoCloud 与 ConfigDrive 数据源差异(PVE 相关)
PVE 7.0+ 版本默认使用 NoCloud 数据源,Cloud-Init 的配置 ISO 会被挂载到 /dev/sr0。
cloud-init 服务启动时会按顺序查找可用的数据源:NoCloud → ConfigDrive → OpenStack → ……
因此,你只需将 user-data 直接写入 PVE 的 Cloud-Init 驱动设置中即可,无需手动更改虚拟机内的数据源配置。
六、如何立即生效,无需重启?
克隆后的虚拟机在首次开机时,cloud-init 会自动运行。
如果你想在已启动的模板虚拟机中立即测试配置效果,可以执行以下命令:
sudo cloud-init clean # 清理 cloud-init 缓存
sudo cloud-init init --local # 仅本地运行 bootcmd、mounts 等模块
mount | grep /data # 查看 /data 是否已挂载为 ext4 文件系统
七、完整克隆脚本示例(可与 Ansible 结合)
以下是一个 Ansible playbook 任务示例,用于从模板克隆并自动创建带第二块硬盘的虚拟机:
- name: 创建带第二块数据盘的 Ubuntu 22.04 主机
community.general.proxmox_kvm:
node: pve1
vmid: "{{ item }}"
name: "web-{{ item }}"
clone: ubuntu2204-template
full: true
scsi:
scsi1: local-lvm:50,ssd=1,discard=on
ciuser: ubuntu
cipassword: Passw0rd
searchdomains: example.com
nameserver: 8.8.8.8
sshkeys: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
# user-data 已在模板中配置,克隆后即刻生效
八、常见报错排查
| 错误信息 |
可能原因与解决方案 |
Device scsi-0QEMU_QEMU_HARDDISK_2 not found |
模板未挂载 scsi1 硬盘,或克隆时总线号发生变更。检查虚拟机硬件配置。 |
mount: /data: wrong fs type |
bootcmd 模块未执行完成,ext4 文件系统未创建成功。检查 /var/log/cloud-init.log 日志。 |
重启后 /data 目录为空或丢失 |
配置中使用了 /dev/sdb1 导致盘符漂移。必须更换为 /dev/disk/by-id/ 下的持久化设备名。 |