Episode ini menyiapkan VM yang langsung siap pakai: mengunduh cloud image (Ubuntu, Fedora, Debian), mengonversinya ke raw, mem-boot via direct maupun UEFI, lalu mengotomatiskan bootstrap dengan cloud-init (password, SSH key, dan packages) lewat user-data dan metadata.

Sejauh ini kita boot VM dengan cara yang masih "manual" — dan menyediakan login lewat console serial itu melelahkan. Di episode 9 kita mengubah cara kerja ini: menggunakan cloud image resmi dari distribusi dan cloud-init untuk melakukan bootstrap otomatis. Hasilnya, VM bisa di-provisioning tanpa sentuhan manusia: IP, SSH key, user, bahkan instalasi package, semuanya terjadi saat boot pertama.
Ini bukan sekadar kenyamanan. Di dunia nyata, platform cloud (dan Kata Containers) memakai pola yang sama: image yang immutable dan provisioning yang deklaratif. Memahami cloud image dan cloud-init berarti memahami bagaimana VM di-cloud "dilahirkan".
Cloud image adalah image sistem operasi yang dioptimalkan untuk VM: tidak ada installer interaktif, login default lewat SSH dengan key, dan cloud-init terpasang. Setiap distribusi besar menyediakannya:
ubuntu-24.04-server-cloudimg-amd64.img.Fedora-Cloud-Base.debian-12-genericcloud-amd64.qcow2.wget https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.imgKarena ukurannya besar dan biasanya berupa qcow2 yang rapat, konversi ke raw agar langsung dipakai virtio-blk:
qemu-img convert -O raw ubuntu-24.04-server-cloudimg-amd64.img ubuntu.raw
qemu-img info ubuntu.rawNote
Jangan menyalahgunakan cloud image langsung sebagai disk yang ditulis berulang-ulang. Pola production: image adalah base yang immutable; setiap VM dibuat dengan menyalin image ke disk baru (atau memakai qcow2 dengan backing file) agar tidak ada drift antar VM.
Saat boot pertama, guest menjalankan layanan cloud-init yang mencari data konfigurasi dari beberapa sumber. Dua yang utama:
Cloud-init menerima data ini dari berbagai datasource: NoCloud (disajikan sebagai file di disk atau volume), Config Drive, atau metadata service. Di Cloud Hypervisor, cara termudah adalah menyajikan user-data sebagai volume NoCloud.
Cloud Hypervisor menyajikan user-data sebagai disk kedua. Untuk membuatnya, kita pakai cloud-localds dari paket cloud-image-utils:
sudo apt install -y cloud-image-utils
cloud-localds seed.img user-data.yamlcloud-localds seed.img user-data.yaml membuat image kecil berisi user-data dan metadata dalam format NoCloud. Sajikan sebagai disk kedua saat boot:
cloud-hypervisor \
--kernel kernel-vmlinux \
--disk path=ubuntu.raw \
--disk path=seed.img \
--cpus boot=2 \
--memory size=2G \
--net tap=ch0,ip=192.168.100.1,mac=a8:21:95:80:35:e6 \
--serial tty \
--cmdline "console=ttyS0 root=/dev/vda1 rw"Contoh user-data yang lengkap:
#cloud-config
hostname: ch-vm-01
users:
- name: arman
sudo: ALL=(ALL) NOPASSWD:ALL
groups: sudo
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA...your-public-key...
ssh_pwauth: false
package_update: true
packages:
- htop
- curl
- qemu-guest-agent
write_files:
- path: /etc/motd
content: |
Welcome to Cloud Hypervisor VM!
runcmd:
- systemctl enable --now qemu-guest-agentBaca struktur utamanya:
users: mendefinisikan user arman dengan akses sudo tanpa password dan SSH key kalian.ssh_pwauth: false menonaktifkan login password — hanya SSH key, pola paling aman.packages: menginstall paket saat boot pertama.write_files: menulis file arbitrer (di sini /etc/motd).runcmd: menjalankan perintah segera setelah paket terinstall.Setelah boot, tunggu cloud-init selesai lalu login lewat SSH dari host:
ssh -i ~/.ssh/id_ed25519 arman@192.168.100.10Di dalam guest, riwayat cloud-init bisa diperiksa:
cloud-init status
cat /var/log/cloud-init-output.log | tail -20cloud-init status menunjukkan done saat provisioning selesai. Jika status masih running, tunggu sebentar — boot pertama menginstall packages sehingga butuh waktu.
Selain user-data, kalian bisa mengontrol network guest lewat metadata. Dengan cloud-init, konfigurasi network bisa disuntikkan lewat blok network (jika image memakai netplan/NetworkManager):
version: 2
ethernets:
default:
match:
name: en*
dhcp4: false
addresses:
- 192.168.100.10/24
gateway4: 192.168.100.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]Sajikan bersama seed dengan cloud-localds --network-config network-config seed.img user-data.yaml. Hasilnya: guest langsung memiliki IP statis tanpa konfigurasi manual.
Cloud image yang lebih baru (terutama yang memakai GRUB/ESP) butuh firmware UEFI. Boot dengan CLOUDHV.fd:
cloud-hypervisor \
--firmware CLOUDHV.fd \
--disk path=ubuntu.raw \
--disk path=seed.img \
--cpus boot=2 \
--memory size=2G \
--serial ttyDi jalur UEFI, partisi root di dalam image biasanya bukan /dev/vda1 — image UEFI umumnya memakai /dev/vda15 untuk ESP dan root di partisi lain. Jika kernel panik karena tidak menemukan root, cek layout partisi dengan guestfish atau qemu-nbd.
Tip
Selalu verifikasi layout partisi sebelum menebak root=. qemu-nbd bisa memaparkan image sebagai device blok tanpa menjalankan VM: modprobe nbd max_part=8 && qemu-nbd --connect=/dev/nbd0 ubuntu.raw lalu lihat partisi dengan fdisk -l /dev/nbd0. Lepas dengan qemu-nbd --disconnect.
--disk path=seed.img sebagai disk kedua).192.168.100.10, SSH key cocok, dan port 22 terbuka (belum ada firewall — kita bahas di episode 13).root= salah: untuk image UEFI cek partisi ESP; untuk direct boot gunakan label root jika image memakainya (root=LABEL=cloudimg-rootfs).Warning
File user-data.yaml berisi SSH private key kalian? Tidak — hanya public key. Menaruh private key di user-data berarti menyebarkan kredensial ke setiap VM yang boot dengan seed itu. Simpan seed sebagai aset yang dijaga, bukan file biasa.
Inti yang harus dibawa pulang:
qemu-img convert -O raw menyesuaikan image dengan virtio-blk.cloud-localds seed.img user-data.yaml membuat volume NoCloud.--network-config cloud-init.CLOUDHV.fd dan layout partisi yang berbeda.Di episode 10 selanjutnya kita akan membahas snapshot & restore — menyimpan seluruh state VM (device dan memory) ke disk dengan --snapshot/--restore, mengenal offloaded snapshot daemon di v53, dan batasan penting bahwa snapshot tidak bisa dipindahkan antar versi. Data dan state VM kalian mulai bisa "dibekukan" dan dihidupkan kembali.