SR-IOV trên Linux: Giảm thiểu Độ trễ và Giải phóng CPU cho các Tác vụ Ảo hóa

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

Nút thắt cổ chai lúc 2 giờ sáng

Đó là lúc 2 giờ sáng khi các dashboard Grafana chuyển sang màu đỏ rực. Một cụm cơ sở dữ liệu lưu lượng cao chạy trên các máy ảo KVM đang bị mất 15% gói tin, và độ trễ đã tăng vọt từ 2ms lên hơn 200ms. Trên máy chủ host, CPU không hề gặp khó khăn với các truy vấn cơ sở dữ liệu. Thay vào đó, tiến trình ksoftirqd bị treo ở mức 100% vì bridge Linux tiêu chuẩn không thể theo kịp tốc độ 2 triệu gói tin nhỏ mỗi giây. Stack mạng phần mềm đã trở thành một nút thắt cổ chai khổng lồ.

Single Root I/O Virtualization (SR-IOV) giải quyết vấn đề này bằng cách thay đổi cách chia sẻ phần cứng. Thay vì buộc hệ điều hành host phải mô phỏng một switch ảo, SR-IOV cho phép một card mạng vật lý (NIC) tự chia nhỏ thành nhiều phân đoạn ở cấp độ phần cứng. Các phân đoạn này hoạt động như các thiết bị PCIe độc lập. Bạn có thể chuyển trực tiếp chúng vào một VM, cho phép lưu lượng mạng bỏ qua hoàn toàn kernel của máy chủ host.

Trong môi trường vận hành (production), đây không chỉ là một lựa chọn xa xỉ. Đó là yêu cầu bắt buộc đối với các tác vụ hiệu suất cao như lõi mạng 5G viễn thông, nền tảng giao dịch tần suất cao hoặc mảng lưu trữ NVMe-over-Fabrics.

Bắt đầu nhanh: Kích hoạt SR-IOV trong 5 phút

Nếu bạn có card Intel X710 hoặc Mellanox ConnectX-5 hiện đại, bạn có thể triển khai việc này rất nhanh chóng. Dưới đây là các bước thực hiện nhanh cho các hệ thống dựa trên Ubuntu hoặc RHEL.

1. Bật IOMMU trong BIOS/UEFI

Đảm bảo VT-d (Intel) hoặc AMD-Vi (AMD) đã được bật trong BIOS của bạn. Điều này cho phép phần cứng ánh xạ bộ nhớ một cách an toàn cho các thiết bị ảo. Nếu không có tính năng này, kernel sẽ chặn mọi nỗ lực gán phần cứng trực tiếp cho máy khách (guest).

2. Cập nhật tham số khởi động Kernel

Bạn cần yêu cầu kernel Linux khởi tạo các driver IOMMU khi khởi động. Chỉnh sửa tệp /etc/default/grub và sửa đổi dòng GRUB_CMDLINE_LINUX_DEFAULT.

# Cho CPU Intel (ví dụ: Xeon Scalable)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on iommu=pt"

# Cho CPU AMD (ví dụ: EPYC)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash amd_iommu=on iommu=pt"

Cờ iommu=pt (pass-through) là cực kỳ quan trọng. Nó ngăn kernel cố gắng quản lý các thiết bị mà nó không cần thiết, giúp cải thiện hiệu suất tổng thể. Áp dụng các thay đổi và khởi động lại:

sudo update-grub
sudo reboot

3. Khởi tạo các Virtual Function (VF)

Xác định NIC vật lý của bạn bằng lệnh ip link. Trong ví dụ này, chúng ta sẽ sử dụng eno1. Để tạo 4 phân đoạn ảo, hãy ghi trực tiếp vào mục nhập sysfs của thiết bị PCI:

echo 4 | sudo tee /sys/class/net/eno1/device/sriov_numvfs

Chạy lệnh ip link show eno1. Bây giờ bạn sẽ thấy từ vf 0 đến vf 3 được liệt kê dưới giao diện chính, mỗi giao diện có địa chỉ MAC riêng biệt có thể gán được.

Kiến trúc: PF so với VF

Quản lý SR-IOV hiệu quả đòi hỏi việc hiểu rõ mối quan hệ giữa hai loại chức năng PCIe.

  • Physical Function (PF): Đây là thiết bị PCIe chính. Nó đóng vai trò là trình quản lý, xử lý cấu hình toàn cục và việc tạo/xóa các phân đoạn ảo.
  • Virtual Function (VF): Đây là các chức năng nhẹ, được hỗ trợ bởi phần cứng. Chúng không có khả năng quản lý nhưng xử lý việc di chuyển dữ liệu với hiệu suất cực cao.

Trong thiết lập bridge tiêu chuẩn, mọi gói tin đi từ đường dây, qua NIC, vào kernel của host và cuối cùng mới đến VM. Việc chuyển đổi ngữ cảnh (context switching) này tiêu tốn chu kỳ CPU. Với SR-IOV, switch phần cứng nội bộ của NIC sẽ xử lý việc định tuyến. Các gói tin di chuyển từ đường dây trực tiếp đến bộ nhớ của VM thông qua DMA (Direct Memory Access). Điều này giảm độ trễ từ khoảng 50-100 micro giây xuống còn dưới 10 micro giây.

Tối ưu hóa cho môi trường vận hành

Các lệnh echo thủ công sẽ không còn hiệu lực sau khi khởi động lại hệ thống. Để có môi trường vận hành ổn định, bạn cần một cấu hình bền vững.

Cấu hình bền vững qua Udev Rules

Tạo một quy tắc udev để đảm bảo các VF được tạo ngay khi phần cứng được phát hiện. Tạo tệp /etc/udev/rules.d/80-sriov.rules:

ACTION=="add", SUBSYSTEM=="net", KERNEL=="eno1", ATTR{device/sriov_numvfs}="8"

Gắn thẻ VLAN ở cấp độ phần cứng

Một lợi ích lớn của SR-IOV là đẩy việc gắn thẻ VLAN xuống phần cứng NIC. Điều này ngăn máy ảo khách nhìn thấy lưu lượng mạng mà nó không được phép. Bạn có thể thực thi việc này từ máy chủ host:

# Ép VF 0 vào VLAN 100
sudo ip link set eno1 vf 0 vlan 100

Gán VF cho KVM

Tìm địa chỉ PCI của VF bằng lệnh lspci | grep "Virtual Function". Nó sẽ có dạng như 04:10.0. Trong cấu hình XML của Libvirt, hãy thêm khối sau:

<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x04' slot='0x10' function='0x0'/>
  </source>
</hostdev>

Những bài học kinh nghiệm thực tế xương máu

Cấu hình SR-IOV thường gặp phải những vấn đề đặc thù của phần cứng. Dưới đây là ba sai lầm phổ biến cần tránh.

1. Rào cản khi Live Migration

Vì VM hiện đã được liên kết vật lý với một NIC cụ thể trên Host A, bạn không thể thực hiện live-migrate (di trú trực tiếp) nó sang Host B bằng các công cụ tiêu chuẩn. Để khắc phục, hãy sử dụng một failover bond bên trong máy khách. Kết hợp một giao diện VirtIO (để di trú) và một giao diện SR-IOV (để lấy tốc độ). Khi VM di chuyển, nó sẽ tạm thời chuyển sang driver VirtIO cho đến khi tìm thấy một VF mới trên máy chủ đích.

2. Cạn kiệt ngắt (Interrupt Exhaustion)

Mỗi VF yêu cầu các vector ngắt MSI-X. Nếu bạn cố gắng tạo 64 VF trên một card chỉ hỗ trợ 128 vector, trong khi máy chủ của bạn có 32 lõi CPU, bạn có thể bị cạn kiệt tài nguyên. Hầu hết các kỹ sư nhận thấy rằng 8 đến 16 VF cho mỗi cổng là “điểm cân bằng lý tưởng” để đảm bảo sự ổn định.

3. Cờ tin cậy (Trust Flag)

Theo mặc định, các VF bị hạn chế vì lý do bảo mật. Nếu VM của bạn cần chạy một trình điều phối container (orchestrator) hoặc thay đổi địa chỉ MAC của chính nó, bạn phải cấp quyền tin cậy một cách rõ ràng:

sudo ip link set eno1 vf 0 trust on

Lời kết

SR-IOV lấp đầy khoảng cách hiệu suất giữa máy ảo và máy chủ vật lý một cách hiệu quả. Mặc dù nó làm tăng độ phức tạp cho việc di trú và yêu cầu phần cứng cụ thể, nhưng lợi ích về hiệu suất là không thể phủ nhận. Trong các thử nghiệm của tôi bằng iperf3, việc chuyển từ bridge Linux sang SR-IOV đã giảm tải CPU của máy chủ đi 40% trong khi vẫn duy trì tốc độ ổn định 10Gbps. Nếu mạng đang là nút thắt cổ chai của bạn, đây là nơi đầu tiên bạn nên xem xét.

Share: