So sánh cơ chế sandboxing giữa gVisor và Kata Containers
Trong kiến trúc Secure AI Sandbox, chúng ta cần hiểu rõ sự khác biệt về mức độ cách ly để chọn đúng runtime cho từng loại workload AI.
Kata Containers sử dụng một máy ảo (VM) nhẹ dựa trên QEMU cho mỗi container, cung cấp sự cách ly ở mức kernel (kernel isolation). Ngược lại, gVisor thực hiện sandboxing ở mức user-space thông qua một kernel giả lập (user-space kernel) gọi là Go runtime, chạy trên kernel host.
Đối với các thư viện AI không tin cậy (untrusted AI libraries) như các gói Python tùy chỉnh tải từ nguồn ngoài, gVisor là lựa chọn tối ưu hơn vì nó giảm thiểu chi phí khởi tạo (startup latency) và tiêu thụ tài nguyên RAM so với VM, trong khi vẫn ngăn chặn các cuộc tấn công exploit vào kernel host.
Tuy nhiên, gVisor có giới hạn về hiệu năng I/O và GPU so với Kata Containers, do đó chúng ta chỉ sử dụng gVisor cho các workload xử lý logic AI thuần túy, không yêu cầu truy cập trực tiếp vào phần cứng GPU tốc độ cao.
Cấu hình runtime gVisor (runsc) trên Kubernetes
Để Kubernetes có thể sử dụng gVisor, chúng ta cần cài đặt runtime gVisor (runsc) trên node và đăng ký nó với Container Runtime Interface (CRI) thông qua containerd.
Bước đầu tiên là cài đặt các gói cần thiết cho gVisor trên node Linux (giả sử Ubuntu 22.04 hoặc Debian 11).
sudo apt update && sudo apt install -y gvisor-runsc
Command này sẽ tải và cài đặt binary `runsc` vào thư mục `/usr/bin/`.
Sau khi cài đặt, chúng ta cần cấu hình containerd để nhận diện và sử dụng runtime gVisor. Containerd cần một profile runtime riêng biệt.
Tạo file cấu hình runtime gVisor tại đường dẫn `/etc/containerd/config.toml`. Lưu ý: Nếu file đã tồn tại, hãy thêm phần cấu hình runtime mới vào cuối file.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.gvisor]
runtime_type = "io.containerd.runsc.v1"
pod_annotations = ["io.containerd.grpc.v1.cri"]
Đoạn cấu hình này định nghĩa một runtime mới có tên là `gvisor` sử dụng binary `runsc`. Tham số `pod_annotations` giúp gVisor nhận diện pod để thiết lập network namespace chính xác.
Tiếp theo, khởi động lại dịch vụ containerd để áp dụng cấu hình mới.
sudo systemctl restart containerd
Kết quả mong đợi: Dịch vụ containerd khởi động lại thành công mà không báo lỗi về cấu hình runtime.
Để xác minh runtime đã được đăng ký, chạy lệnh kiểm tra các runtime hiện có trong containerd.
containerd --namespace=k8s.io runtime list
Output phải hiển thị dòng `io.containerd.runsc.v1` hoặc tên runtime `gvisor` tùy thuộc vào phiên bản containerd.
Triển khai container AI sử dụng gVisor
Bây giờ chúng ta sẽ tạo một Pod Kubernetes sử dụng runtime gVisor để chạy một thư viện AI không tin cậy. Chúng ta sẽ sử dụng một hình ảnh Docker đơn giản chứa Python và một script giả lập thư viện AI.
Tạo file manifest YAML cho Pod với tên `ai-untrusted-pod.yaml`.
apiVersion: v1
kind: Pod
metadata:
name: ai-untrusted-pod
labels:
app: ai-sandbox
spec:
runtimeClassName: gvisor
containers:
- name: ai-worker
image: python:3.9-slim
command: ["python", "-c", "import os; print('Running in gVisor:', os.popen('cat /proc/version').read())"]
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
Trọng tâm ở đây là trường `runtimeClassName: gvisor`, chỉ định Kubernetes sử dụng runtime gVisor đã cấu hình ở phần trước. Pod này sẽ chạy một container Python đơn giản để in thông tin kernel.
Triển khai Pod vào cluster Kubernetes.
kubectl apply -f ai-untrusted-pod.yaml
Kết quả mong đợi: Kubernetes chấp nhận và tạo Pod. Trạng thái ban đầu sẽ là `ContainerCreating` khi node tải hình ảnh và khởi tạo runtime gVisor.
Chờ Pod chuyển sang trạng thái `Running` hoặc `Completed` (do script chỉ chạy 1 lệnh rồi dừng).
kubectl wait --for=condition=ready pod/ai-untrusted-pod --timeout=120s
Để xác minh Pod đang chạy trên gVisor, chúng ta sẽ kiểm tra logs và xem thông tin kernel bên trong container.
kubectl logs ai-untrusted-pod
Kết quả mong đợi: Output phải hiển thị thông báo `Running in gVisor: Linux version ... gvisor`. Dòng này chứng tỏ container đang chạy trên kernel giả lập của gVisor chứ không phải kernel host.
Kiểm tra tính cách ly mạng và bảo mật
Để đảm bảo tính cách ly, chúng ta cần kiểm tra xem container gVisor có thể truy cập vào mạng nội bộ của host hay không, hoặc có thể đọc các file nhạy cảm của host.
Triển khai lại Pod với một lệnh kiểm tra khả năng truy cập mạng và filesystem.
apiVersion: v1
kind: Pod
metadata:
name: ai-network-test
spec:
runtimeClassName: gvisor
containers:
- name: test-container
image: alpine:3.18
command: ["sh", "-c", "ping -c 3 169.254.169.254 && ls /etc/kubernetes"]
securityContext:
allowPrivilegeEscalation: false
Lệnh này cố gắng ping địa chỉ metadata của cloud provider (thường bị chặn trong sandbox) và liệt kê thư mục nhạy cảm `/etc/kubernetes` của host.
kubectl apply -f ai-network-test.yaml && kubectl logs ai-network-test
Kết quả mong đợi:
- Command `ping` sẽ timeout hoặc bị chặn (connection refused/timed out), chứng tỏ gVisor đã cô lập mạng.
- Command `ls /etc/kubernetes` sẽ báo lỗi `Permission denied` hoặc `No such file or directory`, chứng tỏ container không thể truy cập filesystem của host.
Thêm vào đó, kiểm tra xem container có thể thực thi các hệ thống gọi (syscall) bị cấm hay không.
kubectl exec ai-network-test -- cat /proc/self/status | grep Seccomp
Kết quả mong đợi: Giá trị `Seccomp` phải là `2` (Strict), chứng tỏ gVisor đang áp dụng chính sách seccomp nghiêm ngặt để ngăn chặn các syscall không an toàn.
So sánh với Pod chạy trên runtime mặc định (dockerd/containerd) bằng cách tạo một Pod tương tự nhưng không có `runtimeClassName` và thực hiện cùng lệnh `ls /etc/kubernetes`.
kubectl run test-host --image=alpine:3.18 --command -- ls /etc/kubernetes
Kết quả mong đợi: Pod chạy trên runtime mặc định (nếu không có NetworkPolicy chặn) thường có thể đọc được thư mục này nếu nó được mount vào, trong khi Pod gVisor hoàn toàn bị chặn. Điều này khẳng định cơ chế sandboxing của gVisor hiệu quả hơn cho các workload không tin cậy.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Secure AI Sandbox với Kata Containers, gVisor và Policy Engine
« Phần 2: Triển khai Kata Containers cho workload AI yêu cầu bảo mật cao
Phần 4: Xây dựng Policy Engine với OPA và Kubernetes Gatekeeper »