Cài đặt và cấu hình K3s trên các node Proxmox
Chuẩn bị môi trường và cài đặt K3s
Chúng ta sẽ chọn K3s thay vì KubeVirt cho phần này vì K3s nhẹ hơn, dễ cấu hình hơn cho các workload AI inference, và tích hợp sẵn nhiều tính năng cần thiết như CNI và Storage. KubeVirt tốt cho việc chạy VM trong K8s, nhưng ở đây chúng ta cần chạy container trực tiếp trên node để tối ưu GPU.
Trên mỗi VM Proxmox (1 Master và ít nhất 2 Worker), đảm bảo bạn đã SSH vào với quyền root hoặc sudo. Thực hiện lệnh cài đặt K3s phiên bản stable nhất.
Trên node Master (ví dụ IP: 192.168.1.10):
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.28.0+k3s1 sh -s - server --flannel-backend=wireguard-native --disable=traefik --disable=local-storage
Tại sao: Chúng ta cố định version 1.28 để đồng bộ với series, dùng wireguard-native cho networking (nhanh hơn flannel mặc định trong một số trường hợp), và tắt traefik/local-storage vì chúng ta sẽ tự cấu hình Calico và Storage riêng cho AI.
Kết quả mong đợi: K3s khởi động, token được in ra màn hình (bắt đầu bằng k3s://). Lưu token này, bạn sẽ cần nó cho các node worker. File config sẽ nằm ở /etc/rancher/k3s/config.yaml.
Trên các node Worker (ví dụ 192.168.1.11, 192.168.1.12):
curl -sfL https://get.k3s.io | K3S_URL=https://192.168.1.10:6443 K3S_TOKEN= sh -
Tại sao: Kết nối worker vào cluster master đã tạo sẵn, sử dụng token để xác thực an toàn.
Kết quả mong đợi: Worker join thành công, xuất hiện thông báo "K3s server is ready".
Verify kết quả: Trên node Master, chạy lệnh sau:
k3s kubectl get nodes
Bạn sẽ thấy 3 node với trạng thái READY. Nếu chưa READY, kiểm tra firewall (port 6443, 8472, 8473) trên Proxmox.
Cấu hình Networking CNI (Calico) cho cụm Kubernetes
Tắt Flannel và triển khai Calico
Mặc định K3s dùng Flannel, tuy nhiên Calico cung cấp tính năng NetworkPolicy mạnh mẽ hơn, rất cần thiết cho bảo mật và isolation trong phần 9 của series. Ngoài ra, Calico hỗ trợ tốt hơn cho các workload high-throughput.
Trước tiên, cần tắt Flannel bằng cách chỉnh sửa config file.
cat > /etc/rancher/k3s/config.yaml
Tại sao: Tắt Flannel để tránh xung đột IP và route khi cài Calico. Để disable-network-policy=false để Calico có thể quản lý policy.
Khởi động lại K3s service trên tất cả các node (Master và Worker) để áp dụng thay đổi.
systemctl restart k3s
Tại sao: Áp dụng config mới, Flannel sẽ không còn chạy.
Cài đặt Calico bằng manifest chính thức của K3s.
k3s kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
Tại sao: Triển khai Calico CNI. Version 3.26 tương thích tốt với K3s 1.28.
Kết quả mong đợi: Pod calico-kube-controllers và calico-node sẽ xuất hiện và chuyển sang trạng thái Running.
Verify kết quả: Chờ 2-3 phút cho Calico khởi động xong, sau đó chạy:
k3s kubectl get pods -n kube-system | grep calico
Tất cả pods Calico phải ở trạng thái Running. Kiểm tra IP của các node có được Calico phân bổ không bằng lệnh:
k3s kubectl get nodes -o wide
Trang cột EXTERNAL-IP sẽ hiển thị IP của node, và bạn có thể ping thử giữa các node bằng IP nội bộ Calico (thường là dải 10.42.x.x).
Tạo các node worker và cấu hình taint/toleration cho GPU nodes
Đánh dấu GPU Nodes và chuẩn bị Toleration
Trong cụm AI, không phải node nào cũng có GPU. Chúng ta cần đánh dấu các node có GPU để chỉ các Pod yêu cầu GPU mới được schedule vào đó. Điều này tránh việc Pod AI bị schedule vào node CPU-only và treo.
Giả sử node 192.168.1.11 và 192.168.1.12 có GPU NVIDIA, còn node 192.168.1.10 (Master) chỉ là CPU.
Áp dụng Taint (bám) cho các node có GPU để ngăn Pod thông thường chạy vào.
k3s kubectl taint nodes 192.168.1.11 nvidia.com/gpu=true:NoSchedule
k3s kubectl taint nodes 192.168.1.12 nvidia.com/gpu=true:NoSchedule
Tại sao: Taint "NoSchedule" với key "nvidia.com/gpu" sẽ buộc Kubernetes chỉ schedule Pod nào có Toleration tương ứng vào các node này.
Kết quả mong đợi: Các node GPU vẫn hiển thị READY nhưng bị đánh dấu có taint.
Verify kết quả: Kiểm tra taint trên node:
k3s kubectl describe node 192.168.1.11 | grep Taint
Bạn sẽ thấy dòng: Taints: nvidia.com/gpu=true:NoSchedule.
Bây giờ, khi tạo Pod cho AI inference (sẽ làm ở phần 3), chúng ta sẽ thêm Toleration vào spec của Pod để nó có thể chạy trên các node này. Cấu hình này là bước chuẩn bị bắt buộc.
Cài đặt NVIDIA Device Plugin để Kubernetes nhận diện GPU
Triển khai NVIDIA Container Toolkit và Device Plugin
Để Kubernetes nhận diện GPU, cần hai thành phần: Runtime (containerd) phải biết cách chạy container với driver GPU, và Device Plugin để báo cho Kubelet về tài nguyên GPU hiện có.
Trên các node có GPU (Worker 11 và 12), cài đặt NVIDIA Container Toolkit.
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit.gpg
curl -fsSL https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit.gpg] https://#g' > /etc/apt/sources.list.d/nvidia-container-toolkit.list
apt-get update
apt-get install -y nvidia-container-toolkit
Tại sao: Cài đặt driver runtime cần thiết để containerd có thể inject driver GPU vào container.
Cấu hình containerd để sử dụng nvidia-container-runtime.
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
Chỉnh sửa file /etc/containerd/config.toml, tìm phần [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] và thêm runtime "nvidia". Nội dung config hoàn chỉnh:
cat > /etc/containerd/config.toml
Tại sao: Khai báo runtime nvidia trong containerd để K3s (dùng containerd) có thể gọi driver này khi request GPU.
Khởi động lại containerd và k3s trên node GPU:
systemctl restart containerd
systemctl restart k3s
Cài đặt NVIDIA Device Plugin dưới dạng DaemonSet để chạy trên mọi node có GPU.
k3s kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.15.0/nvidia-device-plugin.yml
Tại sao: DaemonSet này sẽ tự động chạy trên các node có driver NVIDIA, báo cáo số lượng GPU cho Kubelet.
Kết quả mong đợi: Pod nvidia-device-plugin sẽ xuất hiện trên các node GPU và trạng thái Running.
Verify kết quả: Chạy lệnh để xem tài nguyên GPU được nhận diện:
k3s kubectl get pods -n kube-system | grep nvidia-device-plugin
Và kiểm tra xem node có resource "nvidia.com/gpu" không:
k3s kubectl describe node 192.168.1.11 | grep -A 5 "Allocated resources"
Hoặc đơn giản hơn, xem capacity của node:
k3s kubectl describe node 192.168.1.11 | grep nvidia.com/gpu
Bạn sẽ thấy dòng: nvidia.com/gpu: 1 (hoặc số lượng card GPU thực tế).
Kiểm tra trạng thái cluster và xác nhận khả năng nhận GPU của pod
Triển khai Pod thử nghiệm yêu cầu GPU
Bây giờ chúng ta sẽ tạo một Pod mẫu để kiểm tra toàn bộ quy trình: Networking, Taint/Toleration, và Device Plugin.
Tạo file YAML manifest cho pod thử nghiệm, bao gồm Toleration để vượt qua taint của node GPU và Request GPU.
cat > /tmp/gpu-test-pod.yaml
Tại sao: Toleration cho phép pod chạy trên node có taint, và resources limits yêu cầu 1 GPU. Nếu thiếu Toleration, pod sẽ Pending. Nếu thiếu resources, pod sẽ không nhận GPU.
Triển khai pod:
k3s kubectl apply -f /tmp/gpu-test-pod.yaml
Kết quả mong đợi: Pod sẽ được schedule vào node 192.168.1.11 hoặc 192.168.1.12.
Verify kết quả: Kiểm tra trạng thái pod:
k3s kubectl get pod gpu-test
Trạng thái phải là Completed (vì lệnh nvidia-smi chạy xong) hoặc Running (nếu bạn đổi command). Quan trọng nhất là kiểm tra node nó đang chạy:
k3s kubectl get pod gpu-test -o wide
Node NAME phải là IP của node GPU. Kiểm tra log để xem nvidia-smi có in ra thông tin card GPU không:
k3s kubectl logs gpu-test
Bạn sẽ thấy bảng thông tin GPU của NVIDIA (Driver Version, CUDA Version, Memory Usage). Nếu thấy bảng này, nghĩa là hạ tầng Kubernetes trên Proxmox đã sẵn sàng cho phần 3: Triển khai vLLM.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng AI inference hiệu năng cao với vLLM, TensorRT-LLM và Kubernetes trên Proxmox
« Phần 1: Chuẩn bị hạ tầng phần cứng và cài đặt Proxmox VE
Phần 3: Triển khai vLLM trên Kubernetes với cơ chế PagedAttention »