Trong Kubernetes, taints và tolerations là các cơ chế cho phép bạn kiểm soát vị trí các pod được lên lịch trong cụm. Chúng cung cấp khả năng kiểm soát chi tiết việc đặt pod lên các node, đảm bảo rằng các pod chạy trên những node phù hợp dựa trên các yêu cầu cụ thể như năng lực phần cứng, độ ưu tiên của workload hoặc lịch bảo trì. Hướng dẫn này sẽ giải thích taints và tolerations là gì, cách chúng hoạt động, và cách sử dụng hiệu quả thông qua các ví dụ thực tế.
Yêu cầu trước khi bắt đầu
- Hiểu biết cơ bản về các khái niệm trong Kubernetes (pod, node, lên lịch).
- Một cụm Kubernetes (ví dụ: Minikube, Kind, hoặc cụm cloud như GKE, EKS, AKS).
kubectl
đã được cài đặt và cấu hình để tương tác với cụm.
Taints và Tolerations là gì?
Taints
Taint là một thuộc tính được áp dụng cho node để ngăn không cho các pod được lên lịch lên node đó, trừ khi pod đó chấp nhận (tolerate) taint. Taints rất hữu ích khi:
- Dành riêng các node cho workload cụ thể
- Đánh dấu node với phần cứng đặc biệt
- Ngăn pod chạy trên node trong quá trình bảo trì
Một taint bao gồm:
- Key: Định danh duy nhất (ví dụ: dedicated)
- Value: Giá trị đi kèm với key (ví dụ: gpu)
- Effect: Hành vi lên lịch (ví dụ: NoSchedule, PreferNoSchedule, hoặc NoExecute)
Tolerations
Toleration là một thuộc tính được áp dụng cho pod, cho phép nó được lên lịch trên node có taint tương ứng. Toleration khớp với taint dựa trên key, value và effect – từ đó vô hiệu hóa sự giới hạn của taint.
Cách chúng hoạt động cùng nhau
- Mặc định, một node có taint sẽ từ chối pod nếu pod đó không có toleration tương ứng.
- Toleration không ép buộc pod chạy trên node đó, nó chỉ cho phép. Các yếu tố khác như affinity, tài nguyên, độ ưu tiên vẫn được xét đến.
- Taints/tolerations bổ sung cho node affinity: affinity hút pod đến node, còn taint đẩy pod đi.
Các loại Effect trong Taints
- NoSchedule: Pod không có toleration sẽ không được lên lịch trên node. Pod đã chạy không bị ảnh hưởng.
- PreferNoSchedule: Tránh lên lịch pod không có toleration, nhưng không cưỡng chế hoàn toàn.
- NoExecute: Pod không có toleration sẽ bị đẩy ra (evict) ngay lập tức và các pod mới không thể được lên lịch.
Tại sao nên sử dụng Taints và Tolerations?
- Dành riêng node cho workload cụ thể (ví dụ: ML, database)
- Sử dụng phần cứng đặc biệt (GPU, RAM cao)
- Quản lý bảo trì node
- Cách ly workload quan trọng khỏi workload thông thường
Thiết lập Taints và Tolerations
Bước 1: Thêm Taint vào Node
kubectl taint nodes <node-name> key=value:effect
Ví dụ: Chặn các pod không phù hợp chạy trên node1
:
kubectl taint nodes node1 dedicated=gpu:NoSchedule
Kiểm tra taint:
kubectl describe node node1
Tìm dòng:
Taints: dedicated=gpu:NoSchedule
Bước 2: Thêm Toleration vào Pod
File YAML mẫu gpu-pod.yaml
:
apiVersion: v1
kind: Pod
metadata: name: gpu-pod
spec: containers: - name: nginx image: nginx tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule"
Áp dụng pod:
kubectl apply -f gpu-pod.yaml
Bước 3: Kiểm tra Pod được lên lịch
kubectl get pods -o wide
Nếu không có toleration, pod sẽ ở trạng thái Pending.
Bước 4: Xoá Taint
kubectl taint nodes node1 dedicated=gpu:NoSchedule-
Kiểm tra lại:
kubectl describe node node1
Sử dụng nâng cao
Tolerate mọi giá trị của key
tolerations:
- key: "dedicated" operator: "Exists" effect: "NoSchedule"
Chấp nhận mọi giá trị của key dedicated
.
Toleration Seconds (cho NoExecute
)
tolerations:
- key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300
Pod sẽ chờ 300 giây trước khi bị đẩy khỏi node.
Kết hợp với Node Affinity
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/gpu operator: In values: - "true" tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule"
Toleration mặc định
Kubernetes tự động thêm các toleration mặc định cho các taint sau:
node.kubernetes.io/not-ready:NoExecute
node.kubernetes.io/unreachable:NoExecute
Thời gian chờ mặc định là 300 giây.
Ví dụ thực tế: Dành riêng Node cho GPU
Bối cảnh: Cụm có 3 node, node1 có GPU. Chỉ pod nặng về GPU mới được lên lịch lên node1.
Các bước:
1. Taint node1:
kubectl taint nodes node1 dedicated=gpu:NoSchedule
2. Gán nhãn node1:
kubectl label nodes node1 node-role.kubernetes.io/gpu=true
3. Tạo pod dùng GPU:
apiVersion: v1 kind: Pod metadata: name: gpu-workload spec: containers: - name: ml-container image: tensorflow/tensorflow:latest-gpu affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-role.kubernetes.io/gpu operator: In values: - "true" tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule"
Áp dụng:
kubectl apply -f gpu-workload.yaml
4. Tạo pod thường (không dùng GPU):
apiVersion: v1 kind: Pod metadata: name: regular-pod spec: containers: - name: nginx image: nginx
Áp dụng và kiểm tra:
kubectl apply -f regular-pod.yaml kubectl get pods -o wide
regular-pod
sẽ ở trạng thái Pending hoặc được lên lịch lên node khác.
Sự cố thường gặp
- Pod kẹt ở Pending: Kiểm tra nếu pod thiếu toleration.
- Bị đẩy bất ngờ: Kiểm tra taint NoExecute và toleration.
- Taint không hoạt động: Xác minh lại cú pháp và tên node.
Best practice
- Dùng key/value rõ ràng (
dedicated=database
thay vìkey1=value1
) - Kết hợp với node affinity để kiểm soát chi tiết
- Theo dõi taint trong cụm bằng:
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
- Ghi chú tài liệu sử dụng taint để nhóm dễ hiểu
Kết luận
Taints và tolerations là công cụ mạnh mẽ để quản lý nơi các pod được chạy trong Kubernetes. Bằng cách gắn taint vào node và thêm toleration vào pod, bạn có thể thực thi các chính sách lên lịch tối ưu, cách ly workload và xử lý các yêu cầu đặc biệt như node có GPU hoặc bảo trì. Hãy thử áp dụng các ví dụ trong hướng dẫn này trên cụm của bạn để có kinh nghiệm thực tế.
Cảm ơn các bạn đã theo dõi!