跳转到内容

Debian / Ubuntu 云镜像模板 ​

装一遍 Debian、点几十次「下一步」,和用官方 Cloud 镜像导入一块磁盘、配上 Cloud-Init,两者最后得到的系统差不多,但后者建好模板后每次开新机只要几秒钟,还不用回答任何安装问题。这篇讲怎么把模板做出来。

适合谁 ​

你的情况适不适合
经常要开新的 Debian/Ubuntu 测试机或服务非常适合,一次投入,之后反复受益
只装一台,装完不会再要第二台用创建第一个虚拟机的 ISO 安装流程更直接
需要图形界面桌面版官方 Cloud 镜像通常是精简的服务器版,不适合

和「Cloud-Init 快速部署」的分工

本文只讲怎么把 Cloud 镜像导入成一个可克隆的模板。Cloud-Init 本身能配置的内容(用户、SSH 密钥、网络、自定义脚本)见 Cloud-Init:十秒钟开一台配好的虚拟机。两篇配合着看。

资源规划 ​

项建议起点
vCPU1–2,克隆出来的虚拟机可以再调
内存1–2 GB
磁盘官方 Cloud 镜像通常只有几百 MB,导入后按需 qm resize 扩容

模板本身不需要预留太多资源——它不会被开机运行,资源规划是给克隆出来的虚拟机做的。

创建与安装 ​

第一步:获取官方 Cloud 镜像 ​

在宿主机 shell下载。用 qcow2 格式的 generic cloud 镜像(不是安装用的 ISO):

sh
# 在宿主机执行,以下版本号仅为示例,用官网当前发布的最新版链接替换
# Debian(官网:https://cloud.debian.org/images/cloud/)
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2

# Ubuntu(官网:https://cloud-images.ubuntu.com/)
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

版本号自己去官网确认

Debian 和 Ubuntu 的代号、版本号会随时间推进(例如 Debian 13 Trixie、Ubuntu 后续 LTS)。上面命令里的路径和文件名仅作示例,下载前去对应官网确认当前的目录结构和最新版本,不要照抄旧教程里写死的版本号。

第二步:建一个空壳虚拟机 ​

不通过创建向导,直接用命令行建一个只有基础配置、没有磁盘的虚拟机(<vmid> 建议用一个专门的号段区分模板,比如 9000):

sh
# 在宿主机执行
qm create <vmid> --name debian-12-cloud-template --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 --cpu host --machine q35 --bios ovmf --scsihw virtio-scsi-single

如果用了 --bios ovmf,PVE 会提示需要一块 EFI 磁盘:

sh
# 在宿主机执行,<storage> 换成你的存储名,例如 local-lvm
qm set <vmid> --efidisk0 <storage>:0,efitype=4m,pre-enrolled-keys=0

用 UEFI 还是 SeaBIOS

Cloud 镜像两种都支持。不确定就用 SeaBIOS(省掉 EFI 磁盘这一步),除非你有明确理由要 UEFI(比如未来要直通设备)。BIOS/Machine 选项装完不要再改,理由见创建第一个虚拟机。

第三步:导入磁盘并挂上 ​

sh
# 在宿主机执行,<storage> 换成目标存储名
qm importdisk <vmid> debian-12-genericcloud-amd64.qcow2 <storage>

# 挂到 scsi0
qm set <vmid> --scsi0 <storage>:vm-<vmid>-disk-0

# 设置启动顺序
qm set <vmid> --boot order=scsi0

Ubuntu 的旧文档提到 virtio-scsi-pci

早期教程用的是 virtio-scsi-pci 控制器。本站沿用创建第一个虚拟机里推荐的 virtio-scsi-single,对 Cloud 镜像同样适用,性能更好。

第四步:加上 Cloud-Init 磁盘和串口控制台 ​

sh
# 在宿主机执行
qm set <vmid> --ide2 <storage>:cloudinit
qm set <vmid> --serial0 socket --vga serial0
qm set <vmid> --agent enabled=1

--serial0 socket --vga serial0 让你在没有配置静态 IP 之前也能通过 PVE 的 Console 看到系统的串口输出,排查首次启动问题时很有用。

第五步:转成模板 ​

sh
# 在宿主机执行
qm template <vmid>

转换后这台「虚拟机」不能再开机,只能被克隆,机制和普通模板一样,见快照、克隆与模板。

第一次启动之后 ​

模板本身不开机,验证要通过克隆一台实例来做:

sh
# 在宿主机执行,<newid> 换成新虚拟机编号
qm clone <vmid> <newid> --name debian-test-01 --full

# 配置 Cloud-Init:账号、密钥、网络
qm set <newid> --ciuser debian --sshkeys ~/.ssh/id_rsa.pub --ipconfig0 ip=dhcp

# 开机
qm start <newid>

首次启动时 cloud-init 会在系统内部完成账号创建、SSH 密钥写入、网络配置和磁盘分区扩容(把 qcow2 里几百 MB 的文件系统扩到你实际分配的磁盘大小,仅限第一次启动生效)。完整的 Cloud-Init 参数说明见 Cloud-Init:十秒钟开一台配好的虚拟机。

检查结果 ​

  1. qm status <newid> 显示 running。
  2. PVE Console 或 qm agent <newid> network-get-interfaces 能看到分配到的 IP(前提是装了 agent,Cloud 镜像通常默认已带 qemu-guest-agent,用下面的命令确认)。
  3. ssh debian@<ip> 能用密钥直接登录,不需要密码。
  4. df -h 里根分区大小等于你分配的磁盘容量,说明 cloud-init 的扩容生效了。
  5. 再克隆一台,改个名字和 IP,两台互不冲突——证明模板可以稳定复用。

在克隆出来的虚拟机内部确认 guest agent 状态:

sh
# 在虚拟机内部执行
systemctl status qemu-guest-agent

备份与维护 ​

模板本身不需要单独纳入 vzdump 备份——它不包含运行时数据,重新走一遍导入流程就能再生成一份。真正需要备份的是克隆出来、装了实际业务的虚拟机。

模板要定期更新

Cloud 镜像下载下来之后系统版本就固定了。定期(比如每季度)重新走一遍导入流程,或者克隆一台出来手动 apt full-upgrade 后再转回模板,避免每次克隆出来的都是一堆待更新的旧系统。

常见问题 ​

克隆出来的虚拟机启动很慢,卡在启动界面。 检查是不是忘了加 --ide2 <storage>:cloudinit;没有这块盘,cloud-init 会因为找不到配置数据源而等待超时。

SSH 连不上,密码登录也不行。 Cloud 镜像默认不允许密码登录 root,且很多镜像默认没设密码。用 --sshkeys 指定公钥是标准做法,不要指望密码登录。

磁盘没有按预期扩容。 扩容只在 cloud-init 第一次启动时执行。虚拟机已经跑起来之后再改磁盘大小,需要手动在客户机内部用 growpart/resize2fs 处理,或者从模板重新克隆一台。

qm importdisk 报错找不到命令,或者行为和教程不一致。 不同 PVE 版本这个命令的语法有细微差异(比如新版本支持在 qm create 里直接指定 import-from),以你的版本 qm importdisk --help 输出为准。

参考资料 ​

Proxmox VE 非官方中文使用指南,与 Proxmox Server Solutions GmbH 无隶属关系。