Сборка шаблона cloud-init на ZFS
Приветствую!

Разберём, как корректно собирать Cloud-Init шаблоны в Proxmox VE при использовании ZFS. Материал основан на практическом опыте и типичных проблемах при переходе с классических схем хранения (mdadm + LVM) на ZFS.

Введение

Моё знакомство с Proxmox VE началось с 7-й версии, когда система часто разворачивалась поверх Debian вручную. Изначально я использовал mdadm + LVM - это было просто и предсказуемо. После перехода на серверное железо и миграции на ZFS (с восстановлением виртуальных машин из бэкапов) проявилась проблема: при развёртывании виртуальных машин (ВМ) через Terraform перестал корректно работать dynamic inventory в Ansible.

Причина оказалась не в Terraform или Ansible, а глубже - в несовместимости модели хранения ZFS (zvol) и формата qcow2. Этот разбор и лёг в основу статьи.

В статье рассмотрим:

ПО, используемое в статье:

ПОВерсия
Proxmox VE9.1
Debian13

Для лучшего понимания сути заметки, важно озвучить теоретическую сторону данного кейса.

Проблематика: ZFS и QCOW2

Ключевая проблема - различие моделей хранения данных.

В Proxmox VE с ZFS:

Это создаёт архитектурный конфликт:

Характеристикаqcow2zvol
ТипФайлБлочное устройство
Требует наличия ФСДаНет
Copy-on-WriteВнутри файлана уровне ZFS
Использование в Proxmox VEdirectory storageZFS storage

Различия между qcow2, raw, zvol и ZFS dataset

QCOW2

qcow2 - это файловый формат с поддержкой:

Фактически это слой поверх файловой системы.

Проблема на ZFS - двойной CoW:

Последствия:

Поэтому в документации Proxmox VE не рекомендуется использовать qcow2 на ZFS.

RAW

RAW - это линейный образ без дополнительной логики.

Преимущества: минимальные накладные расходы, предсказуемая производительность и оптимальность для ZFS.

ZVOL

ZVOL - это блочное устройство внутри ZFS.

Ключевой параметр: volblocksize (размер блока). Размер блока напрямую влияет на производительность системы ввода-вывода, потому важно указать оптимальное значение.

Типичные значения:

В Proxmox VE по умолчанию создаётся zvol с размером блока 16K, что оптимально для дисков ВМ на ZFS.

ZFS Dataset

ZFS dataset - это файловая система внутри ZFS.

Используется для:

Особенности:

Почему возникает конфликт

Проблема появляется при попытке использовать файловый образ (qcow2) как источник для блочного устройства (zvol).

На практике это выглядит так:

Типичная ошибка в инструкциях:

BASH
qm importdisk 7777 ./debian-13-generic-amd64.qcow2 storage --format qcow2
Нажмите, чтобы развернуть и увидеть больше

Здесь явно задан qcow2, что некорректно для zvol.

Результат:

Варианты решения

Подход 1: ZFS Dataset (directory storage)

Создайте набор данных (dataset) с файловой системой, например:

PLAINTEXT
rpool/data/images
Нажмите, чтобы развернуть и увидеть больше

И используйте его как каталог (directory storage).

Преимущества: простая настройка.

Недостатки: двойной CoW.

Вывод: допустимо, но не оптимально.

Подход 2 (рекомендуемый): использование RAW

На этапе импорта диска в пустую виртуальную машину укажите формат RAW вместо стандартного qcow2:

BASH
qm importdisk <VMID> <image> <storage> --format raw
Нажмите, чтобы развернуть и увидеть больше

Например, для машины с id 7777 из инструкции на сайте команда будет такой:

BASH
qm importdisk 7777 ./debian-13-generic-amd64.qcow2 storage --format raw
Нажмите, чтобы развернуть и увидеть больше

Во время импорта qcow2 конвертируется в raw при импорте, raw записывается в zvol.

Преимущества: нет двойного CoW, максимальная производительность и Cloud-Init работает корректно.

Сборка Cloud-Init шаблона на ZFS

Информации не так много, но читатели не знакомые с ZFS, вероятно, успели запутаться. Поэтому предлагаю ещё раз последовательно разобрать типовой процесс создания шаблона виртуальной машины с использованием Cloud-Init, с учётом особенностей работы с ZFS.

1. Импорт образа

  1. Увеличиваем размер диска:
BASH
qemu-img resize ./debian-13-generic-amd64.qcow2 32G
Нажмите, чтобы развернуть и увидеть больше

Где debian-13-generic-amd64.qcow2 - образ диска cloud-init, а 32G - итоговый размер (32ГБ).

  1. Создаём новую виртуальную машину без диска:
BASH
qm create 9998 --name "debian-13-ci" --memory 2048 --cores 2 --net0 virtio,bridge=vnet01
Нажмите, чтобы развернуть и увидеть больше

Расшифровка:

  1. Импортируем образ qcow2 в формате raw (ключевое отличие):
BASH
qm importdisk 9998 debian-13-generic-amd64.qcow2 vm-hdd --format raw
Нажмите, чтобы развернуть и увидеть больше

Где vm-hdd - имя вашего zvol в Proxmox VE.

  1. Устанавливаем SCSI контроллер и добавляем ранее импортированный диск:
BASH
qm set 9998 --scsihw virtio-scsi-single --scsi0 vm-hdd:vm-9998-disk-0,discard=on
Нажмите, чтобы развернуть и увидеть больше
  1. Обновляем порядок загрузки:
