Kubernetes (hay còn gọi là K8s), đã tồn tại trong 5 năm qua, hứa hẹn sẽ giải phóng người dùng khỏi rắc rối cơ sở hạ tầng. Các kỹ sư phần mềm không cần phải giải quyết việc phân bổ cơ sở hạ tầng, công suất hoặc tối ưu hóa trên cơ sở hạ tầng. Còn đối với DevOps, họ chỉ cần quản lý đủ các work node để các pod được phân bổ.

Làm việc với K8 đôi khi đem lại trải nghiệm của một máy tính lớn có thể chứa tất cả các ứng dụng nơi chúng ta chỉ cần kubectl apply – ing pod tất cả mọi nơi, nhưng vẫn còn một số hạn chế nên xem xét trong khi triển khai các ứng dụng. Ví dụ: một số ứng dụng phải có ít nhất một bản sao trên mỗi vùng khả dụng, một số ứng dụng không được đặt chung với các ứng dụng khác trong cùng một host, một số ứng dụng khác phải chạy trên một phiên bản cụ thể,…..

Về mặt cơ sở hạ tầng, có một số điều cần được quản lý để thực hiện được yêu cầu scheduling phía trên:

  • # worker nodes vừa đủ để chứa tất cả các pods
  • Mở rộng – dựa trên số liệu nào?
  • Các giới hạn của scheduling, chẳng hạn như vị trí PVC, affinity và toleration
  • Các phiên bản nào được khởi chạy như  các worker node

Mặc dù một số ràng buộc và yêu cầu scheduling này có thể được đáp ứng bằng các kỹ thuật khác nhau (eksctl nodegroups, instance-group trong KOPS, node pool GKE). Bài viết này sẽ trình bày cách để thực hiện bằng việc chỉ sử dụng K8s. 

 

Tình huống 1 – Scheduling đơn giản

Ở ví dụ này không có yêu cầu gì đặc biệt – ta có một pod đơn giản và muốn chạy ở đâu cũng được. Khó khăn ở đây đó là không có chỗ trống trong cluster để pod này hoạt động (có thể còn một số chỗ nhưng thậm chí cũng không đủ để chạy một ứng dụng nhỏ). Tình huống này được minh họa trong sơ đồ 1.

Vậy chúng ta nên là gì? Câu trả lời rất đơn giản – chỉ cần mở rộng cluster như minh họa trong sơ đồ # 2

 

Tình huống 2:  AZ cụ thể

Nếu pod đầu tiên không “kén chọn” lắm thì trong ví dụ tiếp theo, pod của chúng ta phải nằm trong vùng khả dụng cụ thể (ví dụ us-west-1b). Điều này đạt được bằng cách sử dụng K8 NodeSelector. Đối tượng nodeSelector trong đặc tả của pod, schedule các pod trên các node có nhãn cụ thể. Có một số nhãn tích hợp trên mỗi node hiện đang được gắn theo mặc định và có thể được sử dụng cho nhu cầu của chúng ta. Trong ví dụ của chúng ta, nhãn tích hợp này sẽ là failure-domain.beta.kubernetes.io/zone.  Trên quan điểm cơ sở hạ tầng, không có đủ tài nguyên trong us-west-1b (để mô phỏng kết nối giữa scheduling pod và cơ sở hạ tầng của cluster) (sơ đồ 3 dưới đây)

Mặc dù có đủ chỗ trong cluster để giữ pod này theo các yêu cầu, nhưng không đủ chỗ để pod này hoạt động. Giải pháp cho ví dụ này – mở rộng thêm node trong vùng khả dụng phù hợp để cho phép chạy và lên lịch pod mới. (sơ đồ 4)

 

Tình huống 3 – Khối lượng liên tục yêu cầu vị trí

Các cluster liên tục phát triển và các pod được lập lịch bình thường. Khía cạnh lập lịch tiếp theo cần được cân nhắc khá liên quan đến ví dụ trước – 1 pod PVC cần được lập lịch trong cluster, nhưng lần này, pod đó không chỉ định một vùng khả dụng cụ thể. Đó những hạn chế từ vị trí PVC (ví dụ: PVC trong AZ thể hiện ở mô hình  5)

Để giải quyết vấn đề scheduling này, cần mở rộng quy mô cluster một lần nữa, nhưng lần này là trên us-west-1a có đính kèm PVC (sơ đồ 6)

Tình huống 4 – Các trường hợp cụ thể

Một số ứng dụng yêu cầu lưu lượng cao ví dụ API-Servers/Proxies/Ứng dụng web. Do đó, các pod này nên chạy trong các trường hợp có băng thông rộng, ví dụ c5.4xlarge. 

Để làm được việc này, có thể chỉ định một nodeAffinity với nhãn tích hợp đặc biệt của K8 beta.kubernetes.io/instance-type và tạo ra một danh sách các phiên bản khả dụng cho pod của chúng ta.

 

Kết luận

Mặc dù K8s cho phép chạy tất cả các ứng dụng trong một máy tính lớn, nhưng trách nhiệm của chúng ta là cần xác định giới hạn scheduling của các ứng dụng và đảm bảo có đủ các cơ sở hạ tầng phù hợp để đáp ứng các yêu cầu của ứng dụng.

Một số công cụ K8 cho phép ta chỉ định các yêu cầu lập lịch dựa trên cấp độ của pod đó:

  1. Pod affinity/anti-affinity
  2. nodeAffinity/anti-affinity
  3. Taints and Tolerations
  4. Node selector

Bằng cách sử dụng các cách trên, chúng ta có thể tạo ra một thông số cơ sở hạ tầng (YAML) cho ứng dụng để có thể sử dụng cho nhiều công cụ K8 (kể cả khi được tạo bởi KOPS / kubespray / EKS / GKE….) và có thể tự mở rộng từ cấp độ triển khai.

Về mặt cơ sở hạ tầng, cần sử dụng các giải pháp Autoscaling Cluster để đảm bảo có đủ các phiên bản (đúng loại và đúng vị trí ) cho các ứng dụng mà không cần quản lý cơ sở hạ tầng này theo cách thủ công. Các giải pháp đang có mặt trên thị trường là:

  • Spotinst Ocean: được phát triển bởi Spotinst nhằm để tiết kiệm chi phí dựa trên việc quản lý cơ sở hạ tầng bằng cách chạy các work nodes trên spot instance trong khi nhìn vào thông số kỹ thuật Pod và tìm kiếm tất cả các yêu cầu đã đề cập ((nodeSelectors, node/pod affinity/anti-affinity, taints & tolerations, nhận diện PVC……)
  • Cluster-autoscaler – được phát triển và hỗ trợ bởi cộng đồng. Có một số hạn chế và khác biệt trong việc triển khai giữa các nhà cung cấp đám mây. Yêu cầu mức độ vận hành cao hơn để giải quyết các chủ đề được đề cập trong bài này.