Trước khi bắt đầu
Cấu hình tối thiểu cho lab
Lộ trình này chạy hết trên VM. Trang này nói lab cần gì, vì sao cần, và phase nào là phase làm phát sinh yêu cầu đó — để không phải nâng cấp giữa chừng.
Không cần máy mạnh. Cần đúng vài thứ, và biết trước thứ nào sẽ chặn phase nào.
Bảng yêu cầu
| Hạng mục | Tối thiểu | Khuyến nghị | Phase nào cần |
|---|---|---|---|
| CPU | x86_64 có VT-x (Intel) hoặc AMD-V, bật trong BIOS | thêm EPT/NPT cho MMU virtualization | P1 trở đi |
| RAM | 8 GB | 16 GB | 8GB đủ 1 VM; VXLAN cần 2 VM cùng lúc |
| Đĩa trống | 30 GB | 60 GB trên SSD | cloud image + overlay của nhiều VM |
| Block device rời | 1 | 2 ổ rời ngoài ổ hệ thống | lab LVM |
| Swap | có swap thật, ≥ 2 GB | 4 GB | lab vm.swappiness |
| cgroup | v2 unified | — | lab cgroup, container tự viết |
| Máy thứ hai | không bắt buộc | một máy nữa có /dev/kvm | lab VXLAN qua mạng thật |
Kiểm nhanh ba thứ đầu:
$ ls -l /dev/kvm # không có ⇒ VT-x chưa bật trong BIOS
$ lscpu | grep -iE 'vmx|svm|ept|npt'
$ stat -fc %T /sys/fs/cgroup # phải là cgroup2fs
$ swapon --show # trống ⇒ chưa có swap
$ lsblk -d -o NAME,SIZE,ROTA,MODEL # ROTA=1 là đĩa quay
Vì sao nên là bare metal
Chạy lab trong một VM lồng VM (nested) hoạt động được cho gần hết lộ trình, nhưng hỏng đúng ở phase quan trọng nhất.
Phase 6 dùng perf record để lấy sampling profile và vẽ flame graph. perf đọc PMU — bộ đếm hiệu năng của CPU, thứ đếm cache miss, branch miss, cycle. Phần lớn hypervisor không phơi PMU cho guest, hoặc chỉ phơi một phần. Kết quả là perf chạy nhưng số liệu vô nghĩa, và bài học “average vô dụng, phải nhìn percentile” không hiện ra được.
Kiểm PMU có thật hay không, ngay trong máy sắp dùng:
$ perf stat -e cycles,instructions,cache-misses true
# <not supported> hoặc <not counted> ở cột số ⇒ không có PMU thật
$ ls /sys/bus/event_source/devices/ # chỉ thấy 'software' ⇒ tương tự
Với các phase còn lại — process, memory, filesystem, namespace, network — nested chạy tốt và chênh lệch chỉ là tốc độ.
Không dùng máy production làm host lab. Lộ trình này cố tình phá hệ thống: giới hạn memory tới mức OOM, làm hỏng initramfs, sửa ruleset netfilter, wipe block device. Một máy cũ, một máy để không, hay một máy thuê rẻ đều được — miễn là hỏng nó không ảnh hưởng đến ai.
Đĩa: vì sao cần hai block device rời
Phase 3 có lab LVM. Với một PV thì chỉ tạo được VG đơn giản, và bỏ mất hai thứ chỉ xuất hiện khi có nhiều PV:
pvmove— dời extent đang dùng từ ổ này sang ổ khác trong lúc LV vẫn online. Đây là thao tác thay ổ mà không downtime, và là lý do chính người ta dùng LVM.- LV trải trên nhiều device,
vgextendđể nới VG khi hết chỗ.
Không có ổ rời thì dùng loop device trên file được — lab vẫn chạy, chỉ mất phần “block device thật hành xử khác file” (queue depth, scheduler, latency).
Nếu có sẵn một HDD quay và một SSD trên cùng máy thì giữ lại cả hai. Phase 6 chạy cùng một workload fio trên hai ổ rồi so distribution latency — bài học về percentile hiện ra rõ hơn mọi biểu đồ trong sách. Không có thì thay bằng cách gây tải song song trên cùng một ổ, kém sắc nét hơn nhưng vẫn thấy được hình.
Phân bổ đĩa gợi ý
| Vai trò | Đặt ở đâu | Phase dùng tới |
|---|---|---|
Storage pool libvirt (/var/lib/libvirt/images) | ổ hệ thống, ưu tiên SSD | toàn bộ, từ P1 |
| Hai PV cho lab LVM | hai block device rời, hoặc hai loop device | Phase 3 |
Ổ để gây tải fio/biolatency | ổ nào cũng được, HDD thì bài học rõ hơn | Phase 6 |
Trên Ubuntu, AppArmor giới hạn cả QEMU lẫn virt-aa-helper — chương trình sinh profile cho từng VM. Profile của helper cho phép đọc /var/lib/libvirt/images/** tường minh, nhưng chặn thẳng mọi thứ nằm trong thư mục ẩn của home. Để cloud image ở ~/.local/share/… là gặp Permission denied mà ls -l nhìn hoàn toàn bình thường. Chi tiết cơ chế nằm trong mục Bẫy của Phiên 1.
Host OS: distro nào cũng được, nhưng biết mình đang ở đâu
Lab không phụ thuộc distro của host. Nhưng hai họ distro khác nhau ở ba chỗ đủ để một chuỗi lệnh copy từ blog gãy ngay dòng đầu:
| Debian / Ubuntu | Arch / Fedora / RHEL / openSUSE | |
|---|---|---|
| Kiến trúc daemon | monolithic libvirtd | modular: virtqemud, virtnetworkd, virtstoraged… |
| Cần enable | .service | .socket (socket activation) |
Network default | thường active sẵn sau khi cài | thường phải net-start + net-autostart tay |
| AppArmor / SELinux | AppArmor bật mặc định, có profile riêng mỗi VM | Arch thường không có; RHEL dùng SELinux |
Đây không phải chi tiết vụn — nó là bài học đầu tiên của lộ trình về chuyện “cùng một virsh nói chuyện với hai kiến trúc daemon khác nhau”. Xem ghi chú đính chính để biết chiều nào là chiều nào, vì rất nhiều tài liệu nói ngược.
Guest: chốt 24.04 noble
Guest mặc định là Ubuntu 24.04 noble, kể cả khi host mới hơn. Ba lý do:
- Mẫu số chung thấp hơn. Thứ học trên 24.04 áp lên bản mới gần như luôn đúng; chiều ngược lại thì không. Dựa vào behavior chỉ có ở kernel mới rồi ssh vào một máy LTS cũ lúc có sự cố là hụt tay đúng lúc cần nhất — và máy cũ mới là máy hay phải debug.
- Không mất nội dung nào. 24.04 đã có cgroup v2 unified,
iptables-nft, và BTF sẵn chobpftrace. - Host và guest có vai trò khác nhau. Host chỉ làm hypervisor nên version mới là lợi (libvirt/QEMU mới hơn). Guest mới là nơi học, nên nó nên khớp với loại máy mình thật sự phải vận hành.
Script lab-reset.sh ở Phase 0 nên nhận release làm tham số — tách phần image nào khỏi phần dựng thế nào. Khi cần tái dựng một sự cố có thật, guest phải khớp version của máy gặp sự cố, không thì có thể không tái hiện được.
Máy thứ hai cho lab VXLAN
Phase 5 có một lab dựng VXLAN tunnel giữa hai máy vật lý khác nhau, cho hai netns ở hai đầu ping nhau. Chạy cả hai đầu trên cùng một máy vẫn học được cơ chế, nhưng mất phần thú vị nhất: MTU và phân mảnh chỉ hiện ra khi gói tin đi qua mạng thật.
Đầu thứ hai không cần mạnh — một VM cloud rẻ nhất có /dev/kvm là đủ.
Gói VXLAN đi thô trên UDP 4789. Nếu dựng tunnel qua internet, giới hạn source IP ở firewall của provider — đừng mở 4789 cho cả thế giới. Đây cũng chính là lý do các overlay network production đều bọc thêm một lớp (IPsec, WireGuard); lab để trần là để nhìn thấy gói tin, không phải để dùng thật.
Cách làm việc
Một tmux session, mọi thứ chạy trong đó. Nếu host lab là máy khác và vào bằng ssh, mở tmux trước cả khi cài gói. Rớt mạng giữa lúc VM đang boot mà không có tmux là mất phiên console, và ở Phase 0 thì phiên console chính là thứ đang học.
Tạo user thường, thêm vào group libvirt và kvm. Chạy bằng root bỏ qua toàn bộ phần quyền của phiên đầu — group nào cho quyền gì, vì sao phải đăng nhập lại, qemu:///system khác qemu:///session ra sao. Đó là nội dung học, không phải thủ tục hành chính. Về sau lỗi quyền sẽ khó thấy vì root che hết.
Một cách làm nên tránh: điều khiển libvirt từ xa bằng virt-install --connect qemu+ssh://host/system. Mọi đường dẫn — cloud image, user-data, disk qcow2 — được daemon phía xa resolve trên filesystem của nó, nên liên tục vướng cảnh “file ở máy A, daemon tìm ở máy B”. Cứ ssh vào host lab rồi chạy tại chỗ.
Checklist trước phiên đầu tiên
ls /dev/kvmtồn tại, và user thường đọc/ghi được.lscpucó cờvmx(Intel) hoặcsvm(AMD).stat -fc %T /sys/fs/cgrouptrả vềcgroup2fs.swapon --showcó ít nhất một dòng.- User thường đã ở trong group
libvirtvàkvm, và đã đăng nhập lại sau khi thêm. - Còn ít nhất 30 GB trống ở nơi đặt storage pool.
- Nếu vào bằng ssh:
tmuxđã cài.
Xong checklist thì sang Phiên 1.