Skip to content

利用搬瓦工 VPS 定制 Debian 镜像 支持 Cloud-Init 快速部署虚拟机【模板篇】 ​

前言 ​

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

搬瓦工系统
搬瓦工系统

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

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

Debian 云镜像
Debian 云镜像

定制镜像 ​

提示

如果你没有条件定制镜像,可以直接下载我定制的 Debian 镜像


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

使用 virt-customize 自动化定制参考了《为 Proxmox VE 定制 Debian Cloud 系统镜像与创建虚拟机模板》,如果想要深入了解的可以去看看原文

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

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

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

generic 镜像
generic 镜像

选择好了合适的镜像后,我们接着用 libguestfs-tools 来自动化定制镜像,这一过程需要一台国外的 VPS,网络比较流畅,定制不容易出问题,这里用到的是搬瓦工的 E-commerce 系列,支持切换 15 个机房,具体配置如下:

👉查看所有机房的详细测评

套餐名机房线路配置 (核心/内存/硬盘/流量)价格链接
SPECIAL 20G KVM PROMO V5 - CN2 GIA ECOMMERCE可选美国、加拿大、日本、荷兰等 15 个机房优化线路2C / 1G / 20G / 1T$49.99 / 季立即购买
SPECIAL 40G KVM PROMO V5 - CN2 GIA ECOMMERCE可选美国、加拿大、日本、荷兰等 15 个机房优化线路3C / 2G / 40G / 2T$89.99 / 季立即购买
SPECIAL 80G KVM PROMO V5 - CN2 GIA ECOMMERCE可选美国、加拿大、日本、荷兰等 15 个机房优化线路4C / 4G / 80G / 3T$56.99 / 月立即购买

如果只是进行简单的镜像定制,对配置要求并不高,建议选择 SPECIAL 20G KVM PROMO V5 - CN2 GIA ECOMMERCE,1G 内存就够用了,性价比比较高。

若还需要对定制完成的镜像进行压缩处理,则对内存的要求会更高。此时建议选择 SPECIAL 80G KVM PROMO V5 - CN2 GIA ECOMMERCE 套餐,4G 内存更为合适,避免压缩过程中的性能瓶颈。

SPECIAL 20G KVM PROMO V5 - CN2 GIA ECOMMERCE
SPECIAL 20G KVM PROMO V5 - CN2 GIA ECOMMERCE
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。

调整配置
调整配置

一键脚本 ​

对于不适合直接定制到系统镜像中的应用,为此我写了一个脚本,集成了一些常用的软件和测试脚本。

sh
wget -O one-click.sh https://gist.githubusercontent.com/izhichao/60906715e2c59ff92be281b1ba58f482/raw/one-click.sh && chmod +x one-click.sh && ./one-click.sh

后续可以通过 ./one-click.sh 执行脚本,一共分成了三个板块,分别是测试脚本、常用软件以及常用设置,其中测试脚本以及常用软件调用的都是官方的下载链接,可以放心使用。

测试脚本
测试脚本
常用软件
常用软件
常用设置
常用设置

脚本完全开源,并且代码结构非常的简单,如果我的脚本不满足你的需求,完全可以在此基础上加上你自己需要的软件。

Last updated:

Evoxt:Evoxt:
最便宜的亚太优化线路 —— 马来西亚 电信 GIA / 联通 9929 仅需 $3.32 起!
95 折优惠码AFF2377-DEV
🎉银河录像局:
Netflix / Spotify/ ChatGPT / Claude 等 AI 流媒体一站式合租平台!
95 折优惠码zhichao
关注微信公众号
优化线路
Evoxt

Evoxt

最便宜的亚太优化线路

马来西亚 电信 GIA / 联通 9929
优惠码:AFF2377-DEV

1C / 512MB / 5GB SSD / 150GB 流量

$3.32/月
优化线路
搬瓦工

搬瓦工

15 个机房自由切换

洛杉矶 DC6 机房
电信 / 联通 GIA + 移动 CMIN2

2C / 2GB / 40GB SSD / 1TB 流量

$49.99/季