Hướng dẫn cài đặt và sử dụng KVM trên Ubuntu: Từ zero đến chạy máy ảo đầu tiên

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

Vấn đề: Cần chạy máy ảo trên Linux server mà không có GUI

Bạn muốn test một distro mới, dựng môi trường sandbox để thử script nguy hiểm, hoặc cần chạy song song nhiều hệ thống cùng lúc. VirtualBox là lựa chọn quen thuộc — nhưng trên server Ubuntu không màn hình thì cài VirtualBox để làm gì? Và ngay cả khi có màn hình, VirtualBox thường bị lỗi module sau mỗi lần update kernel — phải chạy lại sudo /sbin/vboxconfig là chuyện mình gặp đến chán.

Mình đang chạy homelab với Proxmox VE quản lý 12 VM và container — đây là playground để test mọi thứ trước khi đưa lên production. Proxmox thực chất xây trên KVM. Vậy tại sao không dùng thẳng KVM trên Ubuntu khi cần setup gọn nhẹ hơn, không phải cài thêm cả một distro riêng?

Phân tích: KVM khác VirtualBox ở điểm nào quan trọng?

KVM (Kernel-based Virtual Machine) là hypervisor loại 1, chạy thẳng trên phần cứng qua CPU virtualization extension (Intel VT-x hoặc AMD-V). Nó được tích hợp vào Linux kernel từ phiên bản 2.6.20 — tức là đã có mặt trên mọi distro modern mà không cần cài thêm gì. VirtualBox thì khác: hypervisor loại 2, hoạt động như ứng dụng bình thường trên host OS, có thêm một lớp overhead ở giữa.

Ba lý do mình chuyển hẳn sang KVM thay vì VirtualBox cho server:

  • Hiệu năng sát native: VM chạy qua KVM có thể đạt 95–98% hiệu năng so với máy thật, đặc biệt với disk I/O và network khi dùng virtio driver
  • Không bị break sau kernel update: KVM là module kernel chính thức, không phải DKMS module bên ngoài như VirtualBox — update kernel xong vẫn chạy bình thường
  • Quản lý linh hoạt: virsh (CLI), virt-manager (GUI), Cockpit (web UI) — tùy môi trường mà chọn tool phù hợp

Các bước cài đặt KVM trên Ubuntu

Bước 1: Kiểm tra CPU có hỗ trợ hardware virtualization

Skip bước này, cài xong mới biết CPU không hỗ trợ — mất công từ đầu:

egrep -c '(vmx|svm)' /proc/cpuinfo

Kết quả lớn hơn 0 là được. Ra 0 thì cần vào BIOS bật VT-x (Intel) hoặc AMD-V. Cách xem rõ ràng hơn:

sudo apt install cpu-checker -y
kvm-ok

Output mong đợi: KVM acceleration can be used.

Bước 2: Cài đặt KVM và các công cụ đi kèm

sudo apt update
sudo apt install -y \
  qemu-kvm \
  libvirt-daemon-system \
  libvirt-clients \
  bridge-utils \
  virtinst \
  virt-manager

Mỗi package có vai trò riêng:

  • qemu-kvm: engine chính để emulate phần cứng và chạy VM
  • libvirt-daemon-system: daemon quản lý VM qua Unix socket, cung cấp API thống nhất
  • libvirt-clients: bộ CLI gồm virsh — lệnh chính dùng hàng ngày
  • bridge-utils: cần nếu muốn VM lấy IP trực tiếp trên LAN (bridge network)
  • virtinst: cung cấp virt-installvirt-clone
  • virt-manager: GUI quản lý VM (chỉ cần nếu có desktop environment)

Bước 3: Thêm user hiện tại vào group libvirt và kvm

Không làm bước này, mọi lệnh virsh đều phải gõ sudo — khá phiền:

sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER

Sau đó logout và login lại. Muốn áp dụng ngay mà không cần logout:

newgrp libvirt

Bước 4: Đảm bảo libvirt daemon đang chạy

sudo systemctl enable --now libvirtd
systemctl status libvirtd

Status active (running) là ổn. Lần đầu cài, default NAT network của libvirt (virbr0) chưa tự start — cần bật thủ công:

virsh net-list --all
virsh net-start default
virsh net-autostart default

