Runbook — Windows Server 2022 Template di Incus Cluster#
Cluster: trim-computes-shr-incus-01 s/d 04 (Lenovo ThinkAgile HX630, Debian 13, Incus 7.2 Zabbly)
Storage: lvmcluster (sanlock/lvmlockd) di QNAP iSCSI — pool-qnap-hdd-01 (cluster-wide), pool-iso-and-templates (node-local, incus-01)
Terakhir diperbarui: 25 Juli 2026
1. Ringkasan & Keputusan Arsitektur#
Template Windows Server 2022 dibuat sebagai VM stopped pasca-sysprep di project Templates. Deployment VM baru dilakukan via incus copy / OpenTofu source_instance, BUKAN via incus publish + image.
Kenapa jalur copy, bukan publish:
- Bug lvmcluster — di storage lvmcluster, volume VM disimpan sebagai QCOW2 container di dalam LV.
incus publish(build sebelum fix PR lxc/incus#3705) meng-export volume sebagai raw, sehingga image berisi file QCOW2 mentah. Instance dari image tersebut gagal boot:BdsDxe: failed to load Boot0002 ... Not Found→ jatuh ke PXE, dan firmware File Explorer kosong total (tidak ada ESP terbaca). Referensi: forum thread 26990. - Copy lebih ringan — mekanisme copy instance lebih cepat daripada unpack image besar (konfirmasi maintainer Incus).
- Snapshot delete juga masih bugged di build yang sama (
qemu-img commitdengan path kosong) — sehingga snapshot template ditunda sampai fix rilis (lihat §11).
Setelah fix #3705 masuk paket Zabbly: publish boleh dipakai sebagai arsip versi immutable (lihat §11), jalur copy tetap jadi jalur deploy harian.
2. Prasyarat#
- Akses root/sudo ke node incus-01 (ISO node-local ada di sini).
- ISO Windows Server 2022 (
SERVER_EVAL_x64FRE_en-us) dan ISOvirtio-win-latestsudah tersedia sebagai custom volume di poolpool-iso-and-templates. - Project
Templatessudah ada. Catatan: project ini memakaifeatures.storage.volumes: "true"→ punya namespace volume sendiri, volume di projectdefaultTIDAK terlihat dari sini. - Ruang kosong cukup di
pool-qnap-hdd-01untuk root disk 66GiB.
Cek cepat:
incus storage volume list pool-iso-and-templates --all-projects
incus project show Templates | grep -E "storage.volumes|images"3. Siapkan ISO di Project Templates#
Karena namespace volume terpisah, copy kedua ISO dari default ke Templates (copy, bukan move — biar tetap bisa dipakai project lain):
incus storage volume copy pool-iso-and-templates/SERVER_EVAL_x64FRE_en-us \
pool-iso-and-templates/SERVER_EVAL_x64FRE_en-us --target-project Templates
incus storage volume copy pool-iso-and-templates/virtio-win-latest \
pool-iso-and-templates/virtio-win-latest --target-project TemplatesRationale: device
disktidak bisa menunjuk volume lintas project. Kalau attach errorStorage volume not foundpadahal volume ada, cek dulu project dan lokasi node-nya — dua penyebab paling umum.
4. Create VM Template#
WAJIB pin ke incus-01 (--target) karena ISO-nya node-local. Tanpa target, scheduler bisa menaruh VM di node lain dan attach ISO gagal Storage volume not found.
incus init trim-vm-shr-tx-template-win2022 --empty --vm --project Templates \
--target trim-computes-shr-incus-01 \
-c limits.cpu=4 -c limits.memory=8GiB \
-s pool-qnap-hdd-01 \
-d root,size=66GiBSet image.os=Windows — WAJIB, ini yang menentukan isi agent drive nanti (Windows vs Linux) dan menyesuaikan behavior QEMU untuk guest Windows:
incus config set trim-vm-shr-tx-template-win2022 image.os=Windows --project TemplatesOpsional (vTPM, tidak wajib untuk Win2022):
incus config device add trim-vm-shr-tx-template-win2022 vtpm tpm --project TemplatesGotcha flag
-d: formatnyadevice,key=value— SATU pasang key=value per flag.-d root,size=66GiB,pool=...akan error validation. Pool dipisah ke flag-s.
Gotcha move antar node:
incus move --targetuntuk VM yang sudah dibuat bisa gagaltarget instance root disk size is smaller than the migration source— LV di lvmcluster di-round up ke extent boundary (66GiB → 66.01g), validasi migrasi menolak. Kalau VM masih kosong, lebih cepat delete + init ulang dengan--targetyang benar.
5. Attach ISO Installer & Driver#
incus config device add trim-vm-shr-tx-template-win2022 install disk \
pool=pool-iso-and-templates source=SERVER_EVAL_x64FRE_en-us boot.priority=10 --project Templates
incus config device add trim-vm-shr-tx-template-win2022 drivers disk \
pool=pool-iso-and-templates source=virtio-win-latest --project Templates6. Install Windows#
Start dan buka console VGA:
incus start trim-vm-shr-tx-template-win2022 --project Templates
incus console trim-vm-shr-tx-template-win2022 --type=vga --project Templates6a. Masalah: WinPE tidak melihat disk maupun CD virtio#
Di step “Load driver”, dialog Browse hanya menampilkan Boot (X:) — tidak ada CD drive sama sekali.
Penyebab: semua storage device (disk 66GB + kedua ISO) menempel di bus virtio-scsi, dan WinPE belum punya driver vioscsi. Firmware EDK2 bisa boot dari ISO (punya driver sendiri), tapi begitu WinPE mengambil alih — buta total. Telur-ayam: driver ada di CD yang tidak terbaca karena butuh driver itu sendiri.
Solusi (pilih salah satu):
Opsi A — pindahkan ISO virtio ke bus USB (tercepat; WinPE punya driver USB built-in):
incus stop trim-vm-shr-tx-template-win2022 --project Templates --force
incus config device set trim-vm-shr-tx-template-win2022 drivers io.bus=usb --project Templates
incus start trim-vm-shr-tx-template-win2022 --project TemplatesOpsi B — repack ISO installer dengan distrobuilder (driver di-inject ke boot.wim/install.wim, masalah hilang dari akar):
sudo distrobuilder repack-windows --windows-version=w2k22 \
--drivers=virtio-win.iso SERVER_EVAL_x64FRE_en-us.iso win2022-virtio.iso
incus storage volume import pool-iso-and-templates win2022-virtio.iso win2022-virtio \
--type=iso --project Templates
# lalu swap device "install" ke volume baru ini6b. Load driver di installer#
Di pemilihan disk: Load driver → Browse → CD virtio-win:
vioscsi\2k22\amd64→ disk 66GB muncul, DVD installer terbaca lagiNetKVM\2k22\amd64→ network langsung hidup di first boot
Lanjutkan instalasi sampai masuk desktop.
7. Post-Install (urutan penting)#
7a. VirtIO Guest Tools#
Jalankan virtio-win-guest-tools.exe dari CD virtio — install semua driver sisanya (Balloon, serial, QXL, dsb) sekali jalan.
7b. Driver viosock (prasyarat komunikasi agent)#
Kalau guest-tools melewatkannya (cek Device Manager: unknown device / PCI Simple Communications Controller bertanda seru), install manual dari PowerShell/CMD admin:
pnputil /add-driver D:\viosock\2k22\amd64\viosock.inf /installVerifikasi: Device Manager → System devices → VirtIO Socket tanpa tanda seru.
7c. Incus Agent (Windows)#
Dari host, attach agent drive:
incus config device add trim-vm-shr-tx-template-win2022 agent disk source=agent:config --project Templates
incus restart trim-vm-shr-tx-template-win2022 --project TemplatesKalau isi CD agent berupa file Linux (
install.sh, foldersystemd) — berartiimage.os=Windowsbelum di-set (§4). Set, lalu restart VM: drive akan berisiincus-agent.exe+install.ps1.
Di dalam Windows (PowerShell admin, sesuaikan drive letter):
powershell -ExecutionPolicy Bypass -File E:\install.ps1Restart VM, lalu verifikasi dari host — IP muncul = vsock → agent → host jalan penuh:
incus info trim-vm-shr-tx-template-win2022 --project Templates
incus exec trim-vm-shr-tx-template-win2022 --project Templates -- cmd /c hostnamePENTING: device
agent(CD-ROM) TIDAK boleh di-detach — diakses setiap boot untuk refresh agent + credentials TLS. Ini bagian permanen template; semua clone otomatis mewarisinya. Catatan: jam guest harus sinkron wajar dengan host (agent pakai TLS cert).
7d. Windows Update + software standar#
- Windows Update sampai tuntas (di template, bukan di tiap clone).
- Install software/agent standar perusahaan.
7e. Yang JANGAN dilakukan di template#
- ❌ Join domain
- ❌ Set IP statis
- ❌ Aktivasi lisensi final
Semua itu urusan per-clone setelah deploy. Template harus netral.
8. Fallback Bootloader (anti masalah NVRAM)#
UEFI NVRAM (boot entries) itu per-instance dan tidak ikut ter-copy sempurna di semua jalur. Windows hanya mendaftarkan \EFI\Microsoft\Boot\bootmgfw.efi via NVRAM entry — kalau entry hilang, firmware fallback ke \EFI\Boot\bootx64.efi yang TIDAK di-install Windows di fixed disk. Kita isi manual supaya disk self-bootable di firmware manapun:
mountvol S: /S
copy /Y S:\EFI\Microsoft\Boot\bootmgfw.efi S:\EFI\Boot\bootx64.efi
mountvol S: /D
mountvol /Sme-mount EFI System Partition (FAT32 tersembunyi) ke drive letter pilihan. HurufSarbitrary. Cek duludir S:\EFIkalau ragu.
9. Sysprep — Langkah Terakhir di Dalam Guest#
C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown /mode:vm/generalize— buang SID, machine-specific state → tiap clone dapat identitas baru/oobe— clone boot ke Out-of-Box Experience/mode:vm— skip hardware re-detection (semua clone di virtual hardware identik, first boot jauh lebih cepat)
VM shutdown sendiri setelah selesai.
⚠️ JANGAN PERNAH start template ini lagi. Sekali boot, generalize-nya terpakai (dan ada rearm limit). Kalau butuh update template → lihat §12.
10. Finalisasi dari Host#
Detach ISO installer & driver (agent drive TETAP terpasang):
incus config device remove trim-vm-shr-tx-template-win2022 install --project Templates
incus config device remove trim-vm-shr-tx-template-win2022 drivers --project TemplatesProteksi template:
incus config set trim-vm-shr-tx-template-win2022 security.protection.delete=true --project Templates
incus config set trim-vm-shr-tx-template-win2022 boot.autostart=false --project TemplatesTest clone (wajib sebelum dipakai produksi)#
incus copy trim-vm-shr-tx-template-win2022 test-win-01 \
--project Templates --target-project Staging --target trim-computes-shr-incus-01
incus start test-win-01 --project StagingKriteria lulus:
- Boot masuk OOBE (region → EULA → password Administrator baru). Langsung ke login screen lama = sysprep gagal, ulangi dari §9 (template harus di-rebuild).
incus info test-win-01 --project Stagingmenampilkan IP (agent + viosock ikut ter-clone).whoami /user→ SID berbeda dari template.
Bersihkan: incus stop test-win-01 --project Staging && incus delete test-win-01 --project Staging
Ekspektasi durasi copy: lvmcluster = LV non-thin, tidak ada CoW — copy adalah salinan blok penuh via qemu-img (~140 MB/s di pool HDD lewat iSCSI). Belasan menit per clone itu NORMAL. Tips: selalu sertakan --target yang sama dengan lokasi eksekusi supaya read-write satu node; pool SSD (RAID10 SA500) akan memangkas waktu signifikan. Monitor: incus operation list --project <proj> + iostat -xm 2 (metadata operation tidak menampilkan persentase — normal).
11. Deployment#
OpenTofu (jalur utama)#
resource "incus_instance" "win_vm" {
name = var.vm_name
type = "virtual-machine"
project = "Staging"
profiles = var.profiles
source_instance = {
project = "Templates"
name = "trim-vm-shr-tx-template-win2022"
# snapshot = "clean" # aktifkan setelah fix #3705 rilis, lihat bawah
}
}Tiap apply VM baru = belasan menit (block copy) — tofu terlihat “hang”, itu normal.
Manual#
incus copy trim-vm-shr-tx-template-win2022 <nama-vm> \
--project Templates --target-project <project> --target <node>Setelah fix PR #3705 masuk paket Zabbly#
Cek build: apt policy incus (Zabbly rebuild dengan version string tetap “7.2” — bandingkan TANGGAL di Installed: vs Candidate:). Upgrade rolling per node, tunggu incus cluster list ONLINE sebelum lanjut node berikutnya.
Lalu:
- Snapshot beku:
incus snapshot create trim-vm-shr-tx-template-win2022 clean --project Templates→ aktifkansnapshot = "clean"di tofu. Deploy selalu dari titik beku walau template tak sengaja berubah. - Publish sebagai arsip versi (opsional, hybrid):
incus publish trim-vm-shr-tx-template-win2022 --alias win2022-template-2026.07 --project Templates
# WAJIB verifikasi sebelum dipercaya:
incus image export win2022-template-2026.07 /tmp/win-img --project Templates
file /tmp/win-img*
# "DOS/MBR boot sector; GPT" = sah ✅ | "QEMU QCOW2 Image" = masih bugged ❌, hapus image12. Update Template (siklus rebuild)#
Template pasca-sysprep tidak boleh di-boot, jadi update = rebuild:
- Copy template ke VM kerja baru:
incus copy trim-vm-shr-tx-template-win2022 win2022-work --project Templates - Boot
win2022-work(dia akan lewat OOBE sekali), update/ubah sesuai kebutuhan - Ulangi §8–§10 pada
win2022-work - Setelah test clone lulus: rename/tukar peran —
win2022-workjadi template baru, template lama diarsip (publish ber-tanggal, setelah fix) atau dihapus (security.protection.delete=falsedulu)
13. Troubleshooting#
| Gejala | Penyebab | Solusi |
|---|---|---|
Instance dari image publish: BdsDxe ... Not Found → PXE, Boot From File kosong | Bug publish qcow2-in-raw di lvmcluster | Jangan pakai publish sebelum fix #3705; deploy via copy (§11) |
incus snapshot delete / incus delete (VM ber-snapshot): qemu-img commit -f qcow2 : Could not open '' | Bug path resolution snapshot-delete lvmcluster; aktivasi LV manual TIDAK menolong | Sebelum fix: hapus record snapshot via incus admin sql (backup dump dulu!) + lvremove LV snapshot, lalu delete VM normal |
Attach ISO: Storage volume not found (volume terlihat ada) | (a) Volume di project lain — features.storage.volumes=true memisah namespace; (b) VM di node berbeda dari volume node-local | (a) incus storage volume copy ... --target-project; (b) cek incus info <vm> | grep Location, samakan dengan lokasi volume |
incus move --target: root disk size is smaller than the migration source | LV rounding lvmcluster (66GiB vs 66.01g) | VM kosong: delete + init ulang dengan --target; VM berisi: naikkan size root device dulu |
| Installer Windows: tidak ada disk & CD di Load driver | WinPE tanpa driver vioscsi, semua device di virtio-scsi | §6a — io.bus=usb untuk ISO virtio, atau repack distrobuilder |
CD agent berisi file Linux (install.sh, systemd) | image.os belum Windows | incus config set <vm> image.os=Windows + restart VM |
Agent tidak konek (tidak ada IP di incus info) | Driver viosock belum terpasang / jam guest jauh dari host / agent drive ter-detach | §7b–7c; sinkronkan jam; pasang kembali device agent |
| Copy terasa hang, operation metadata kosong | Normal — lvmcluster non-thin, block copy penuh; metadata memang tidak ada progress | Monitor iostat -xm 2 di node source & target; JANGAN Ctrl+C |
| Clone boot ke login screen lama (bukan OOBE) | Template sempat ter-boot setelah sysprep, atau sysprep tidak jalan | Rebuild template (§12) |
14. Referensi#
- Forum thread bug publish: https://discuss.linuxcontainers.org/t/windows-server-2022-vm-from-published-image-fails-uefi-boot-bdsdxe-not-found-no-filesystem-visible-in-boot-from-file/26990
- Fix upstream: https://github.com/lxc/incus/pull/3705
- Incus docs — instance creation & agent: https://linuxcontainers.org/incus/docs/main/howto/instances_create/
- Forum — agent Windows &
image.os: https://discuss.linuxcontainers.org/t/incus-agent-on-windows-vm/24794