1. Xử lý lỗi OOMKilled và tối ưu bộ nhớ cho mô hình lớn
Khi triển khai các mô hình ngôn ngữ lớn (LLM) trên Kubernetes, lỗi OOMKilled thường xảy ra khi container vượt quá giới hạn bộ nhớ (Memory Limit) đã đặt. Hệ thống Kubernetes sẽ giết (kill) container đó để bảo vệ node. Giải pháp không chỉ là tăng RAM, mà cần tối ưu cấu hình requests và limits cùng cơ chế memoryFraction hoặc sử dụng memory-management trong code.
1.1. Chẩn đoán nguyên nhân OOMKilled
Trước khi sửa lỗi, cần xác định xem pod bị kill do dùng hết RAM thực tế hay do Kubernetes giới hạn. Sử dụng lệnh kubectl describe pod để xem trạng thái Last State.
Thực thi lệnh sau để kiểm tra trạng thái pod bị lỗi:
kubectl describe pod ai-agent-prod -n production | grep -A 5 "Last State"
Kết quả mong đợi: Bạn sẽ thấy dòng Reason: OOMKilled và Exit Code: 137. Điều này xác nhận container đã bị giết vì hết bộ nhớ.
1.2. Điều chỉnh Resource Limits và Requests
Sửa file ai-agent-deployment.yaml để tăng limits.memory và cân đối requests.memory. Quan trọng nhất là thiết lập requests thấp hơn limits một chút để Kubernetes có thể schedulling nhưng vẫn cho phép peak memory cao hơn. Đối với mô hình lớn, cần tính toán RAM cho model weights + context window + runtime overhead.
Đường dẫn file: /k8s/manifests/ai-agent-deployment.yaml. Nội dung hoàn chỉnh:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-agent-prod
namespace: production
labels:
app: ai-agent
version: v2.0
spec:
replicas: 3
selector:
matchLabels:
app: ai-agent
template:
metadata:
labels:
app: ai-agent
version: v2.0
spec:
containers:
- name: ai-agent
image: registry.internal/ai-agent:v2.0
ports:
- containerPort: 8000
resources:
requests:
memory: "4Gi"
cpu: "500m"
limits:
memory: "12Gi"
cpu: "2000m"
env:
- name: MODEL_MEMORY_FRACTION
value: "0.7"
- name: MAX_CONTEXT_LENGTH
value: "8192"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 30
periodSeconds: 5
Kết quả mong đợi: Pod sẽ khởi động thành công, không bị OOMKilled ngay lập tức. Kubernetes sẽ phân bổ 4Gi RAM đảm bảo (requests) nhưng cho phép pod dùng tới 12Gi khi cần thiết (limits).
1.3. Cấu hình Memory Management trong ứng dụng
Với các mô hình sử dụng thư viện như llama-cpp-python hoặc vllm, cần truyền biến môi trường để giới hạn bộ nhớ sử dụng bởi thư viện, tránh để thư viện chiếm toàn bộ RAM của container. Điều này giúp ngăn chặn tình trạng OOM ngay cả khi limits được đặt cao.
Thêm biến môi trường MODEL_MEMORY_FRACTION vào file config của ứng dụng hoặc biến môi trường trong deployment (như đã làm ở trên). Nếu dùng vllm, cần thêm --gpu-memory-utilization (nếu có GPU) hoặc --cpu-memory-utilization.
Kiểm tra lại hành vi của ứng dụng sau khi deploy:
kubectl exec -it ai-agent-prod- -n production -- cat /proc/meminfo | grep MemAvailable
Kết quả mong đợi: Lượng RAM available không về 0 ngay khi chạy tác vụ nặng, chứng tỏ ứng dụng đang tự giới hạn bộ nhớ sử dụng theo cấu hình.
2. Chiến lược cân bằng tải cho các loại Agent khác nhau
Không phải tất cả Agent đều xử lý yêu cầu với tốc độ và độ phức tạp như nhau. Một Agent "Researcher" có thể cần 10 giây để tìm kiếm, trong khi Agent "Summarizer" chỉ mất 2 giây. Load Balancing mặc định của Kubernetes (Round Robin) có thể gây quá tải cho các pod xử lý chậm. Cần áp dụng chiến lược Weighted Load Balancing hoặc Topology-Aware Routing.
2.1. Cấu hình Service với Weighted Routing (Traffic Splitting)
Sử dụng Service kết hợp với Label Selector để phân tách traffic. Tuy nhiên, để cân bằng tải chính xác hơn dựa trên độ phức tạp, chúng ta sẽ sử dụng istio hoặc nginx-ingress với virtualService (giả định môi trường có Service Mesh hoặc Ingress Controller hỗ trợ). Nếu dùng Kubernetes thuần, ta dùng weight trong Ingress.
Tạo file ai-agent-ingress.yaml để phân luồng traffic. Giả sử 70% traffic đi về nhóm Agent "Fast" và 30% về nhóm Agent "Heavy".
Đường dẫn file: /k8s/manifests/ai-agent-ingress.yaml. Nội dung hoàn chỉnh:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ai-agent-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/weight: "100"
nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"
spec:
rules:
- host: ai-agent.company.com
http:
paths:
- path: /api/agent/fast
pathType: Prefix
backend:
service:
name: ai-agent-fast-service
port:
number: 80
- path: /api/agent/heavy
pathType: Prefix
backend:
service:
name: ai-agent-heavy-service
port:
number: 80
Kết quả mong đợi: Traffic đến endpoint /api/agent/fast sẽ chỉ được phân phối cho các pod có label type=fast, tránh việc request nhẹ bị kẹt bởi request nặng đang chạy.
2.2. Sử dụng Priority Class cho Agent quan trọng
Trong môi trường đa Agent, cần ưu tiên các Agent xử lý nghiệp vụ quan trọng (Critical) so với Agent chạy các tác vụ phụ trợ (Batch). Sử dụng PriorityClass để Kubernetes ưu tiên scheduling và preemption (bóc pod ít quan trọng) khi tài nguyên khan hiếm.
Tạo file priority-class.yaml:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: ai-critical-priority
annotations:
description: "Highest priority for critical AI Agents"
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
Sau đó, cập nhật Deployment của Agent quan trọng để trỏ vào PriorityClass này:
kubectl patch deployment ai-agent-prod -n production -p '{"spec": {"template": {"spec": {"priorityClassName": "ai-critical-priority"}}}}'
Kết quả mong đợi: Khi node thiếu tài nguyên, Kubernetes sẽ giết các pod có priority thấp hơn để nhường chỗ cho pod Agent quan trọng, đảm bảo tính sẵn sàng cho dịch vụ chính.
2.3. Verify cân bằng tải
Sử dụng curl để tạo hàng loạt request và kiểm tra Access Log hoặc Metrics trên Ingress Controller để đảm bảo traffic được phân phối đúng tỷ lệ.
for i in {1..100}; do curl -s http://ai-agent.company.com/api/agent/fast | grep "pod-name"; done | sort | uniq -c
Kết quả mong đợi: Số lần request của các pod trong service ai-agent-fast-service phải tương đối đều nhau (hoặc theo tỷ lệ weight đã cấu hình), không có pod nào quá tải.
3. Thực hiện Blue-Green Deployment để cập nhật phiên bản Agent không gián đoạn
Blue-Green Deployment là chiến lược triển khai hai môi trường song song (Blue: phiên bản cũ đang chạy, Green: phiên bản mới). Khi Green ổn định, chuyển toàn bộ traffic sang Green, sau đó hạ Blue. Cách này giúp rollback gần như tức thời nếu có lỗi.
3.1. Chuẩn bị hai ReplicaSet (Blue và Green)
Tách biệt Deployment thành hai Deployment riêng biệt với cùng một Service nhưng sử dụng Label khác nhau để phân biệt phiên bản. Service sẽ trỏ vào label phiên bản hiện tại.
Tạo file blue-green-deployment.yaml chứa cả hai phiên bản (v2.0 là Blue, v2.1 là Green).
Đường dẫn file: /k8s/manifests/blue-green-deployment.yaml. Nội dung hoàn chỉnh:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-agent-blue
namespace: production
labels:
app: ai-agent
version: v2.0
spec:
replicas: 3
selector:
matchLabels:
app: ai-agent
version: v2.0
template:
metadata:
labels:
app: ai-agent
version: v2.0
spec:
containers:
- name: ai-agent
image: registry.internal/ai-agent:v2.0
ports:
- containerPort: 8000
resources:
limits:
memory: "12Gi"
requests:
memory: "4Gi"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-agent-green
namespace: production
labels:
app: ai-agent
version: v2.1
spec:
replicas: 3
selector:
matchLabels:
app: ai-agent
version: v2.1
template:
metadata:
labels:
app: ai-agent
version: v2.1
spec:
containers:
- name: ai-agent
image: registry.internal/ai-agent:v2.1
ports:
- containerPort: 8000
resources:
limits:
memory: "12Gi"
requests:
memory: "4Gi"
---
apiVersion: v1
kind: Service
metadata:
name: ai-agent-service
namespace: production
spec:
selector:
app: ai-agent
version: v2.0
ports:
- port: 80
targetPort: 8000
type: ClusterIP
Kết quả mong đợi: Cả hai Deployment đều được tạo. Service hiện tại chỉ trỏ đến v2.0 (Blue). Traffic vẫn đi về phiên bản cũ.
3.2. Thực hiện chuyển đổi Traffic (Cutover)
Để chuyển sang phiên bản mới (Green), chỉ cần cập nhật selector trong Service để trỏ vào version: v2.1. Không cần restart pod hay downtime.
Thực thi lệnh patch để đổi label selector của Service:
kubectl patch service ai-agent-service -n production -p '{"spec": {"selector": {"app": "ai-agent", "version": "v2.1"}}}'
Kết quả mong đợi: Tất cả traffic từ client ngay lập tức chuyển sang các pod chạy v2.1. Các pod v2.0 vẫn chạy nhưng không nhận request mới.
3.3. Quy trình Rollback nhanh
Nếu phát hiện lỗi ở v2.1, chỉ cần revert lại selector của Service về v2.0. Đây là lợi thế lớn nhất của Blue-Green.
kubectl patch service ai-agent-service -n production -p '{"spec": {"selector": {"app": "ai-agent", "version": "v2.0"}}}'
Kiểm tra xem traffic đã quay về Blue chưa:
kubectl get pods -n production -l app=ai-agent,version=v2.1 --no-headers | wc -l
Kết quả mong đợi: Sau khi rollback, các pod v2.1 không nhận thêm traffic. Có thể giữ lại v2.1 trong vài giờ để debug trước khi xóa.
4. Tổng kết bài học và Checklist bảo mật cuối cùng
Trước khi đưa hệ thống AI Agent vào vận hành chính thức (Production), cần rà soát lại toàn bộ kiến trúc từ góc độ bảo mật và độ tin cậy. Các bài học từ quá trình xử lý OOM và cân bằng tải cần được đúc kết thành quy chuẩn.
4.1. Checklist bảo mật AI Agent
Thực hiện kiểm tra từng mục sau trên môi trường Production:
- Secret Management: Đảm bảo không có API Key, Token được hardcode trong Docker Image hoặc ConfigMap. Phải sử dụng
Kubernetes Secrets hoặc HashiCorp Vault (đường dẫn /var/run/secrets/kubernetes.io).
- Network Policies: Cấu hình
NetworkPolicy để chỉ cho phép traffic từ Gateway API vào Agent, và chỉ cho phép Agent gọi ra các dịch vụ nội bộ (Database, Vector DB, External LLM API) cần thiết.
- Pod Security Standards: Cấu hình
PodSecurityContext để chạy pod với quyền runAsNonRoot: true và readOnlyRootFilesystem: true.
- LLM Prompt Injection: Đảm bảo code Agent có cơ chế lọc input (sanitization) trước khi gửi đến LLM để ngăn chặn tấn công Prompt Injection.
- Rate Limiting: Tích hợp
RateLimit ở Gateway (Ingress) để chống DDoS hoặc lạm dụng tài nguyên LLM.
4.2. Config NetworkPolicy mẫu
Tạo file network-policy.yaml để cô lập môi trường Agent.
Đường dẫn file: /k8s/manifests/network-policy.yaml. Nội dung hoàn chỉnh:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ai-agent-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: ai-agent
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: gateway
- podSelector:
matchLabels:
app: api-gateway
ports:
- protocol: TCP
port: 8000
egress:
- to:
- namespaceSelector:
matchLabels:
name: production
- podSelector:
matchLabels:
app: vector-db
ports:
- protocol: TCP
port: 6379
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- protocol: TCP
port: 443
Kết quả mong đợi: Agent chỉ nhận được request từ Gateway API và chỉ được phép kết nối ra ngoài qua port 443 (cho API LLM) hoặc vào Vector DB nội bộ. Các kết nối trái phép bị chặn.
4.3. Verify bảo mật và hiệu năng cuối cùng
Thực hiện test tấn công cơ bản và kiểm tra giới hạn tài nguyên.
kubectl run stress-test --image=busybox --restart=Never -n production -- /bin/sh -c "while true; do curl -s http://ai-agent-service:80/health; done"
Sau đó kiểm tra xem NetworkPolicy có chặn traffic từ pod stress-test không (nó không nằm trong whitelist của Ingress).
kubectl logs stress-test -n production
Kết quả mong đợi: Connection timeout hoặc refused, chứng tỏ NetworkPolicy đang hoạt động. Sau đó xóa pod stress-test.
kubectl delete pod stress-test -n production
Hệ thống đã sẵn sàng cho sản xuất với cơ chế tự phục hồi (OOM handling), cân bằng tải thông minh, khả năng cập nhật không gián đoạn (Blue-Green) và lớp bảo mật chặt chẽ.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng AI Agent tự động hóa với LangGraph, CrewAI và Kubernetes
« Phần 10: Troubleshooting nâng cao và chiến lược sản xuất