BASH
qm set 9998 --boot order=scsi0
Нажмите, чтобы развернуть и увидеть больше
  1. Добавляем Cloud-Init диск:
BASH
qm set 9998 --ide1 vm-hdd:cloudinit
Нажмите, чтобы развернуть и увидеть больше
  1. Настраиваем пользователя, пароль и SSH для cloud-init:
BASH
# --- Пользователь ---
# Создаём пользователя:
qm set 9998 --ciuser ansible
qm set 9998 --cipassword <ПАРОЛЬ ПОЛЬЗОВАТЕЛЯ>
# Добавляем SSH ключ:
qm set 9998 --sshkeys ~/.ssh/id_ed25519.pub

# ------- СЕТЬ -------
# Настройка IP по DHCP:
qm set 9998 --ipconfig0 ip=dhcp
# Статический IP:
qm set 9998 --ipconfig0 ip=10.10.10.254/24,gw=10.10.10.1
# Установить адрес DNS-сервера 10.10.10.15:
qm set 9998 --nameserver 10.10.10.15
# Задать домен поиска infra.lan:
qm set 9998 --searchdomain infra.lan

# ----- Обновления -----
# Установка обновлений при запуске:
qm set 9998 --ciupgrade 1
# Не устанавливать обновления:
qm set 9998 --ciupgrade 0
Нажмите, чтобы развернуть и увидеть больше
  1. Добавляем последовательный порт:
BASH
qm set 9998 --serial0 socket --vga serial0
Нажмите, чтобы развернуть и увидеть больше
  1. Включаем QEMU Guest Agent для взаимодействия гипервизора с гостевой системой:
BASH
qm set 9998 --agent enabled=1
Нажмите, чтобы развернуть и увидеть больше
  1. Сохраняем машину как шаблон:
BASH
qm template 9998
Нажмите, чтобы развернуть и увидеть больше
  1. Создаём клон ранее собранного шаблона для проверки работы Cloud-Init:

  1. Запускаем тестовую машину и проверяем:

Готово! Теперь шаблон Cloud-Init работает корректно и хранится на вашем zvol.

2. Добавление Cloud-Init в готовый шаблон

Если вы не так давно узнали про Cloud-Init и уже успели собрать шаблоны типовых виртуальных машин под вашу инфраструктуру не расстраивайтесь!

Есть способ добавить поддержку Cloud-Init для уже существующих шаблонов, рассмотрим пример с Debian 13 Trixie.

  1. Сделайте полную копию шаблона (Full Clone).
  2. Подключитесь к терминалу новой машины через VNC или SSH.
  3. Переключитесь на пользователя root (если используете пользовательскую учётную запись):
BASH
sudo -i
Нажмите, чтобы развернуть и увидеть больше
  1. Обновите систему:
BASH
apt update && apt full-upgrade -y
Нажмите, чтобы развернуть и увидеть больше
  1. Установите гоствевой агент (если не сделали этого ранее) и пакет cloud-init:
BASH
apt install -y qemu-guest-agent cloud-init
Нажмите, чтобы развернуть и увидеть больше
  1. Создайте новую конфигурацию Cloud-Init для Proxmox VE:
BASH
/etc/cloud/cloud.cfg.d/99-pve.cfg
Нажмите, чтобы развернуть и увидеть больше

В файл вставьте строку такого вида:

BASH
datasource_list: [ NoCloud, ConfigDrive ]
Нажмите, чтобы развернуть и увидеть больше

Сохраните изменения и выйдите из текстового редактора.

  1. Выполните очистку журналов и machine-id:
BASH
cloud-init clean --logs
rm -f /etc/machine-id
truncate -s 0 /etc/machine-id
Нажмите, чтобы развернуть и увидеть больше
  1. При желании можно почистить журналы в системе и кэш apt:
BASH
journalctl --rotate
journalctl --vacuum-time=1s
apt clean
Нажмите, чтобы развернуть и увидеть больше
  1. Выключите машину:
BASH
poweroff
Нажмите, чтобы развернуть и увидеть больше
  1. Переключитесь на терминал гипервизора и добавьте диск Cloud-Init к этой машине:
BASH
qm set <VMID> --ide2 <storage>:cloudinit
Нажмите, чтобы развернуть и увидеть больше
  1. Затем добавьте последовательный порт:
BASH
qm set <VMID> --serial0 socket --vga serial0 
Нажмите, чтобы развернуть и увидеть больше
  1. Включите агента:
BASH
qm set <VMID> --agent enabled=1
Нажмите, чтобы развернуть и увидеть больше
  1. Сохраните данную машину как шаблон:
BASH
qm template <VMID>
Нажмите, чтобы развернуть и увидеть больше

После этого можно добавить дополнительные параметры Cloud-Init и проверить работу обновлённого шаблона.

Типичные ошибки

Наиболее частые проблемы:

Эти ошибки часто проявляются не сразу, но создают проблемы при масштабировании.

Вывод

Если вы используете Proxmox VE с ZFS оптимальная схема будет такой:

ZFS уже реализует CoW, снапшоты и thin provisioning. Использование qcow2 поверх ZFS дублирует эти механизмы и приводит к деградации производительности и усложнению архитектуры.

Авторские права

Автор: Кирилл Решетников

Ссылка: https://r4ven.me/virtualization/sborka-shablona-cloud-init-na-zfs/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша