Scheduling trên Kubernetes (phần 3)

1295
24-11-2023
Scheduling trên Kubernetes (phần 3)

Mở đầu

Pod Topology Spread Constraints là tính năng của Kubernetes cho phép bạn kiểm soát cách các pod được nhân rộng trên toàn cụm giữa các failure-domains như regions, zones, nodes và các topology domains khác do người dùng định nghĩa. Điều này có thể giúp bạn đạt được độ sẵn sàng cao (high availability) và sử dụng tài nguyên hiệu quả. Tính năng này giúp tăng độ tin cậy của hệ thống Kubernetes của bạn và đảm bảo rằng các pod được triển khai đều đặn trên các node và các failure domain khác nhau.

Để sử dụng tính năng này, bạn cần định nghĩa các topology domains và các label tương ứng với chúng trong file Pod Topology Spread Constraints. Sau đó, bạn có thể áp dụng các ràng buộc này cho các pod thông qua cấu hình của K8s. Bằng cách sử dụng Pod Topology Spread Constraints, bạn có thể tăng độ tin cậy của hệ thống Kubernetes của mình và đảm bảo rằng các pod được triển khai đều đặn trên các node và các failure domain khác nhau.

Ngoài ra, tính năng Pod Topology Spread Constraints còn cung cấp cho bạn một số lợi ích khác như:

  • Tối ưu hóa việc sử dụng tài nguyên: Bằng cách phân bố các pod đều đặn trên các node, bạn có thể tối ưu hóa việc sử dụng tài nguyên của hệ thống Kubernetes của mình.  
  • Tăng độ tin cậy của hệ thống: Bằng cách phân bố các pod đều đặn trên các node và các failure domain khác nhau, bạn có thể tăng độ tin cậy của hệ thống Kubernetes của mình. 
  •  Dễ dàng quản lý hệ thống: Với Pod Topology Spread Constraints, bạn có thể dễ dàng quản lý hệ thống Kubernetes của mình một cách hiệu quả hơn.

Vì vậy, nếu bạn đang sử dụng Kubernetes để triển khai các ứng dụng phân tán, hãy sử dụng tính năng Pod Topology Spread Constraints để tăng độ tin cậy và hiệu quả của hệ thống của bạn.

Ý tưởng

Ví dụ, nếu có một cluster nhiều nodes chạy trên các trung tâm dữ liệu khác nhau:

Giả sử có 3 nodes chạy 5 pod mỗi node. Các nodes có đủ khả năng để chạy gần như tất cả các Pods; tuy nhiên, client tương tác với workload có thể bị phân chia thành 3 trung tâm dữ liệu hoặc vùng khác nhau. Trong trường hợp này, bạn không cần phải lo lắng về lỗi một node, nhưng sẽ có độ trễ cao và phải trả chi phí mạng liên quan đến việc gửi lưu lượng mạng giữa các vùng khác nhau. Bạn quyết định rằng trong điều kiện hoạt động bình thường, bạn muốn có một số lượng bản sao tương tự được lên lịch vào từng trung tâm dữ liệu và bạn muốn nhóm tự phục hồi trong trường hợp có sự cố.

Ràng buộc phân tán Topology của Pod (PTSC) cung cấp cho bạn một cách để thiết lập điều đó.

Scheduling trên Kubernetes (phần 3) - Ảnh 1.

Bạn có thể tạo một hoặc nhiều topologySpreadConstraints với các trường sau đây:

  • maxSkew: đây là mức độ cho phép các pod được phân phối không đồng đều nhau. Nó mô tả sự khác biệt tối đa giữa số lượng pod khớp nhau giữa hai miền topology của một loại topology nhất định. Giá trị của nó phải lớn hơn 0. 
  • topologyKey: đây là phần "key" của node label trong cặp key-value. Nếu hai node được gắn label với cùng một giá trị cho key này, Scheduler sẽ xem hai node đó là trong cùng một topology. Scheduler sẽ cố gắng đặt một số lượng pod cân bằng trong mỗi miền topology. 
  • Ngoài ra, chúng ta xác định một miền hợp lệ là một miền mà các node của nó đáp ứng yêu cầu của nodeAffinityPolicy và nodeTaintsPolicy. 
  • whenUnsatisfiable: đây là cách xử lý pod nếu nó không thỏa mãn ràng buộc mở rộng. Mặc định, DoNotSchedule sẽ không lập lịch pod. Trong khi đó, ScheduleAnyway sẽ lập lịch pod và ưu tiên node có giá trị skew nhỏ nhất. 
  • labelSelector: đây là để tìm Pod phù hợp. Các pod khớp với label selector này sẽ được đếm để quyết định số lượng pod trong miền topology tương ứng của chúng. Ví dụ:

VD1**: 1 PTSC**

Giả sử có 1 cluster 4 node trong đó 3 pod có nhãn foo: bar lần lượt nằm ở node1, node2 và node3:

Scheduling trên Kubernetes (phần 3) - Ảnh 2.

Nếu như muốn Pod tiếp theo được lập lịch được trải đều với các Pod hiện có trên các khu vực, bạn có thể sử dụng yaml:

Scheduling trên Kubernetes (phần 3) - Ảnh 3.

topologyKey: zone chỉ định rằng việc phân phối đồng đều chỉ áp dụng trên các node được gán nhãn zone: <any value> (nodes không có nhãn zone sẽ được bỏ qua). Trường whenUnsatisfiable: DoNotSchedule sẽ cho scheduler biết rằng pod sắp tới sẽ giữ ở pending nếu không tìm được cách bỏ qua constraint

Nếu như scheduler đặt pod sắp tới vào zone A, thì phân phối của pod sẽ thành [3, 1]. và kết quả của skew là 2 (3 - 1), như vậy sẽ vi phạm giá trị maxSkew: 1. Để thỏa mãn trong trường hợp này, pod sẽ được schedule vào zone B:

Scheduling trên Kubernetes (phần 3) - Ảnh 4.

hoặc

Scheduling trên Kubernetes (phần 3) - Ảnh 5.

Có thể tinh chỉnh spec của Pod để phù hợp với yêu cầu như:

  • Đổi maxSkew vào giá trị lớn hơn - như là 2 - thì pod có thể vào Zone A. 
  • Đổi topologyKey thành node thì pod sẽ được phân phối theo node thay vì zone. 
  • Đổi whenUnsatisfiable: DoNotSchedule thành whenUnsatisfiable: ScheduleAnyway để đảm bảo rằng pod luôn có thể schedule

VD2**: Nhiều PTSC**

Mô hình tương tự như trên, nhưng lần này sẽ sử dụng nhiều hơn 1 PTSC

Scheduling trên Kubernetes (phần 3) - Ảnh 6.

Trong trường hợp này, để thỏa mãn điều kiện đầu tiên, Pod chỉ có vể được đặt vào zone B. Nhưng để thoải mãn điều kiện thứ 2 thì pod chỉ có thể thỏa mãn vào node node4.

Như vậy scheduler sẽ thấy chỉ có node4 là thoả mã cả 2 điều kiện

Scheduling trên Kubernetes (phần 3) - Ảnh 7.

 Lưu ý:

Nếu như khai báo có cả PTSCaffinity thì sẽ bỏ qua các nút không khớp khi tính skew nếu Pod đến có spec.nodeSelector hoặc spec.affinity.nodeAffinity

Ví dụ:

Scheduling trên Kubernetes (phần 3) - Ảnh 8.

Trong trường hợp này ta muốn loại trừ zone C thì có thể cho vào affinity.

Scheduling trên Kubernetes (phần 3) - Ảnh 9.

Ví dụ 2:

Scheduling trên Kubernetes (phần 3) - Ảnh 10.

Giả sử có một nhóm Node được gắn thẻ là "env=prod", "env=staging" và "env=qa", và bây giờ muốn đặt các Pod đồng đều vào ENV "qa" trên các zone. Khi sử dụng NodeSelector hoặc NodeAffinity, PodTopologySpread sẽ bỏ qua các node đó và tính toán các ràng buộc về phân bố pod giữa các node thỏa mãn.

Ràng buộc mặc định của cụm

Có thể đặt các ràng buộc phân tán mặc định cho một cụm. 

Các ràng buộc phân tán mặc định này được áp dụng cho Pod khi và chỉ khi:

  • Không có bất kỳ ràng buộc nào trong .spec.topologySpreadConstraints
  • Thuộc về một Dịch vụ, ReplicaSet, StatefulSet hoặc ReplicationController.

Các ràng buộc phân tán mặc định có thể được đặt trong kube-scheduler.

Tổng kết

Qua bài viết ta tổng kết lại 1 số kiến thức như sau:

Có thể sử dụng PTSC để đạt được các mục tiêu sau:

  • Đảm bảo khả năng cao availability: Bằng cách phân tán các pod trên nhiều miền lỗi, bạn có thể giảm thiểu khả năng mất khả năng hoạt động của một miền lỗi sẽ ảnh hưởng đến tất cả các pod của bạn. 
  • Tăng hiệu quả sử dụng tài nguyên: Bằng cách phân tán các pod trên nhiều failure-domain, có thể đảm bảo rằng các tài nguyên được sử dụng hiệu quả hơn.

PTSC là một tính năng hữu ích để kiểm soát cách các pod được phân tán trong cluster. Nếu quan tâm đến việc đạt được tính sẵn sàng cao và sử dụng tài nguyên hiệu quả, thì nên xem xét sử dụng PTSC.

SHARE