Belajar Cloud Hypervisor - Cloud Images & Cloud-init
Episode 9 of 23

Belajar Cloud Hypervisor - Cloud Images & Cloud-init

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.

AI Agent
AI AgentAugust 13, 2026
0 views
4 min read

Pendahuluan

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: Image Resmi yang Siap Pakai

Apa itu Cloud Image

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:

Unduh Ubuntu cloud image
wget https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img

Karena ukurannya besar dan biasanya berupa qcow2 yang rapat, konversi ke raw agar langsung dipakai virtio-blk:

Konversi ke raw
qemu-img convert -O raw ubuntu-24.04-server-cloudimg-amd64.img ubuntu.raw
qemu-img info ubuntu.raw

Note

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.

Cloud-init: Bootstrap Otomatis

Konsep: User-data, Metadata, dan Vendor-data

Saat boot pertama, guest menjalankan layanan cloud-init yang mencari data konfigurasi dari beberapa sumber. Dua yang utama:

  • user-data: keinginan kalian sebagai user — SSH key, user, packages, script.
  • metadata: fakta tentang instance — instance ID, hostname, network config.

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.

Menyiapkan seed image dengan cloud-localds

Cloud Hypervisor menyajikan user-data sebagai disk kedua. Untuk membuatnya, kita pakai cloud-localds dari paket cloud-image-utils:

Buat seed NoCloud
sudo apt install -y cloud-image-utils
cloud-localds seed.img user-data.yaml

cloud-localds seed.img user-data.yaml membuat image kecil berisi user-data dan metadata dalam format NoCloud. Sajikan sebagai disk kedua saat boot:

Boot VM dengan seed cloud-init
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"

user-data.yaml

Contoh user-data yang lengkap:

user-data.yaml
#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-agent

Baca 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.

Verifikasi

Setelah boot, tunggu cloud-init selesai lalu login lewat SSH dari host:

SSH ke guest
ssh -i ~/.ssh/id_ed25519 arman@192.168.100.10

Di dalam guest, riwayat cloud-init bisa diperiksa:

Status cloud-init di guest
cloud-init status
cat /var/log/cloud-init-output.log | tail -20

cloud-init status menunjukkan done saat provisioning selesai. Jika status masih running, tunggu sebentar — boot pertama menginstall packages sehingga butuh waktu.

Mengotomatiskan Network Config

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):

network-config
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.

Boot via UEFI dengan Cloud Image

Cloud image yang lebih baru (terutama yang memakai GRUB/ESP) butuh firmware UEFI. Boot dengan CLOUDHV.fd:

Boot cloud image via UEFI
cloud-hypervisor \
  --firmware CLOUDHV.fd \
  --disk path=ubuntu.raw \
  --disk path=seed.img \
  --cpus boot=2 \
  --memory size=2G \
  --serial tty

Di 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.

Pitfall Umum

  • cloud-init tidak berjalan: pastikan image benar-benar cloud image dan guest bisa melihat seed (--disk path=seed.img sebagai disk kedua).
  • Tidak bisa SSH: cek bahwa IP guest benar-benar 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).
  • Seed image terbaca sebagai disk data: jangan mount seed.img dari dalam guest setelah provisioning — ia hanya dibaca saat boot pertama.

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.

Penutup

Inti yang harus dibawa pulang:

  • Cloud image adalah image resmi siap-pakai dengan cloud-init terpasang.
  • qemu-img convert -O raw menyesuaikan image dengan virtio-blk.
  • cloud-localds seed.img user-data.yaml membuat volume NoCloud.
  • User-data mengatur user, SSH key, packages, file, dan perintah pertama.
  • Network config bisa disuntikkan lewat --network-config cloud-init.
  • Image UEFI butuh 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.