找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

280

积分

0

好友

40

主题
发表于 昨天 02:37 | 查看: 5| 回复: 0

“硬盘加上去了,UUID 抄错了,机器起不来……”

如果你在使用 Proxmox VE 虚拟机模板时,曾通过手动修改 /etc/fstab 来挂载第二块硬盘,很可能踩过这个坑。今天,我们将通过配置 cloud-init,将“加盘→分区→格式化→挂载”的流程自动化,实现克隆100台虚拟机也能0失误。

一、cloud-init 能帮我们干多少活?

  1. 自动扩容第一分区(系统盘)。
  2. 自动识别第二块空盘,完成格式化并挂载到指定目录(如 /data)。
  3. 若目标硬盘已存在分区或文件系统,则自动跳过,避免误伤数据。
  4. 全程无需重启,克隆开机后数秒内即可完成。

二、PVE 端:为模板挂载“第二块空盘”

  1. 选中模板虚拟机,进入“硬件”选项卡,点击“添加”选择“SCSI 存储”。
  2. 设置容量(例如 50G),建议勾选“SSD仿真”与“Discard”。
  3. 在总线/设备位置中,务必选择 scsi1,以确保系统识别为 /dev/sdb(后续脚本配置会更省心)。
  4. 关键步骤:在将虚拟机转为模板前,务必“分离” Cloud-Init 驱动(CD-ROM),否则在克隆时会生成重复的驱动器。

三、编写 user-data:用 mountsbootcmd 指令搞定

将以下配置粘贴到 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/ 下的持久化设备名。
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-3 15:27 , Processed in 0.059227 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表