Hướng dẫn sử dụng libvirt để quản lý máy ảo KVM từ command line (virsh)

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

Bối cảnh: Khi production VM treo lúc 2 giờ sáng

2:17 sáng. Điện thoại rung — khách hàng báo web app không respond. SSH vào hypervisor host, không có GUI, không có web panel, chỉ có terminal trắng tinh. Đây là lúc mình nhận ra: biết virsh hay không là ranh giới giữa fix xong đi ngủ tiếp và ngồi mò đến sáng.

Mình chạy homelab với Proxmox VE quản lý 12 VM và container — playground để test mọi thứ trước khi đưa lên production. Proxmox có web UI tiện, nhưng bên dưới nó vẫn dùng libvirt và QEMU. Trên bare-metal server thuê ở data center, thứ duy nhất mình có là SSH và virsh. Bài này ghi lại những gì thực sự dùng được trong production — không phải lý thuyết sách vở.

Nói nhanh về kiến trúc: libvirt là lớp trừu tượng hóa trên KVM/QEMU — thay vì gọi thẳng QEMU với cả trang tham số khó nhớ, bạn dùng libvirt API cho gọn. virsh (virtualization shell) là CLI client của libvirt, thứ mình gõ vào terminal lúc 2 giờ sáng đó. Tại sao phải học virsh thay vì dùng GUI mãi?

  • Remote server không có desktop environment
  • Script automation: snapshot trước mỗi deployment, backup định kỳ
  • Debug VM treo khi web UI của management tool cũng không vào được
  • Quản lý 10+ VM cùng lúc: 1 lệnh loop là xong hết, không phải click từng cái

Cài đặt libvirt và các công cụ liên quan

Trước khi cài, kiểm tra CPU có hỗ trợ virtualization không:

grep -E '(vmx|svm)' /proc/cpuinfo | head -1
# vmx = Intel VT-x, svm = AMD-V
# Nếu output rỗng → BIOS chưa bật VT, vào BIOS enable trước

Cài đặt trên Ubuntu/Debian:

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

# Kiểm tra KVM load được không
sudo kvm-ok
# Expected: INFO: /dev/kvm exists — KVM acceleration can be used

Trên CentOS/RHEL/AlmaLinux:

sudo dnf install -y qemu-kvm libvirt libvirt-client virt-install virt-top
sudo systemctl enable --now libvirtd

Thêm user vào group libvirt để dùng virsh không cần sudo:

sudo usermod -aG libvirt,kvm $USER
newgrp libvirt  # Apply ngay mà không cần logout

Từ tạo VM đến vận hành hàng ngày

Tạo VM đầu tiên bằng virt-install

Cách nhanh nhất để tạo VM từ ISO:

sudo virt-install \
  --name ubuntu-server-01 \
  --ram 2048 \
  --vcpus 2 \
  --disk path=/var/lib/libvirt/images/ubuntu-server-01.qcow2,size=20,format=qcow2 \
  --os-variant ubuntu22.04 \
  --network bridge=virbr0 \
  --graphics none \
  --console pty,target_type=serial \
  --location 'http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/' \
  --extra-args 'console=ttyS0,115200n8 serial'

# Xem danh sách os-variant hợp lệ:
osinfo-query os | grep ubuntu

Hoặc nếu đã có sẵn cloud image — nhanh hơn cài từ ISO khoảng 15 phút, đây là cách mình hay dùng:

# Download Ubuntu 22.04 cloud image
wget -O /var/lib/libvirt/images/ubuntu-22.04-base.qcow2 \
  https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

# Tạo VM từ base image (copy-on-write, tiết kiệm disk)
sudo qemu-img create -f qcow2 -b /var/lib/libvirt/images/ubuntu-22.04-base.qcow2 \
  -F qcow2 /var/lib/libvirt/images/vm-test.qcow2 20G

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

Chia thành nhóm cho dễ nhớ:

Xem trạng thái VM:

virsh list --all           # Xem tất cả VM (running + stopped)
virsh dominfo ubuntu-server-01   # Thông tin chi tiết 1 VM
virsh domstate ubuntu-server-01  # Chỉ xem trạng thái
virsh vcpuinfo ubuntu-server-01  # CPU affinity và usage
virsh dommemstat ubuntu-server-01  # Memory stats realtime

Start/Stop VM:

virsh start ubuntu-server-01      # Bật VM
virsh shutdown ubuntu-server-01   # Tắt graceful (gửi ACPI signal)
virsh destroy ubuntu-server-01    # Force off — dùng khi VM treo, không respond
virsh reboot ubuntu-server-01     # Reboot graceful
virsh reset ubuntu-server-01      # Hard reset (tương đương bấm nút reset)

Lệnh mình dùng lúc 2 giờ sáng hôm đó:

# VM không respond gì cả — thử graceful trước
virsh shutdown production-web-01
# Chờ 30s, nếu không tắt:
virsh destroy production-web-01
# Bật lại
virsh start production-web-01
# Theo dõi console để xem boot log
virsh console production-web-01
# Thoát console: Ctrl+]

Snapshot — tính năng cứu mình nhiều nhất

Trước mỗi lần deploy hoặc update hệ thống, mình luôn snapshot. Tốn 10 giây nhưng tiết kiệm cả tiếng rollback thủ công nếu có sự cố:

# Tạo snapshot (VM phải đang chạy hoặc đã tắt)
virsh snapshot-create-as ubuntu-server-01 \
  --name "before-nginx-upgrade" \
  --description "Snapshot trước khi upgrade nginx 1.24" \
  --atomic

