So sánh các giải pháp cấp phát card mạng cho máy ảo KVM
Nghẽn mạng ở tầng hypervisor là rào cản lớn nhất khi bạn chạy database chịu tải cao hay gateway xử lý hàng triệu gói tin trên KVM. Hiện nay, hệ sinh thái Linux cung cấp 3 cơ chế cấp phát card mạng chính cho máy ảo:
- Linux Bridge / Open vSwitch (VirtIO-Net): Mô hình mạng ảo hóa mặc định. Gói tin phải đi qua network stack của host OS, vhost-net rồi mới tới VM. Cách này linh hoạt và hỗ trợ Live Migration mượt mà. Đổi lại, độ trễ thường dao động từ 25 – 50µs do CPU host phải liên tục switch context.
- PCIe Passthrough toàn bộ NIC: Bàn giao trực tiếp cả card mạng vật lý cho một VM duy nhất. Hiệu năng đạt 100% bare-metal. Tuy nhiên, giải pháp này cực kỳ tốn kém vì mỗi cổng vật lý chỉ phục vụ đúng một máy ảo.
- SR-IOV (Single Root I/O Virtualization): Chuẩn mở rộng của PCI-SIG cho phép chia tách một cổng vật lý (Physical Function – PF) thành hàng chục card ảo độc lập ở tầng phần cứng (Virtual Functions – VF). Mỗi VF được gán thẳng vào VM qua IOMMU/VFIO. Gói tin đi thẳng vào phần cứng, hoàn toàn bypass kernel của host.
So sánh chi tiết các thông số kỹ thuật
Bảng dưới đây tổng hợp các tiêu chí vận hành thực tế giữa ba phương án:
| Tiêu chí | VirtIO-Net (Bridge) | PCIe Passthrough | SR-IOV (VFIO) |
|---|---|---|---|
| Throughput & PPS | Bị giới hạn bởi xung nhịp CPU host | 100% tốc độ dây cáp (Line-rate) | Đạt ~98-99% tốc độ phần cứng |
| Độ trễ (Latency) | Cao (25 – 50 µs) | Cực thấp (< 2 µs) | Rất thấp (1.5 – 3 µs) |
| Mức chiếm dụng CPU Host | Chiếm 15-30% khi traffic đạt 5-10 Gbps | Gần như 0% | Gần như 0% |
| Mật độ VM chia sẻ | Không giới hạn | 1 VM / 1 Cổng vật lý | 8 – 64+ VF tùy dòng chip NIC |
| Live Migration | Hỗ trợ sẵn theo KVM | Không hỗ trợ | Cần cấu hình failover kèm VirtIO |
Khi nào dự án thực sự cần tới SR-IOV?
Với web server hoặc REST API thông thường, VirtIO-Net vẫn là lựa chọn cân bằng nhất về độ tiện lợi. Bạn chỉ nên chuyển sang SR-IOV trong các kịch bản sau:
- Ứng dụng mạng mật độ gói tin cao: Cụm 5G Core (UPF), WebRTC media gateway, DNS resolver công cộng hay sàn giao dịch tài chính cần đẩy trên 10 triệu PPS.
- Hệ quản trị CSDL phân tán: Cụm Redis Cluster, ScyllaDB hoặc PostgreSQL replicate liên tục và yêu cầu latency microsecond ổn định không bị jitter.
- Tối ưu chi phí hạ tầng: Tận dụng một card Intel X710/E810 25GbE để cấp đường truyền tốc độ cao cho 16-32 VM cùng lúc mà không làm nghẽn CPU host.
Quy trình cấu hình SR-IOV từng bước trên Linux KVM
Bước 1: Kích hoạt IOMMU trong BIOS và Linux Kernel
Truy cập BIOS/UEFI của máy chủ. Bạn bật mục Intel VT-d (hoặc AMD IOMMU) cùng cờ SR-IOV Global Enable.
Tiếp theo, cấu hình kernel parameters trên Host OS bằng cách chỉnh sửa GRUB:
sudo nano /etc/default/grub
Bổ sung tham số IOMMU vào biến GRUB_CMDLINE_LINUX_DEFAULT. Cờ iommu=pt giúp tăng tốc bằng cách bỏ qua việc translate địa chỉ với các thiết bị không passthrough:
# Dành cho CPU Intel
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"
# Dành cho CPU AMD
# GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on iommu=pt"
Cập nhật lại GRUB rồi khởi động lại máy chủ:
sudo update-grub
sudo reboot
Sau khi máy lên, kiểm tra xem IOMMU đã hoạt động chuẩn chưa:
dmesg | grep -E "DMAR|IOMMU"
Bước 2: Cắt Virtual Functions (VF) từ cổng mạng vật lý
Xác định cổng mạng vật lý cần kích hoạt SR-IOV (ví dụ: enp4s0f0):
ip link show enp4s0f0
Kiểm tra số lượng VF tối đa mà chip mạng hỗ trợ:
cat /sys/class/net/enp4s0f0/device/sriov_totalvfs
Khởi tạo 4 Virtual Functions trên cổng này:
echo 4 | sudo tee /sys/class/net/enp4s0f0/device/sriov_numvfs
Kiểm tra danh sách các card ảo vừa được tạo ở tầng PCIe:
lspci | grep -i ethernet
Bước 3: Gán địa chỉ MAC tĩnh và kích hoạt Trust Mode
Việc gán MAC cố định ngay trên host giúp tránh tình trạng VF bị đổi MAC ngẫu nhiên mỗi lần reboot. Đồng thời, bật trust on sẽ cho phép VM chạy promiscuous mode hoặc tích hợp DPDK trơn tru:
# Gán MAC tĩnh và bật Trust mode cho VF 0
sudo ip link set enp4s0f0 vf 0 mac 52:54:00:11:22:33 trust on
# (Tùy chọn) Gán VLAN tag 100 nếu hạ tầng dùng trunking
sudo ip link set enp4s0f0 vf 0 vlan 100
Bước 4: Gán VF vào máy ảo KVM qua Libvirt
Tìm địa chỉ bus PCI của VF vừa cấu hình thông qua lspci (ví dụ: 0000:04:10.0):
lspci -s 04:10.0
Mở file XML cấu hình của máy ảo mục tiêu (ví dụ: db-prod-vm):
virsh edit db-prod-vm
Thêm khối định nghĩa <interface type='hostdev'> vào bên trong cặp thẻ <devices>:
<interface type='hostdev' managed='yes'>
<source>
<address type='pci' domain='0x0000' bus='0x04' slot='0x10' function='0x0'/>
</source>
<mac address='52:54:00:11:22:33'/>
</interface>
Khởi động máy ảo và truy cập console để xác thực:
virsh start db-prod-vm
virsh console db-prod-vm
Bên trong guest OS, lệnh ip a sẽ hiển thị interface mạng mới nhận driver trực tiếp từ hãng (như iavf cho Intel 700/800 series hoặc ixgbevf cho dòng X520/X540).
3 bài học xương máu khi vận hành SR-IOV trong production
Trong thực tế triển khai, hệ thống SR-IOV đôi khi xuất hiện lỗi rớt gói tin chập chờn (intermittent packet loss) vào giờ cao điểm dù băng thông chưa chạm ngưỡng. Dưới đây là cách xử lý triệt để 3 vấn đề phổ biến nhất:
- Tăng kích thước Ring Buffer trong Guest VM: Mặc định, driver VF chỉ cấp buffer nhận/gửi khoảng 256 đến 512 descriptors. Khi gặp đợt micro-burst traffic, card mạng sẽ drop packet ngay tại queue phần cứng. Hãy tăng RX/TX ring buffer trong VM lên mức tối đa (thường là 4096):
# Xem giới hạn ring buffer hiện tại
sudo ethtool -g eth1
# Đẩy buffer lên mức kịch khung
sudo ethtool -G eth1 rx 4096 tx 4096
- Tắt Spoof Checking khi chạy VIP / Keepalived: Nếu máy ảo dùng Virtual IP (Keepalived, VRRP, CARP), card vật lý sẽ chặn toàn bộ gói tin do cơ chế anti-spoofing phát hiện MAC/IP lạ. Hãy tắt kiểm tra giả mạo trên host cho VF đó:
sudo ip link set enp4s0f0 vf 0 spoofchk off
- Tự động khởi tạo VF sau khi reboot: Giá trị
sriov_numvfssẽ tự reset về 0 mỗi khi host khởi động lại. Giải pháp ổn định nhất là tạo một systemd service dạng oneshot để tự động nạp lại số lượng VF:
# Tạo file service /etc/systemd/system/sriov.service
[Unit]
Description=Tu dong khoi tao SR-IOV VFs khi boot
After=network.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo 4 > /sys/class/net/enp4s0f0/device/sriov_numvfs'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Kích hoạt service để cấu hình có hiệu lực vĩnh viễn:
sudo systemctl enable --now sriov.service

