Cấu hình RBAC và Secret để bảo vệ truy cập Model và Database
Bước đầu tiên là thiết lập cơ chế xác thực và phân quyền (RBAC) cho các thành phần trong Kubernetes. Chúng ta sẽ tạo ServiceAccount riêng cho vLLM và VectorDB, đồng thời quản lý các thông tin nhạy cảm như API Key hoặc Token thông qua Kubernetes Secret.
Mục đích: Ngăn chặn truy cập trái phép vào các endpoint nội bộ và đảm bảo dữ liệu nhạy cảm không bị lưu dưới dạng plain text trong file YAML.
1. Tạo Kubernetes Secret cho vLLM và VectorDB
Tạo Secret chứa token truy cập hoặc thông tin xác thực cần thiết. Đây là cách an toàn để inject biến môi trường vào Pod.
kubectl create secret generic vllm-api-secret \
--from-literal=api-key="your-secure-api-key-here" \
--from-literal=model-path="/models/llama-3-8b" \
--namespace=llm-platform
Kết quả mong đợi: Kubernetes trả về thông báo "secret/vllm-api-secret created". Bạn có thể kiểm tra bằng lệnh kubectl get secret vllm-api-secret -n llm-platform.
kubectl create secret generic milvus-credential \
--from-literal=username="root" \
--from-literal=password="your-strong-password-here" \
--namespace=llm-platform
Kết quả mong đợi: Secret cho Milvus được tạo thành công.
2. Tạo Role và RoleBinding cho vLLM Server
Chúng ta cần cấp quyền cho ServiceAccount của vLLM để nó có thể đọc Secret đã tạo ở bước trên, nhưng không được phép ghi hoặc xóa.
cat
Kết quả mong đợi: Role và RoleBinding được tạo. Pod vLLM có thể mount Secret vào container khi khởi động.
3. Cập nhật Deployment vLLM để sử dụng Secret
Cập nhật file Deployment của vLLM (thường nằm ở `/opt/k8s/vllm-deployment.yaml`) để mount Secret vào container dưới dạng biến môi trường.
cat
Kết quả mong đợi: Khi áp dụng patch này, vLLM sẽ nhận biến môi trường VLLM_API_KEY từ Secret. Bạn có thể verify bằng cách exec vào pod và chạy echo $VLLM_API_KEY.
4. Verify bảo mật RBAC
Thử nghiệm truy cập trái phép bằng một ServiceAccount khác để đảm bảo quyền hạn đã được giới hạn đúng cách.
kubectl auth can-i get secrets vllm-api-secret \
--as=system:serviceaccount:default:default \
-n llm-platform
Kết quả mong đợi: Hệ thống trả về no, chứng tỏ ServiceAccount mặc định không có quyền truy cập vào Secret này.
Triển khai Prometheus và Grafana để giám sát Metrics
Hệ thống LLM cần giám sát chặt chẽ các chỉ số như GPU Utilization, VRAM Usage, Request Latency, và Throughput. Chúng ta sẽ triển khai Prometheus để thu thập metrics và Grafana để hiển thị dashboard.
Mục đích: Phát hiện sớm các điểm nghẽn (bottleneck) và cảnh báo khi tài nguyên GPU sắp cạn kiệt.
1. Triển khai Prometheus Operator (KubePrometheusStack)
Sử dụng Helm để cài đặt Prometheus Operator, bao gồm Prometheus, Alertmanager và Grafana.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set server.persistentVolume.enabled=true \
--set grafana.adminPassword="admin123"
Kết quả mong đợi: Các Pod của Prometheus và Grafana chuyển sang trạng thái Running.
2. Cấu hình ServiceMonitor cho vLLM
vLLM mặc định expose metrics tại endpoint /metrics. Chúng ta cần tạo ServiceMonitor để Prometheus tự động scrape endpoint này.
cat
Kết quả mong đợi: Prometheus bắt đầu thu thập dữ liệu từ vLLM. Bạn có thể kiểm tra trong tab "Targets" của Prometheus UI (thường chạy ở port 9090).
3. Cấu hình ServiceMonitor cho VectorDB (Milvus)
Tương tự, cấu hình giám sát cho VectorDB để theo dõi số lượng vector, latency truy vấn, và tình trạng disk.
cat
Kết quả mong đợi: Các metrics của Milvus xuất hiện trong Prometheus.
4. Tạo Dashboard Grafana cho Private LLM
Import một dashboard mẫu hoặc tạo dashboard tùy chỉnh để hiển thị các chỉ số quan trọng.
Tải file JSON dashboard (ví dụ: llm-dashboard.json) và upload lên Grafana.
cat
Kết quả mong đợi: Dashboard hiện ra trong Grafana với các biểu đồ realtime về GPU, Latency và Vector Count.
5. Verify Giám sát
Tạo một workload giả để kiểm tra hệ thống giám sát có phản hồi đúng không.
curl -X POST http://vllm-service:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{"model": "llama-3", "prompt": "Hello world", "max_tokens": 5}'
Kết quả mong đợi: Ngay sau khi request được gửi, bạn thấy các metrics như vllm:num_requests_running tăng lên và latency được ghi nhận trên dashboard Grafana.
Xử lý sự cố (Troubleshooting) các lỗi phổ biến
Khi vận hành hệ thống LLM, các lỗi về tài nguyên (OOM), thời gian chờ GPU (Timeout) và kết nối mạng là phổ biến nhất. Dưới đây là quy trình xử lý cụ thể cho từng trường hợp.
Mục đích: Giảm thời gian downtime và nhanh chóng khôi phục dịch vụ khi sự cố xảy ra.
1. Xử lý lỗi OOM (Out of Memory)
Lỗi này xảy ra khi GPU hoặc RAM bị đầy, thường do batch size quá lớn hoặc model quá nặng so với tài nguyên cấp phép.
Triệu chứng: Pod bị restart liên tục với trạng thái OOMKilled.
kubectl get pods -n llm-platform
kubectl describe pod -n llm-platform | grep -A 5 "Last State"
Kết quả mong đợi: Bạn thấy thông báo Reason: OOMKilled trong phần Last State.
Cách khắc phục: Giảm max_num_batched_tokens hoặc tăng resource limit.
kubectl set resources deployment vllm-server -n llm-platform \
--limits=gpu=nvidia.com/gpu=2 \
--limits=memory=32Gi
Hoặc cập nhật args trong deployment để giảm batch size:
kubectl set env deployment/vllm-server -n llm-platform \
VLLM_MAX_NUM_BATCHED_TOKENS=1024
Kết quả mong đợi: Pod khởi động lại và chạy ổn định mà không bị OOMKilled. Kiểm tra lại logs để đảm bảo không còn lỗi.
2. Xử lý lỗi GPU Timeout
Lỗi này xảy ra khi quá trình inference hoặc training mất quá nhiều thời gian, vượt quá ngưỡng timeout của Kubernetes hoặc ứng dụng.
Triệu chứng: Request bị drop với lỗi 504 Gateway Timeout hoặc Context Deadline Exceeded.
kubectl logs -f -n llm-platform | grep -i "timeout"
Kết quả mong đợi: Logs hiển thị thông báo về việc quá trình bị kill do vượt quá thời gian chờ.
Cách khắc phục: Tăng thời gian chờ (timeout) của liveness probe và readiness probe.
kubectl patch deployment vllm-server -n llm-platform \
-p '{"spec":{"template":{"spec":{"containers":[{"name":"vllm","livenessProbe":{"initialDelaySeconds":300,"timeoutSeconds":60,"periodSeconds":10}}]}}}}'
Kết quả mong đợi: Pod không bị restart khi inference lâu. Các request dài sẽ được xử lý hoàn tất.
3. Xử lý lỗi kết nối mạng (Network Connectivity)
Lỗi xảy ra khi Backend không thể liên lạc với VectorDB hoặc vLLM do DNS, NetworkPolicy hoặc Service bị lỗi.
Triệu chứng: Lỗi Connection refused, Connection timed out trong logs.
kubectl exec -it -n llm-platform -- nslookup milvus-service
Kết quả mong đợi: Nếu DNS không giải quyết được, bạn sẽ thấy lỗi "server can't find milvus-service".
Cách khắc phục: Kiểm tra NetworkPolicy và đảm bảo Service có selector đúng.
kubectl get svc milvus-service -n llm-platform -o yaml
kubectl describe svc milvus-service -n llm-platform
Trường hợp cần mở firewall nội bộ, tạo NetworkPolicy cho phép traffic giữa namespace:
cat
Kết quả mong đợi: Backend có thể ping hoặc connect thành công đến vLLM và Milvus. Lỗi kết nối trong logs biến mất.
4. Quy trình Debug tổng quát
Khi gặp sự cố không rõ nguyên nhân, hãy thực hiện theo quy trình sau:
- Kiểm tra trạng thái Pod:
kubectl get pods -n llm-platform.
- Xem logs chi tiết:
kubectl logs -n llm-platform --tail=100.
- Kiểm tra events của cluster:
kubectl get events -n llm-platform --sort-by='.lastTimestamp'.
- Debug trực tiếp trong container:
kubectl exec -it -n llm-platform -- /bin/bash.
Kết quả mong đợi: Xác định được nguyên nhân gốc rễ (root cause) từ logs hoặc events và áp dụng giải pháp tương ứng.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Private LLM với vLLM, RAG và VectorDB trên hạ tầng Kubernetes
« Phần 8: Tối ưu hóa hiệu năng và scaling tự động cho Private LLM