痛点 链接到标题

传统 PVE 创建 VM 的流程:

  1. 下载 ISO 镜像
  2. 通过 Web UI 或命令行创建 VM
  3. 打开 VNC 控制台,手动走完 Ubuntu 安装向导
  4. 设置用户名、密码、时区、磁盘分区…
  5. 安装完成后登录,再手动配置 SSH key
  6. 重复以上步骤 N 次(如果需要多台)

整个过程耗时 10-15 分钟,且每一步都需要人工介入。如果只是需要一个临时测试环境,这个流程太繁琐了。

方案:cloud image + cloud-init 链接到标题

Ubuntu 官方提供 cloud image(预装 cloud-init 的磁盘镜像),配合 PVE 内置的 cloud-init 支持,可以实现:

  • 无需 ISO 安装,镜像即系统
  • 首次启动自动完成:磁盘扩容、创建用户、注入 SSH key、配置网络
  • 全程无人值守,1-2 分钟即可 SSH 登录

操作步骤 链接到标题

1. 下载 Ubuntu 24.04 cloud image 链接到标题

在 PVE 节点上下载:

# 清华镜像源,速度更快
wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/noble/current/noble-server-cloudimg-amd64.img \
  -O /var/lib/vz/template/iso/ubuntu-24.04-cloudimg.img

2. 创建 VM 并导入镜像 链接到标题

# 创建空 VM(分配资源)
qm create 6000 \
  --name "vm-name" \
  --memory 4096 \
  --cores 2 \
  --net0 virtio,bridge=vmbr0

# 导入 cloud image 到存储
qm importdisk 6000 /var/lib/vz/template/iso/ubuntu-24.04-cloudimg.img local-lvm

# 挂载磁盘并配置引导
qm set 6000 \
  --scsihw virtio-scsi-pci \
  --scsi0 local-lvm:vm-6000-disk-0 \
  --boot order=scsi0

3. 准备 cloud-init 配置 链接到标题

创建 cloud-init 用户配置文件,注入 SSH 公钥:

mkdir -p /var/lib/vz/snippets
# /var/lib/vz/snippets/user-config.yaml
#cloud-config
users:
  - name: admin
    ssh_authorized_keys:
      - "ssh-rsa AAAA... your-public-key"
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: sudo
    shell: /bin/bash
ssh_pwauth: false

4. 关联 cloud-init 到 VM 链接到标题

qm set 6000 \
  --ciuser admin \
  --cicustom "user=local:snippets/user-config.yaml" \
  --ipconfig0 ip=dhcp \
  --agent 1 \
  --serial0 socket \
  --vga serial0

参数说明:

参数 作用
--ciuser 指定 cloud-init 创建的用户
--cicustom 引用自定义 cloud-init 配置文件
--ipconfig0 ip=dhcp 网络 DHCP 自动获取
--agent 1 启用 qemu-guest-agent
--serial0 / --vga serial0 串口控制台输出

5. 启动 VM 链接到标题

qm start 6000

启动后 cloud-init 会自动完成以下工作:

  1. 扩展根分区至磁盘全容量(cloud image 默认只有 2-3G)
  2. 创建用户并设置 sudo 权限
  3. 注入 SSH 公钥到 ~/.ssh/authorized_keys
  4. 配置网络(DHCP)
  5. 启动 qemu-guest-agent

整个过程无需任何人机交互,约 1-2 分钟完成。

6. SSH 登录 链接到标题

从局域网内任意机器直接 SSH 登录:

ssh admin@192.168.x.x

首次登录无需密码,直接使用 SSH key 认证。

验证 链接到标题

登录后检查关键配置是否生效:

# 确认用户和 sudo 权限
whoami
sudo whoami

# 确认磁盘已扩容
df -h /

# 确认网络配置
ip addr show

# 确认 qemu-guest-agent 运行中
systemctl status qemu-guest-agent

原理简析 链接到标题

flowchart LR A[cloud image] --> B[导入 PVE] B --> C[qm create + set] C --> D[cloud-init ISO] D --> E[首次启动] E --> F[磁盘扩容] E --> G[创建用户] E --> H[注入 SSH key] E --> I[配置网络] F --> J[SSH 就绪] G --> J H --> J I --> J

PVE 在 VM 首次启动时,会根据 --cicustom--ciuser 等参数动态生成一个 cloud-init NoCloud ISO,挂载为 IDE 设备。VM 内的 cloud-init 服务检测到该 ISO 后,读取配置并执行初始化。

总结 链接到标题

  • cloud image + cloud-init 是 PVE 上创建 Linux VM 的最佳实践
  • 全程无需 VNC 手动安装,适合批量创建和临时测试环境
  • 配合 Ansible 或 Terraform 可实现完全基础设施即代码
  • 关键点:cloud image 代替 ISO,cloud-init 代替手动配置

下次需要快速拉起一台 Ubuntu 测试机时,试试这个方案,省下的时间用来喝杯咖啡 ☕