Cách tốt nhất: Tạo và quản lý VM bằng virsh + virt-install

Tạo VM đầu tiên từ ISO

Download ISO trước (ví dụ Ubuntu Server 22.04), rồi chạy virt-install:

virt-install \
  --name ubuntu-test \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/ubuntu-test.qcow2,size=20,format=qcow2 \
  --os-variant ubuntu22.04 \
  --network network=default \
  --graphics none \
  --console pty,target_type=serial \
  --location /home/user/ubuntu-22.04-live-server-amd64.iso \
  --extra-args 'console=ttyS0,115200n8 serial'

Ba tham số hay gây nhầm lẫn:

  • --disk format=qcow2: disk động — file trên host chỉ chiếm dung lượng thực sự đang dùng, không chiếm đủ 20GB ngay
  • --os-variant ubuntu22.04: KVM dùng thông tin này để optimize settings (IO scheduler, clock, etc.) — sai OS variant có thể ảnh hưởng hiệu năng. Xem danh sách: osinfo-query os | grep ubuntu
  • --graphics none --console pty: serial console thay vì VNC/SPICE — phù hợp server không có màn hình, SSH vào quản lý từ xa

Các lệnh virsh dùng hàng ngày

# Xem danh sách VM (kể cả đang tắt)
virsh list --all

# Bật / tắt VM
virsh start ubuntu-test
virsh shutdown ubuntu-test    # Tắt an toàn (gửi ACPI signal)
virsh destroy ubuntu-test     # Tắt cứng (như rút điện)

# Kết nối vào console
virsh console ubuntu-test
# Thoát console: Ctrl + ]

# Snapshot trước khi làm gì đó rủi ro
virsh snapshot-create-as ubuntu-test snap-before-upgrade
virsh snapshot-revert ubuntu-test snap-before-upgrade
virsh snapshot-list ubuntu-test

# Xóa VM và toàn bộ disk
virsh undefine ubuntu-test --remove-all-storage

Clone VM — tiết kiệm thời gian đáng kể

Cài từ đầu mỗi lần cần VM mới rất tốn thời gian. Cách làm thực tế hơn: chuẩn bị một VM “base” đã có OS và các package cơ bản, rồi clone khi cần. virt-clone xong trong vài chục giây thay vì cả tiếng cài OS:

# Tắt VM gốc trước
virsh shutdown ubuntu-base

# Clone
virt-clone \
  --original ubuntu-base \
  --name ubuntu-clone-1 \
  --auto-clone

Sau khi clone, SSH vào VM mới và đổi hostname + regenerate SSH host key:

sudo hostnamectl set-hostname ubuntu-clone-1
sudo rm /etc/ssh/ssh_host_*
sudo dpkg-reconfigure openssh-server

Xem tài nguyên và resize disk

# Monitor real-time CPU/RAM của các VM
virt-top

# Xem disk images đang có
virsh vol-list --pool default

# Resize disk (VM phải tắt trước)
sudo qemu-img resize /var/lib/libvirt/images/ubuntu-test.qcow2 +10G
# Sau đó vào trong VM chạy growpart + resize2fs để OS nhận disk mới

Lỗi thường gặp và cách xử lý

virsh báo “permission denied” dù đã add group

Nguyên nhân hay gặp nhất: chưa logout/login sau khi usermod. Chạy groups mà không thấy libvirt trong output — đó là vấn đề. Fix nhanh không cần logout:

newgrp libvirt
virsh list --all

VM tạo xong nhưng boot lên màn hình đen

Thường do --os-variant không đúng. Với distro mới, libvirt cũ có thể chưa có entry — dùng osinfo-query os | grep ubuntu để xem tên chính xác. Không tìm thấy thì dùng --os-variant linux2022 thay thế.

Không ping được từ VM ra ngoài internet

Default network dùng NAT — kiểm tra xem default network có đang chạy không:

virsh net-list --all
# Nếu thấy "default" ở trạng thái "inactive":
virsh net-start default

Bridge network là bước tiếp theo nếu VM cần IP riêng trên cùng dải LAN với host. Nhưng với mục đích lab và test, NAT mặc định là đủ — đơn giản, không cần đụng đến cấu hình mạng của host.

Share: