Proxmox VE 虚拟机创建与 Ubuntu 26.04 无人值守安装实战笔记
Proxmox VE 虚拟机创建与 Ubuntu 26.04 无人值守安装实战笔记
在日常的服务器运维工作中,虚拟机的创建与系统安装是最基础也是最频繁的操作之一。传统的通过 VNC 或 IPMI 进行交互式安装虽然直观,但效率低下,特别是在需要批量部署多台服务器时。本文将详细介绍如何利用 Proxmox VE(以下简称 PVE)平台,结合 Cloud-init 技术,实现 Ubuntu 26.04 Server 版本的无人值守自动化安装。
背景与需求
作为一名运维工程师,我需要经常在测试环境中快速创建虚拟机。每次通过 VNC 进行交互式安装不仅耗时,而且容易因为人工操作失误导致配置不一致。因此,我一直希望能够实现一套标准化的虚拟机创建与系统安装流程:
- 标准化:所有虚拟机使用统一的配置模板
- 自动化:从创建到安装全程无需人工干预
- 可重复:可以快速创建任意数量的虚拟机
- 可追溯:每次创建都有记录可查
本文将完整记录这一次的实践过程,包括遇到的问题以及最终的解决方案。
环境概述
本次操作的环境是一台运行在局域网内的 Proxmox VE 9.0 虚拟化服务器。关键配置信息如下:
- 虚拟化平台:Proxmox VE 9.0
- 存储类型:LVM-thin(本地 SSD 存储)
- 网络模式:桥接模式(bridge vmbr0)
- ISO 存储:CIFS 共享存储(用于存放系统镜像)
- 目标系统:Ubuntu 26.04 LTS Server
说明:本文所有涉及 IP 地址、主机名等敏感信息均已脱敏处理,仅保留技术细节供读者参考。
方案选型
在开始之前,我评估了三种常见的自动化安装方案:
方案一:使用 PVE 自带的 Cloud-init
优点:
- PVE 原生支持,与虚拟机配置深度集成
- 支持自定义用户名、密码、网络配置等
- 可以配合 AutoYAML 实现完整的无人值守安装
缺点:
- 需要额外创建 Cloud-init 数据卷
- 配置相对复杂,需要理解 Cloud-init 的数据结构
方案二:使用 Terraform + PVE Provider
优点:
- 可以实现基础设施即代码(IaC)
- 支持大规模批量部署
- 版本控制友好
缺点:
- 需要额外安装和配置 Terraform
- 学习曲线较陡,适合大规模运维场景
方案三:使用 PXE 网络启动
优点:
- 无需额外介质,自动化程度高
- 适合大规模批量装机
缺点:
- 需要配置 PXE 服务器
- 在当前环境下网络配置较复杂
综合考虑项目的实际需求和技术栈,最终选择了方案一:利用 PVE 原生的 Cloud-init 功能结合 Ubuntu 的 autoinstall 技术实现无人值守安装。
实施步骤
第一步:准备 Ubuntu 26.04 安装镜像
首先需要获取 Ubuntu 26.04 Server 版本的安装镜像。Ubuntu 26.04 是即将发布的 LTS 版本(本文撰写时仍在开发中),其服务器版本提供了完整的 autoinstall 支持。
# 检查 PVE 存储上的 ISO 目录
ls -la /mnt/pve/dsm10-iso/template/iso/ | grep ubuntu
常见的 ISO 文件命名格式为:
ubuntu-26.04-live-server-amd64.iso— 桌面版(带 GUI)ubuntu-26.04-live-server-amd64.iso— 服务器版(本文使用)
将下载好的 ISO 文件上传到 PVE 的 ISO 存储目录后,就可以开始创建虚拟机了。
第二步:创建虚拟机
在 PVE 上创建虚拟机有两种方式:通过 Web UI 或通过命令行。对于需要批量操作或编写脚本的场景,命令行是更高效的选择。
首先,我们来看看参考虚拟机(VM 4519)的配置:
# 查看参考虚拟机的配置
qm config 4519
关键配置项包括:
| 配置项 | 值 | 说明 |
|---|---|---|
ostype |
l26 |
Linux 内核版本 2.6+ |
bios |
ovmf |
UEFI 启动 |
cores |
2 |
CPU 核心数 |
cpu |
x86-64-v2-AES |
CPU 类型 |
memory |
4096 |
内存大小(MB) |
scsi0 |
local-lvm:vm-4519-disk-1,size=20G |
主磁盘 |
efidisk0 |
local-lvm:vm-4519-disk-0,size=4M |
EFI 分区 |
sata0 |
local-lvm:vm-4519-cloudinit |
Cloud-init 卷 |
net0 |
virtio=xx:xx:xx:xx:xx:xx,bridge=vmbr0 |
网络配置 |
由于 PVE 的 qm create 命令在创建虚拟机时无法直接指定需要关联的磁盘卷(需要先存在),一个取巧的方法是使用 qm clone 命令从已有的虚拟机克隆。
# 克隆参考虚拟机
qm clone 4519 4526 --name "VM-Ubuntu26.04-20G" --full
这条命令会:
- 创建新的虚拟机 ID(4526)
- 克隆所有磁盘(EFI 磁盘、系统磁盘、Cloud-init 卷)
- 复制基础配置(CPU、内存、网络等)
克隆完成后,修改虚拟机配置以适配新的需求:
# 修改虚拟机名称和标签
qm set 4526 --name "VM-Ubuntu26.04-20G" --tags ubuntu26.04
# 配置 Cloud-init 用户(用户名)
qm set 4526 --ciuser margrop
# 配置 Cloud-init 密码(密码:xc112vm)
qm set 4526 --cipassword xc112vm
# 挂载 Ubuntu 26.04 ISO 作为安装介质
qm set 4526 --ide2 /mnt/pve/dsm10-iso/template/iso/ubuntu-26.04-live-server-amd64.iso,media=cdrom
# 设置启动顺序:先从 ISO 启动安装,安装完成后从磁盘启动
qm set 4526 --boot order="ide2;scsi0"
注意:克隆的虚拟机会复制原虚拟机的所有磁盘内容。如果原虚拟机已经安装了操作系统,克隆后磁盘上仍然是原系统的数据。对于全新安装,需要确保克隆的是空白系统或使用其他方式创建空白磁盘。
第三步:配置 Cloud-init 无人值守安装
Ubuntu Server 20.04 及更高版本支持通过 autoinstall 技术实现完全自动化的系统安装。配合 Cloud-init,可以实现:
- 自动配置用户名和密码
- 自动配置网络(DHCP 或静态 IP)
- 自动分区和 LVM 配置
- 自动安装指定软件包
- 自动执行安装后配置脚本
首先创建 Cloud-init 配置文件。Cloud-init 使用 YAML 格式,主要包括 user-data(用户配置)和 meta-data(实例元数据)两个文件。
user-data 文件配置示例:
#cloud-config
autoinstall:
version: 1
identity:
hostname: ubuntu
username: margrop
password: $6$v/wBNKhSNqXsLSTw$6V6Um5Jot07v2LJGyRtFHlqDYgzzbQGn9...
ssh:
install-server: true
allow-pw: true
storage:
layout:
name: lvm
guipart: use-existing
packages:
- openssh-server
- qemu-guest-agent
- vim
- net-tools
- curl
- wget
late-commands:
- systemctl enable qemu-guest-agent
配置项说明:
| 配置项 | 说明 |
|---|---|
identity.hostname |
系统主机名 |
identity.username |
初始用户名 |
identity.password |
用户密码(SHA-512 加密) |
ssh.install-server |
是否安装 SSH 服务器 |
ssh.allow-pw |
是否允许密码登录 |
storage.layout.name |
分区布局方案,lvm 表示使用 LVM |
packages |
额外需要安装的软件包列表 |
late-commands |
安装完成后执行的命令 |
生成加密密码的方法:
# 使用 openssl 生成 SHA-512 加密密码
openssl passwd -6 xc112vm
meta-data 文件配置:
instance-id: ubuntu26-4526
local-hostname: ubuntu
第四步:创建 Cloud-init ISO
Cloud-init 需要通过 ISO 介质传递给安装程序。ISO 文件必须满足以下条件:
- 卷标(Volume Label) 必须为
CIDATA - 包含
user-data和meta-data两个文件 - 文件系统格式为 ISO9660(Rock Ridge 扩展)或 Joliet
在 macOS 或 Linux 上创建 Cloud-init ISO 的方法:
方法一:使用 genisoimage(推荐)
# 在 PVE 或 Linux 服务器上执行
genisoimage -o cloudinit-4526.iso \
-V CIDATA \
-J \
-r \
/path/to/cloud-init-files/
方法二:使用 hdiutil(macOS)
cd /path/to/cloud-init-files
hdiutil makehybrid -o autoinstall.iso . -iso -joliet
创建完成后,将 ISO 上传到 PVE 的存储中:
# 上传到 PVE
scp cloudinit-4526.iso root@<PVE-IP>:/mnt/pve/dsm10-iso/template/iso/
第五步:配置虚拟机启动并执行安装
将 Cloud-init ISO 添加为虚拟机的第二光驱,并调整启动顺序:
# 添加 Cloud-init ISO 作为第二光驱(ide3)
qm set 4526 --ide3 /mnt/pve/dsm10-iso/template/iso/cloudinit-4526.iso,media=cdrom
# 设置启动顺序:ISO -> Cloud-init -> 磁盘
qm set 4526 --boot order="ide2;ide3;scsi0"
# 启动虚拟机
qm start 4526
启动后,Ubuntu 安装程序会自动检测到 CIDATA 卷并执行无人值守安装。整个过程无需人工干预,大约需要 5-15 分钟(取决于网络速度和硬件配置)。
常见问题与解决方案
问题一:克隆后磁盘空间不足
错误信息:
Volume group "pve" has insufficient free space
原因:PVE 使用 LVM-thin 存储池,克隆时需要分配新的逻辑卷。如果存储池空间不足,会导致创建失败。
解决方案:
-
清理不再使用的虚拟机和旧快照
# 删除不需要的虚拟机 qm destroy <vmid> # 删除旧快照 qm delsnapshot <vmid> <snapshot-name> -
扩展 LVM-thin 存储池
# 添加新的物理卷 pvcreate /dev/sdX # 扩展卷组 vgextend pve /dev/sdX # 扩展逻辑卷 lvextend -L +XXXG /dev/pve/data -
考虑使用精简置备(Thin Provision)模式
问题二:Cloud-init ISO 未被识别
错误现象:虚拟机从 ISO 启动后,仍然显示交互式安装界面。
原因:
- ISO 卷标不是
CIDATA - 文件结构不正确
- 启动顺序设置错误
解决方案:
-
验证 ISO 卷标
# Linux/PVE volid /dev/srX # macOS diskutil info /dev/diskX | grep "Volume Name" -
检查 ISO 内容结构
# 挂载 ISO 并查看 mount -o loop cloudinit.iso /mnt ls -la /mnt -
确保启动顺序正确
qm set <vmid> --boot order="ide2;ide3;scsi0"
问题三:安装完成后无法 SSH 登录
错误现象:安装过程正常,但安装完成后无法通过 SSH 连接虚拟机。
可能原因:
- SSH 服务未安装或未启动
- 防火墙阻止了 SSH 连接
- 网络配置错误(获取不到 IP)
- 密码配置不正确(加密格式问题)
解决方案:
-
在 Cloud-init 配置中确保安装了 openssh-server
packages: - openssh-server ssh: install-server: true allow-pw: true -
检查虚拟机控制台日志
# 查看虚拟机启动日志 qm terminal <vmid> -
验证 Cloud-init 配置中的密码格式
# 重新生成正确格式的密码 openssl passwd -6 <password>
自动化脚本封装
为了方便日后快速创建虚拟机,我将整个流程封装成了一个脚本:
#!/bin/bash
# create_vm.sh - PVE 虚拟机快速创建脚本
set -e
VM_ID=${1:-}
VM_NAME=${2:-}
ISO_PATH=${3:-}
USER_NAME=${4:-}
USER_PASS=${5:-}
if [ -z "$VM_ID" ] || [ -z "$VM_NAME" ] || [ -z "$ISO_PATH" ]; then
echo "Usage: $0 <vm-id> <vm-name> <iso-path> [user] [password]"
exit 1
fi
USER_NAME=${USER_NAME:-margrop}
USER_PASS=${USER_PASS:-xc112vm}
# 克隆参考虚拟机(需要先创建并配置参考机)
qm clone 4519 ${VM_ID} --name "${VM_NAME}" --full
# 配置虚拟机
qm set ${VM_ID} --ciuser ${USER_NAME}
qm set ${VM_ID} --cipassword ${USER_PASS}
qm set ${VM_ID} --ide2 ${ISO_PATH},media=cdrom
qm set ${VM_ID} --boot order="ide2;scsi0"
# 创建 Cloud-init ISO
# ...(Cloud-init 配置生成代码)
# 启动虚拟机
qm start ${VM_ID}
echo "VM ${VM_ID} created and started successfully!"
使用示例:
./create_vm.sh 4527 "VM-Ubuntu26.04-Test" \
/mnt/pve/dsm10-iso/template/iso/ubuntu-26.04-live-server-amd64.iso \
margrop xc112vm
总结与展望
通过本文的实践,我们成功实现了在 Proxmox VE 平台上创建虚拟机并自动化安装 Ubuntu 26.04 Server 的完整流程。主要收获包括:
-
理解了 PVE 虚拟机的创建机制:通过命令行可以更灵活地控制虚拟机创建的各个环节
-
掌握了 Cloud-init 与 autoinstall 的配合使用:这是 Ubuntu 实现无人值守安装的核心技术
-
学会了常见问题的排查方法:包括存储空间不足、ISO 识别问题等
未来可以进一步优化的地方:
- 集成 Terraform 实现基础设施即代码
- 搭建 PXE 网络启动环境,支持无介质装机
- 建立虚拟机模板库,进一步提高部署效率
- 集成 Ansible 实现配置管理的自动化
希望本文对有类似需求的运维工程师们有所帮助。如果有任何问题或建议,欢迎在评论区交流讨论。
参考资料
- Ubuntu Autoinstall Documentation
- Cloud-init Documentation
- Proxmox VE QEMU/Guest Agent
- Ubuntu 26.04 Release Schedule
本文首发于 2026-04-25