# Xem danh sách snapshot
virsh snapshot-list ubuntu-server-01

# Xem thông tin chi tiết snapshot
virsh snapshot-info ubuntu-server-01 before-nginx-upgrade

# Rollback về snapshot cũ (khi upgrade lỗi)
virsh snapshot-revert ubuntu-server-01 before-nginx-upgrade

# Xóa snapshot không cần nữa
virsh snapshot-delete ubuntu-server-01 before-nginx-upgrade

Clone VM

Clone nhanh hơn cài từ đầu khoảng 20 phút — tiện khi cần spin up VM test nhanh hoặc nhân bản môi trường staging:

# Tắt VM gốc trước khi clone
virsh shutdown ubuntu-server-01

# Clone
sudo virt-clone \
  --original ubuntu-server-01 \
  --name ubuntu-server-02 \
  --auto-clone

# Clone với disk path tùy chỉnh
sudo virt-clone \
  --original ubuntu-server-01 \
  --name ubuntu-server-02 \
  --file /var/lib/libvirt/images/ubuntu-server-02.qcow2

Quản lý Storage Pool

Mặc định libvirt lưu disk image vào /var/lib/libvirt/images/. Khi có thêm SSD riêng hoặc NAS mount, tạo storage pool trỏ vào đó để tận dụng tốc độ:

# Xem pool hiện có
virsh pool-list --all

# Tạo pool mới trỏ vào thư mục tùy chỉnh
virsh pool-define-as ssd-pool dir --target /mnt/ssd/libvirt/images
virsh pool-build ssd-pool
virsh pool-start ssd-pool
virsh pool-autostart ssd-pool

# Xem volume trong pool
virsh vol-list default

# Lấy path thực của disk image
virsh vol-path --pool default ubuntu-server-01.qcow2

# Resize disk VM (VM phải tắt)
virsh vol-resize --pool default ubuntu-server-01.qcow2 30G

Chỉnh sửa cấu hình VM

# Mở XML config để edit (dùng EDITOR mặc định)
virsh edit ubuntu-server-01

# Thay đổi RAM không cần tắt VM (nếu balloon driver hỗ trợ)
virsh setmem ubuntu-server-01 4096M --live --config

# Thêm CPU
virsh setvcpus ubuntu-server-01 4 --live --config

# Autostart khi host reboot
virsh autostart ubuntu-server-01
virsh autostart --disable ubuntu-server-01  # Tắt autostart

Kiểm tra và Monitoring

Xem resource usage realtime

virt-top là lệnh đầu tiên mình gõ khi nghi VM nào đó đang ăn quá nhiều CPU hoặc RAM:

# Top-like cho VM — cực kỳ hữu ích
virt-top

# Stats tất cả VM đang chạy
virsh domstats --live

# CPU stats của 1 VM cụ thể
virsh cpu-stats ubuntu-server-01 --total

# I/O stats disk
virsh domblkstat ubuntu-server-01 vda

# Network stats
virsh domifstat ubuntu-server-01 vnet0

Kiểm tra log khi VM có vấn đề

# Log của libvirtd daemon
sudo journalctl -u libvirtd -f

# Log QEMU của từng VM (rất chi tiết, dùng khi debug)
sudo cat /var/log/libvirt/qemu/ubuntu-server-01.log | tail -50

# Kiểm tra VM XML config hiện tại (bao gồm runtime info)
virsh dumpxml ubuntu-server-01

# Kiểm tra kết nối libvirt OK không
virsh -c qemu:///system version

Script backup nhanh cho tất cả VM

Script này đã cứu mình ít nhất 3 lần — lần gần nhất là khi kernel update làm một VM không boot được. Chạy hàng đêm trước khi thử nghiệm bất cứ cấu hình mới nào:

#!/bin/bash
# snapshot-all.sh — Snapshot tất cả VM đang chạy
SNAP_NAME="daily-$(date +%Y%m%d)"

for vm in $(virsh list --name --state-running); do
  echo "Snapshotting $vm..."
  virsh snapshot-create-as "$vm" \
    --name "$SNAP_NAME" \
    --description "Auto daily snapshot" \
    --atomic && echo "OK: $vm" || echo "FAILED: $vm"
done

echo "Done. Snapshots:"
virsh snapshot-list --all 2>/dev/null || true

Một số lỗi hay gặp

Ba lỗi này xuất hiện thường xuyên nhất khi mới setup — và cũng hay tái xuất sau system update:

Lỗi: error: Failed to connect socket to '/var/run/libvirt/libvirt-sock'

sudo systemctl start libvirtd
# Hoặc kiểm tra socket:
ls -la /var/run/libvirt/

Lỗi: error: Cannot access storage file khi start VM

# Kiểm tra quyền file
ls -la /var/lib/libvirt/images/
# Fix quyền
sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/*.qcow2
sudo chmod 660 /var/lib/libvirt/images/*.qcow2

VM tắt không được (shutdown timeout):

# Tăng timeout shutdown trong /etc/libvirt/qemu.conf:
# shutdown_timeout = 60  (giây)
# Sau đó restart libvirtd
sudo systemctl restart libvirtd

Sau cái đêm 2 giờ sáng đó, mình đã viết toàn bộ những lệnh này vào một file virsh-cheatsheet.md để trên server. Không phải vì không nhớ được — mà vì lúc đang stress, nhìn cheatsheet nhanh hơn Google nhiều.

Share: