KubeVirt: Tuyệt chiêu chạy máy ảo ngay trên Kubernetes cho dân DevOps

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

Gom mọi thứ về một mối: Khi VM và Container ‘về chung một nhà’

Dân DevOps hẳn đã quá quen với cảnh: một tay múa kubectl điều khiển container, tay kia lại lọ mọ trên Proxmox hay VMware để quản lý máy ảo (VM) chạy database cũ. Việc duy trì hai hạ tầng tách biệt thế này cực kỳ ngốn tài nguyên và nhân lực. Trong homelab của mình, mình từng duy trì 12 VM chỉ để phục vụ các app legacy chưa thể container hóa, và việc nhảy qua nhảy lại giữa các Dashboard thực sự là một cực hình.

KubeVirt xuất hiện như một cứu cánh. Nó cho phép chúng ta chạy thẳng máy ảo KVM bên trong các Pod của Kubernetes. Giờ đây, anh em có thể dùng file YAML để định nghĩa một con Windows Server y hệt như cách khai báo một Nginx container đơn giản.

So sánh thực tế: Ảo hóa kiểu cũ vs Cloud Native Virtualization

Trước khi bắt tay vào gõ lệnh, hãy nhìn lại sự khác biệt cốt lõi để biết mình đang đứng ở đâu.

  • Ảo hóa truyền thống (Proxmox, ESXi): Máy ảo là “công dân hạng nhất”. Mạng và lưu trữ được thiết kế riêng cho VM. Nếu muốn chạy K8s, anh em phải cài nó chồng lên các VM này.
  • Cloud Native Virtualization (KubeVirt): Kubernetes đóng vai trò lớp nền (Underlay). VM lúc này trở thành một Resource (CRD) trong K8s. Nó thừa hưởng toàn bộ hệ sinh thái từ Scheduler, RBAC đến Monitoring (Prometheus) và Logging (Loki).

Thay vì đau đầu cấu hình VLAN riêng, VM giờ đây dùng chung dải mạng của Cluster qua Calico hoặc Cilium. Đây là điểm mấu chốt giúp sơ đồ mạng của anh em bớt rối rắm hơn hẳn.

KubeVirt có thực sự thần thánh? Những ưu nhược điểm cần sòng phẳng

Cái hay của KubeVirt

Điểm cộng lớn nhất là sự đồng nhất. Anh em dùng đúng một pipeline CI/CD, một hệ thống cảnh báo cho cả Pod và VM. Tiếp theo là khả năng tận dụng tài nguyên. K8s sẽ tự động đẩy VM vào node nào còn dư RAM/CPU, không cần anh em phải tính toán thủ công từng chút một.

Những gáo nước lạnh cần lưu ý

Vấn đề lớn nhất là hiệu năng. Vì VM chạy lồng trong Pod, nó phải gánh thêm một lớp abstraction. Dù có KVM hỗ trợ, overhead CPU thường rơi vào khoảng 5-10% so với chạy bare-metal. Ngoài ra, việc xử lý Storage cho VM trên K8s (như tạo Disk Image từ PVC) vẫn còn khá rườm rà so với vài cú click chuột trên Proxmox.

Khi nào thì nên “triển” KubeVirt?

Đừng vội vứt bỏ hệ thống VMware hiện tại. Theo kinh nghiệm của mình, hãy cân nhắc KubeVirt trong 3 trường hợp:

  1. Cần hiện đại hóa hạ tầng nhưng vướng vài module cũ chỉ chạy được trên Windows Server hoặc Kernel đặc thù.
  2. Muốn build nền tảng Self-service cho team Dev để họ tự tạo nhanh cả DB (VM) và App (Container) chỉ bằng một bộ YAML duy nhất.
  3. Bạn muốn quản lý mọi thứ qua GitOps và Kubernetes Custom Resources để đồng bộ hóa cấu hình toàn hệ thống.

Từng bước triển khai KubeVirt thực tế

Bước 1: Kiểm tra “nội công” của server

Node phải hỗ trợ ảo hóa phần cứng thì KubeVirt mới chạy mượt được. Anh em kiểm tra nhanh bằng lệnh:

virt-host-validate qemu

Nếu thấy dòng PASS hiện lên đều tăm tắp là ổn. Nếu nhận FAIL, anh em buộc phải dùng chế độ emulation (phần mềm), nhưng tốc độ sẽ chậm như rùa, chỉ nên dùng để vọc vạch cho biết.

Bước 2: Cài đặt KubeVirt Operator

Chúng ta sẽ dùng Operator để quản lý vòng đời KubeVirt một cách chuyên nghiệp nhất.

# Lấy phiên bản mới nhất từ GitHub
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest | grep tag_name | cut -d '"' -f 4)

# Cài đặt Operator và Custom Resource
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

Hãy pha một tách cà phê và đợi vài phút để các Pod trong namespace kubevirt sẵn sàng.

Bước 3: Trang bị công cụ điều khiển virtctl

Để tương tác sâu với VM như vào console hay start/stop, kubectl là chưa đủ. Anh em cần virtctl:

curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64
chmod +x virtctl
sudo mv virtctl /usr/local/bin/

Bước 4: Khởi tạo máy ảo đầu tiên

Đây là mẫu YAML để chạy một con Fedora “siêu nhẹ”. Chỉ mất khoảng 30 giây là nó có thể boot xong từ container image.

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: itfromzero-vm
spec:
  running: false 
  template:
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk: {}
          interfaces:
            - name: default
              masquerade: {}
        resources:
          requests:
            memory: 1024Mi
      networks:
        - name: default
          pod: {}
      volumes:
        - name: containerdisk
          containerDisk:
            image: kubevirt/fedora-cloud-container-disk-demo

Apply file xong, anh em đánh thức máy ảo bằng lệnh:

virtctl start itfromzero-vm

Mẹo nhỏ để không bị “ăn hành” khi làm thực tế

Lỗi phổ biến nhất mà anh em thường gặp là Storage Class không hỗ trợ ReadWriteMany (RWX). Nếu muốn Live Migration (chuyển VM giữa các node mà không downtime), lưu trữ phải được truy cập từ nhiều nơi cùng lúc. Đừng dùng local path trừ khi bạn chỉ muốn chạy test trên một node duy nhất.

Ngoài ra, hãy tìm hiểu thêm về CDI (Containerized Data Importer). Nó giúp anh em kéo file .qcow2 hay .iso trực tiếp từ URL vào thẳng PVC, tiện hơn nhiều so với việc build Docker image thủ công.

KubeVirt có thể không thay thế hoàn toàn được VMware hay Proxmox trong mọi kịch bản, nhưng nó là chìa khóa để đạt tới mô hình quản lý tập trung “Single Pane of Glass”. Chúc anh em build lab thành công, có vướng mắc gì cứ thoải mái để lại bình luận phía dưới nhé!

Share: