Skip to content

PVE 9.0 定制 Debian 13 镜像 支持 Cloud-Init 快速部署虚拟机【模板篇】

前言

经常买 VPS 的肯定都有这种体会:在商家的面板里装系统往往只需要几分钟,而且商家提供的系统模板中还预装了很多常用的工具。

但在本地安装系统时,先不说安装完成后还得手动更换软件源、调整时区、安装常用工具,就连安装过程各种设置选下来,整个过程起码也得花费几十分钟。

实际上,在 PVE 中安装 Debian 并不需要下载 3.7G 的 ISO 镜像,在官方的下载页面就可以看到,完整安装镜像包含了所有桌面环境的套件,但 PVE 中的虚拟机并不需要这些套件,右下角的“云镜像”反而更加合适,直接将下载好的 qcow2 镜像导入,就可以开机,没有复杂的安装过程。

Debian 云镜像
Debian 云镜像

定制镜像

提示

如果你没有条件定制镜像,可以直接下载我定制的 Debian 镜像:夸克网盘 / UC 网盘


或者也可以手动定制,下面导入镜像时导入官方的 qcow2 镜像,在转换为模板前直接启动虚拟机进行手动操作。

使用 virt-customize 自动化定制参考了 Sukka 大佬的文章,如果想要深入了解的可以去看看原文

在“云镜像”的介绍界面,可以看到云镜像分为了 azureec2genericgenericcloudnocloud,这么多镜像我们到底应该选择哪个呢?

首先排除前两个 Amazon EC2 和 Microsoft Azure 的镜像,然后就是最后的 nocloud 不支持 Cloud-Init 也可以排除了。

那么最后就剩下 genericgenericcloud,在 Sukka 大佬的文章中推荐的是更加适合虚拟机的 genericcloud 镜像,但我实际测试下来发现这个镜像有些过于精简了,不包含 USB 相关内核模块,如果你有直通 USB 连接打印机、移动硬盘的需求,建议使用 generic 镜像,更加适合家庭用户

generic 镜像
generic 镜像

选择好了合适的镜像后,我们接着用 libguestfs-tools 来自动化定制镜像,这一过程建议使用国外的 VPS 来操作,避免网络原因造成定制失败,内存的话最好在 4G 以上。

sh
apt install libguestfs-tools

下载官方原版的 qcow2 镜像

sh
wget -c https://cdimage.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2

下面是我定制 Debian 13 镜像用到的命令,主要是为了让这个镜像更加适合国内宝宝体质。

危险

安装软件包时要注意避免冲突。我一开始不小心装了 ifupdown,结果和 systemd-networkd 冲突,导致虚拟机开机一直获取不到 DNS。

通过 resolvectl status 可以查看当前实际生效的 DNS,正常情况下如果 IPv4 是 DHCP 的会获取到 DHCP 分配的 DNS,如果 IPv4 是静态 IP,则可以在 Cloud-Init 中设置 DNS。

提示

在PVE 中使用的虚拟机,强烈建议安装上 qemu-guest-agent

sh
virt-customize -a debian-13-generic-amd64.qcow2 \
  --smp 2 --verbose \
  --timezone "Asia/Shanghai" \
  --append-line "/etc/default/grub:# disables OS prober to avoid loopback detection which breaks booting" \
  --append-line "/etc/default/grub:GRUB_DISABLE_OS_PROBER=true" \
  --run-command "update-grub" \
  --run-command "sed -i 's|Types: deb deb-src|Types: deb|g' /etc/apt/sources.list.d/debian.sources" \
  --run-command "sed -i 's|generate_mirrorlists: true|generate_mirrorlists: false|g' /etc/cloud/cloud.cfg.d/01_debian_cloud.cfg" \
  --update --install "wget,curl,nano,vim,sudo,unzip,mtr-tiny,iputils-ping,bind9-host,dnsutils,net-tools,lsb-release,ca-certificates,bash-completion,fail2ban,dialog,netbase,iproute2,whois,ssh,dbus,systemd,systemd-sysv,locales,apt-utils,gnupg2,apt-transport-https,rsyslog,logrotate,less,rsync,qemu-guest-agent,haveged,systemd-timesyncd" \
  --run-command "apt-get -y autoremove --purge && apt-get -y clean" \
  --run-command "sed -i 's/^#\?\s*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config && sed -i 's/^#\?\s*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config" \
  --append-line "/etc/systemd/timesyncd.conf:NTP=ntp.aliyun.com" \
  --delete "/var/log/*.log" \
  --delete "/var/lib/apt/lists/*" \
  --delete "/var/cache/apt/*" \
  --truncate "/etc/apt/mirrors/debian.list" \
  --append-line "/etc/apt/mirrors/debian.list:https://mirrors.tuna.tsinghua.edu.cn/debian" \
  --truncate "/etc/apt/mirrors/debian-security.list" \
  --append-line "/etc/apt/mirrors/debian-security.list:https://mirrors.tuna.tsinghua.edu.cn/debian-security" \
  --truncate "/etc/machine-id"

具体做了这些操作:

类别功能
基础指定镜像、多核执行
时区设置为上海
引导禁止 OS prober
系统更新包、安装常用工具
SSH启用 root 登录和密码认证
网络设置阿里云 NTP
APT改用清华源、禁用源码仓库
Cloud-Init禁止自动生成镜像源
清理删除日志和缓存
唯一性清空 machine-id 以防冲突

最后再把刚才定制好的镜像压缩一下就大功告成了。

sh
virt-sparsify --compress debian-13-generic-amd64.qcow2 debian-13-generic-amd64-zc.qcow2

制作模板

这一步是将刚才定制好的 qcow2 导入 PVE 中并创建成虚拟机模板,其中大部分操作都可以在 PVE 的网页中完成

创建虚拟机

由于创建的虚拟机后面是转换为模板使用,因此 VM ID 可以填的大一些,与正在运行的虚拟机区分开。

常规
常规

操作系统后面会直接导入 qcow2,所以这里选择“不使用任何介质”

操作系统
操作系统

机型可以选择 “q35”,BIOS 选择 “OVMF (UEFI)”,最重要的是勾选 “Qemu 代理”,可以和虚拟机内安装的 qemu-guest-agent 交互。

系统
系统

刚才定制的 qcow2 本质上就是一个磁盘文件,后面直接导入就是系统盘,因此这里不需要单独添加磁盘,将其删除就好。

磁盘
磁盘

创建的这个虚拟机会转换为模板使用,接下来的 CPU 和内存设置选择低配即可,从模板克隆虚拟机的时候再根据实际需求修改。

CPU
CPU
内存
内存

在内网使用 PVE,可以去掉勾选“防火墙”,方便操作。

网络
网络

这样就创建好了虚拟机,但此时还无法使用,还得导入镜像并且添加上必要的硬件。

导入镜像

网页上不支持导入镜像,因此这一步必须使用命令行操作。

将 qcow2 镜像上传到 PVE 中,通过以下命令导入:

  • 9000 是刚才创建的虚拟机 VM ID
  • /tmp/debian-13-generic-amd64-zc.qcow2 是镜像存放的路径
  • local-lvm 是存储
  • --format=qcow2 将其指定为 qcow2 格式
sh
qm importdisk 9000 /tmp/debian-13-generic-amd64-zc.qcow2 local-lvm --format=qcow2

返回网页,会看到“未使用的硬盘 0”,双击将其添加进来。

导入镜像
导入镜像

接着来到“选项”,找到引导顺序,勾选刚才添加的系统盘,并把它移动到第一位。

引导顺序
引导顺序

添加硬件

除了系统盘以外,我们还需要添加 CloudInit 设备以及串行端口。

其中 CloudInit 设备可以用于配置虚拟机的用户名、密码、DNS、SSH 公钥以及 IP,而串行端口可以让我们使用控制台中的 xterm.js。

CloudInit

添加 CloudInit 设备,添加时建议选择 SCSI 设备。

添加 CloudInit 设备
添加 CloudInit 设备

接着来到 Cloud-Init 选项卡中,添加完 CloudInit 设备之后里面的选项就能修改了,可以设置一下用户、密码以及 IP。

Cloud-Init
Cloud-Init

串行端口

默认情况下,控制台只能选择 noVNC,但它使用起来非常的不方便,清晰度不够也不支持复制粘贴,因此我们需要添加一个“串行端口”来使用其他终端。

串行端口
串行端口

此时,控制台就多了个 xterm.js 可以选择了,使用起来更加的方便。

xterm.js
xterm.js

转换为模板

提示

为了保持系统的纯净度,如果你导入的是定制后的镜像,那么转换成模板前不要启动这台虚拟机。


如果你没有条件自动化定制镜像,那么可以在导入镜像之后,直接启动虚拟机,按照你自己的需求换源、安装常用的软件包等等。

不过这一系列操作会留下一堆日志以及缓存,好在除了 machine-id 外基本上都不会影响克隆后的虚拟机正常使用。

但不移除 machine-id 会使得后续克隆的虚拟机 machine-id 也相同,从而导致各种冲突,因此建议在所有操作完成后、关机前,执行以下命令将 machine-id 移除,最后再关闭虚拟机。

sh
truncate -s /etc/machine-id /var/lib/dbus/machine-id

完成以上所有步骤后,就可以将其转换成模板了,后续的创建虚拟机都以它为基础,几秒钟就可以新开一台虚拟机。

转换成模板
转换成模板

克隆虚拟机

创建一台新的虚拟机,只需要在刚才的模板上右键,选择“克隆”,模式建议选择“完整克隆”,稍等片刻左边的列表中就会有一台新的虚拟机出现了。

完整克隆
完整克隆

由于我们创建的模板选择配置都是比较低的,这时候可以适当调整一下配置,分配更大的内存、硬盘以及 CPU 核心数。

其中硬盘的扩容稍复杂些,选中硬盘后,找到上方的调整大小,初始硬盘为 3G,输入的数字为增量,例如扩容到 10G,则需要在弹出的窗口中填写 7G。

调整配置
调整配置
关注微信公众号
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3