Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Ngày 27 tháng XNUMX tại hội nghị đình công 2019, như một phần của phần “DevOps”, báo cáo “Tự động mở rộng quy mô và quản lý tài nguyên trong Kubernetes” đã được đưa ra. Nó nói về cách bạn có thể sử dụng K8 để đảm bảo tính sẵn sàng cao cho các ứng dụng của bạn và đảm bảo hiệu suất cao nhất.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Theo truyền thống, chúng tôi xin hân hạnh giới thiệu video báo cáo (44 phút, nhiều thông tin hơn bài viết) và phần tóm tắt chính ở dạng văn bản. Đi!

Hãy phân tích chủ đề của báo cáo từng chữ và bắt đầu từ cuối.

Kubernetes

Giả sử chúng ta có các thùng chứa Docker trên máy chủ của mình. Để làm gì? Để đảm bảo khả năng lặp lại và cách ly, từ đó cho phép triển khai CI/CD đơn giản và tốt. Chúng tôi có nhiều phương tiện như vậy với container.

Kubernetes cung cấp gì trong trường hợp này?

  1. Chúng tôi ngừng suy nghĩ về những chiếc máy này và bắt đầu làm việc với “đám mây” cụm container hoặc pod (nhóm container).
  2. Hơn nữa, chúng tôi thậm chí không nghĩ đến từng nhóm riêng lẻ mà quản lý nhiều hơnоcác nhóm lớn hơn. Như là nguyên thủy cấp cao cho phép chúng tôi nói rằng có một mẫu để chạy một khối lượng công việc nhất định và đây là số phiên bản cần thiết để chạy nó. Nếu sau đó chúng tôi thay đổi mẫu, tất cả các phiên bản sẽ thay đổi.
  3. Với API khai báo Thay vì thực thi một chuỗi lệnh cụ thể, chúng tôi mô tả “cấu trúc của thế giới” (trong YAML), được tạo bởi Kubernetes. Và một lần nữa: khi mô tả thay đổi, cách hiển thị thực tế của nó cũng sẽ thay đổi.

Quản lý nguồn tài nguyên

CPU

Hãy để chúng tôi chạy nginx, php-fpm và mysql trên máy chủ. Các dịch vụ này thực sự sẽ có nhiều quy trình đang chạy hơn, mỗi quy trình đều yêu cầu tài nguyên máy tính:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)
(các con số trên slide là “những con vẹt”, nhu cầu trừu tượng của từng quy trình về sức mạnh tính toán)

Để làm việc với điều này dễ dàng hơn, việc kết hợp các quy trình thành các nhóm là hợp lý (ví dụ: tất cả các quy trình nginx thành một nhóm “nginx”). Một cách đơn giản và rõ ràng để thực hiện việc này là đặt mỗi nhóm vào một vùng chứa:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Để tiếp tục, bạn cần nhớ container là gì (trong Linux). Sự xuất hiện của chúng có thể thực hiện được nhờ vào ba tính năng chính trong kernel, được triển khai cách đây khá lâu: khả năng, không gian tên и nhóm. Và sự phát triển hơn nữa đã được hỗ trợ bởi các công nghệ khác (bao gồm cả các “vỏ” tiện lợi như Docker):

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Trong bối cảnh của báo cáo, chúng tôi chỉ quan tâm đến nhóm, bởi vì các nhóm điều khiển là một phần chức năng của vùng chứa (Docker, v.v.) thực hiện quản lý tài nguyên. Các quy trình được kết hợp thành các nhóm, như chúng tôi mong muốn, là các nhóm kiểm soát.

Hãy quay lại các yêu cầu CPU cho các quy trình này và bây giờ là các nhóm quy trình:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)
(Tôi nhắc lại rằng tất cả các con số đều là biểu hiện trừu tượng của nhu cầu về nguồn lực)

Đồng thời, bản thân CPU cũng có một nguồn tài nguyên hữu hạn nhất định (trong ví dụ này là 1000), thứ mà mọi người có thể thiếu (tổng nhu cầu của tất cả các nhóm là 150+850+460=1460). Điều gì sẽ xảy ra trong trường hợp này?

Hạt nhân bắt đầu phân phối tài nguyên và thực hiện nó một cách “công bằng”, cung cấp cùng một lượng tài nguyên cho mỗi nhóm. Nhưng trong trường hợp đầu tiên, chúng có nhiều hơn mức cần thiết (333>150), do đó, phần dư thừa (333-150=183) vẫn được dự trữ, phần này cũng được phân bổ đều giữa hai vùng chứa khác:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Kết quả là: thùng chứa đầu tiên có đủ tài nguyên, thùng thứ hai – không có đủ tài nguyên, thùng thứ ba – không có đủ tài nguyên. Đây là kết quả của hành động bộ lập lịch "trung thực" trong Linux - CFS. Hoạt động của nó có thể được điều chỉnh bằng cách sử dụng phép gán trọng lượng mỗi thùng chứa. Ví dụ như thế này:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Hãy xem trường hợp thiếu tài nguyên trong vùng chứa thứ hai (php-fpm). Tất cả tài nguyên vùng chứa được phân bổ đồng đều giữa các tiến trình. Kết quả là quy trình tổng thể hoạt động tốt, nhưng tất cả công nhân đều chậm lại, nhận được ít hơn một nửa những gì họ cần:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Đây là cách bộ lập lịch CFS hoạt động. Chúng tôi sẽ gọi thêm các trọng số mà chúng tôi gán cho vùng chứa yêu cầu. Tại sao lại như vậy - xem thêm.

Hãy nhìn vào toàn bộ tình huống từ phía bên kia. Như bạn đã biết, mọi con đường đều dẫn đến Rome và trong trường hợp máy tính, dẫn đến CPU. Một CPU, nhiều tác vụ - bạn cần đèn giao thông. Cách đơn giản nhất để quản lý tài nguyên là “đèn giao thông”: họ cấp cho một quy trình một thời gian truy cập cố định vào CPU, sau đó là quy trình tiếp theo, v.v.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Cách tiếp cận này được gọi là hạn ngạch cứng (hạn chế cứng). Hãy nhớ nó đơn giản như giới hạn. Tuy nhiên, nếu bạn phân phối giới hạn cho tất cả các vùng chứa, một vấn đề sẽ phát sinh: mysql đang lái xe dọc đường và đến một lúc nào đó nhu cầu sử dụng CPU của nó đã kết thúc, nhưng tất cả các quy trình khác buộc phải đợi cho đến khi CPU nhàn rỗi.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Hãy quay lại nhân Linux và sự tương tác của nó với CPU - bức tranh tổng thể như sau:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

cgroup có hai cài đặt - về cơ bản đây là hai “xoắn” đơn giản cho phép bạn xác định:

  1. trọng lượng cho container (yêu cầu) là Lượt chia sẻ;
  2. tỷ lệ phần trăm của tổng thời gian CPU để làm việc với các tác vụ vùng chứa (giới hạn) là phần.

Làm thế nào để đo CPU?

Có nhiều cách khác nhau:

  1. Cái gì vẹt, không ai biết - bạn cần phải thương lượng mọi lúc.
  2. Quan tâm rõ ràng hơn, nhưng tương đối: 50% máy chủ có 4 lõi và 20 lõi là những thứ hoàn toàn khác nhau.
  3. Bạn có thể sử dụng những cái đã được đề cập trọng lượng, điều mà Linux biết, nhưng chúng cũng chỉ mang tính chất tương đối.
  4. Tùy chọn thích hợp nhất là đo lường tài nguyên máy tính trong giây. Những thứ kia. tính bằng giây của thời gian bộ xử lý so với số giây của thời gian thực: 1 giây thời gian của bộ xử lý được cung cấp cho mỗi 1 giây thực - đây là toàn bộ một lõi CPU.

Để làm cho việc nói chuyện trở nên dễ dàng hơn, họ bắt đầu đo trực tiếp bằng hạt nhân, nghĩa là chúng có cùng thời gian CPU so với thời gian thực. Vì Linux hiểu được trọng lượng nhưng không hiểu nhiều về thời gian/lõi CPU nên cần có một cơ chế để dịch từ cái này sang cái khác.

Hãy xem xét một ví dụ đơn giản với một máy chủ có 3 lõi CPU, trong đó ba nhóm sẽ có trọng số (500, 1000 và 1500) có thể dễ dàng chuyển đổi thành các phần tương ứng của lõi được phân bổ cho chúng (0,5, 1 và 1,5).

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Nếu bạn lấy một máy chủ thứ hai, nơi sẽ có số lõi gấp đôi (6) và đặt các nhóm giống nhau ở đó, thì việc phân bổ số lõi có thể được tính toán dễ dàng bằng cách nhân với 2 (lần lượt là 1, 2 và 3). Nhưng một thời điểm quan trọng xảy ra khi nhóm thứ tư xuất hiện trên máy chủ này, có trọng lượng, để thuận tiện, sẽ là 3000. Nó lấy đi một phần tài nguyên CPU (một nửa số lõi) và đối với các nhóm còn lại, chúng được tính toán lại (giảm một nửa):

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Kubernetes và tài nguyên CPU

Trong Kubernetes, tài nguyên CPU thường được đo bằng milliadrax, I E. 0,001 lõi được lấy làm trọng lượng cơ bản. (Điều tương tự trong thuật ngữ Linux/cgroups được gọi là chia sẻ CPU, mặc dù chính xác hơn là 1000 millicores = 1024 chia sẻ CPU.) K8s đảm bảo rằng nó không đặt nhiều nhóm trên máy chủ hơn số tài nguyên CPU có trong tổng trọng số của tất cả các nhóm.

Làm thế nào điều này xảy ra? Khi bạn thêm máy chủ vào cụm Kubernetes, nó sẽ được báo cáo có bao nhiêu lõi CPU. Và khi tạo một nhóm mới, bộ lập lịch Kubernetes sẽ biết nhóm này sẽ cần bao nhiêu lõi. Do đó, nhóm sẽ được gán cho một máy chủ có đủ lõi.

Chuyện gì sẽ xảy ra nếu không yêu cầu được chỉ định (tức là nhóm không có số lượng lõi xác định mà nó cần)? Hãy cùng tìm hiểu cách Kubernetes thường tính tài nguyên.

Đối với một nhóm, bạn có thể chỉ định cả yêu cầu (bộ lập lịch CFS) và giới hạn (bạn có nhớ đèn giao thông không?):

  • Nếu chúng được chỉ định bằng nhau thì pod sẽ được gán một lớp QoS đảm bảo. Số lượng lõi này luôn có sẵn cho nó được đảm bảo.
  • Nếu yêu cầu nhỏ hơn giới hạn - Lớp QoS có thể nổ tung. Những thứ kia. Ví dụ: chúng tôi mong đợi một nhóm luôn sử dụng 1 lõi, nhưng giá trị này không phải là giới hạn đối với nhóm đó: đôi khi pod có thể sử dụng nhiều hơn (khi máy chủ có tài nguyên miễn phí cho việc này).
  • Ngoài ra còn có lớp QoS nỗ lực tốt nhất - nó bao gồm chính những nhóm mà yêu cầu không được chỉ định. Tài nguyên được trao cho họ lần cuối.

ký ức

Với trí nhớ, tình huống tương tự, nhưng hơi khác một chút - xét cho cùng, bản chất của những tài nguyên này là khác nhau. Nói chung, sự tương tự như sau:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Hãy xem các yêu cầu được thực hiện như thế nào trong bộ nhớ. Hãy để các nhóm tồn tại trên máy chủ, thay đổi mức tiêu thụ bộ nhớ, cho đến khi một trong số chúng lớn đến mức hết bộ nhớ. Trong trường hợp này, OOM Killer xuất hiện và giết chết tiến trình lớn nhất:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Điều này không phải lúc nào cũng phù hợp với chúng tôi, vì vậy có thể điều chỉnh những quy trình nào là quan trọng đối với chúng tôi và không nên loại bỏ. Để làm điều này, sử dụng tham số oom_score_adj.

Hãy quay lại các lớp QoS của CPU và rút ra sự tương tự với các giá trị oom_score_adj xác định mức độ ưu tiên tiêu thụ bộ nhớ cho các nhóm:

  • Giá trị oom_score_adj thấp nhất cho một nhóm - -998 - có nghĩa là nhóm đó sẽ bị tiêu diệt cuối cùng, điều này đảm bảo.
  • Cao nhất - 1000 - là nỗ lực tốt nhất, những nhóm như vậy sẽ bị tiêu diệt trước tiên.
  • Để tính các giá trị còn lại (có thể nổ tung) có một công thức, bản chất của nó là một nhóm càng yêu cầu nhiều tài nguyên thì khả năng bị giết càng ít.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

"Vòng xoắn" thứ hai - giới hạn_in_byte - về giới hạn. Với nó, mọi thứ trở nên đơn giản hơn: chúng tôi chỉ cần chỉ định dung lượng bộ nhớ được cấp tối đa và ở đây (không giống như CPU) không có vấn đề gì về cách đo nó (bộ nhớ).

trong tổng số

Mỗi nhóm trong Kubernetes được cung cấp requests и limits - cả hai tham số cho CPU và bộ nhớ:

  1. dựa trên các yêu cầu, bộ lập lịch Kubernetes hoạt động, phân phối các nhóm giữa các máy chủ;
  2. dựa trên tất cả các tham số, lớp QoS của nhóm được xác định;
  3. Trọng số tương đối được tính toán dựa trên yêu cầu của CPU;
  4. bộ lập lịch CFS được cấu hình dựa trên các yêu cầu của CPU;
  5. OOM Killer được cấu hình dựa trên yêu cầu bộ nhớ;
  6. “đèn giao thông” được cấu hình dựa trên giới hạn CPU;
  7. Dựa trên giới hạn bộ nhớ, giới hạn được định cấu hình cho nhóm.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Nói chung, bức tranh này trả lời tất cả các câu hỏi về cách phần chính của quản lý tài nguyên diễn ra trong Kubernetes.

Tính năng tự động

Bộ chia tỷ lệ tự động theo cụm K8s

Hãy tưởng tượng rằng toàn bộ cụm đã được chiếm dụng và một nhóm mới cần được tạo. Mặc dù pod không thể xuất hiện nhưng nó bị treo ở trạng thái chưa giải quyết. Để nó xuất hiện, chúng tôi có thể kết nối một máy chủ mới với cụm hoặc... cài đặt bộ chia tỷ lệ tự động theo cụm, công cụ này sẽ thực hiện việc đó cho chúng tôi: đặt mua một máy ảo từ nhà cung cấp đám mây (sử dụng yêu cầu API) và kết nối nó với cụm , sau đó nhóm sẽ được thêm vào .

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Đây là tính năng tự động điều chỉnh quy mô của cụm Kubernetes, hoạt động rất tốt (theo kinh nghiệm của chúng tôi). Tuy nhiên, cũng như những nơi khác, ở đây có một số sắc thái...

Miễn là chúng tôi tăng kích thước cụm thì mọi thứ đều ổn, nhưng điều gì sẽ xảy ra khi cụm bắt đầu giải phóng bản thân? Vấn đề là việc di chuyển các nhóm (để giải phóng máy chủ) rất khó khăn về mặt kỹ thuật và tốn kém về mặt tài nguyên. Kubernetes sử dụng một cách tiếp cận hoàn toàn khác.

Hãy xem xét một cụm gồm 3 máy chủ có Triển khai. Nó có 6 nhóm: hiện tại có 2 nhóm cho mỗi máy chủ. Vì lý do nào đó, chúng tôi muốn tắt một trong các máy chủ. Để làm điều này chúng ta sẽ sử dụng lệnh kubectl drain, cái mà:

  • sẽ cấm gửi nhóm mới đến máy chủ này;
  • sẽ xóa các nhóm hiện có trên máy chủ.

Vì Kubernetes chịu trách nhiệm duy trì số lượng nhóm (6), nên nó chỉ đơn giản là sẽ tạo lại chúng trên các nút khác, nhưng không phải trên nút bị vô hiệu hóa, vì nó đã được đánh dấu là không có sẵn để lưu trữ các nhóm mới. Đây là cơ chế cơ bản cho Kubernetes.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Tuy nhiên, ở đây cũng có một sắc thái. Trong tình huống tương tự, đối với StatefulSet (thay vì Deployment), các hành động sẽ khác. Bây giờ chúng ta đã có một ứng dụng trạng thái - ví dụ: ba nhóm có MongoDB, một trong số đó có một số loại sự cố (dữ liệu đã bị hỏng hoặc một lỗi khác khiến nhóm không thể khởi động chính xác). Và chúng tôi lại quyết định vô hiệu hóa một máy chủ. Chuyện gì sẽ xảy ra?

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

MongoDB có thể chết vì nó cần số đại biểu: đối với một cụm gồm ba cài đặt, ít nhất hai cài đặt phải hoạt động. Tuy nhiên, điều này không xảy ra - nhờ vào PodDisruptBudget. Tham số này xác định số lượng nhóm làm việc tối thiểu được yêu cầu. Biết rằng một trong các nhóm MongoDB không còn hoạt động và thấy rằng PodDisruptionBudget được đặt cho MongoDB minAvailable: 2, Kubernetes sẽ không cho phép bạn xóa nhóm.

Điểm mấu chốt: để chuyển động (và trên thực tế là tạo lại) các nhóm hoạt động chính xác khi cụm được giải phóng, cần phải định cấu hình PodDisruptionBudget.

Chia tỷ lệ theo chiều ngang

Hãy xem xét một tình huống khác. Có một ứng dụng đang chạy dưới dạng Triển khai trong Kubernetes. Lưu lượng truy cập của người dùng đến các nhóm của nó (ví dụ: có ba nhóm trong số đó) và chúng tôi đo lường một chỉ báo nhất định trong các nhóm đó (ví dụ: tải CPU). Khi tải tăng lên, chúng tôi ghi lại theo lịch trình và tăng số lượng nhóm để phân phối yêu cầu.

Ngày nay trong Kubernetes, việc này không cần phải thực hiện thủ công: việc tăng/giảm tự động số lượng nhóm được định cấu hình tùy thuộc vào giá trị của các chỉ báo tải đo được.

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Các câu hỏi chính ở đây là: chính xác những gì để đo lường и làm thế nào để giải thích các giá trị thu được (để đưa ra quyết định thay đổi số lượng nhóm). Bạn có thể đo lường rất nhiều:

Tự động hóa quy mô và quản lý tài nguyên trong Kubernetes (báo cáo tổng quan và video)

Cách thực hiện việc này về mặt kỹ thuật - thu thập số liệu, v.v. - Tôi đã nói chi tiết trong báo cáo về Giám sát và Kubernetes. Và lời khuyên chính cho việc lựa chọn các thông số tối ưu là cuộc thí nghiệm!

SỬ DỤNG phương pháp (Sử dụng độ bão hòa và lỗi), ý nghĩa của nó như sau. Trên cơ sở nào thì việc mở rộng quy mô có ý nghĩa, chẳng hạn như php-fpm? Dựa trên thực tế là công nhân đang cạn kiệt, đây là sử dụng. Và nếu công nhân đã kết thúc và các kết nối mới không được chấp nhận, thì điều này đã xảy ra rồi. bão hòa. Cả hai tham số này phải được đo và tùy thuộc vào các giá trị, phải thực hiện chia tỷ lệ.

Thay vì một kết luận

Báo cáo còn có phần tiếp theo: về chia tỷ lệ theo chiều dọc và cách chọn nguồn lực phù hợp. Tôi sẽ nói về điều này trong các video tiếp theo trên YouTube của chúng tôi - đăng ký để không bỏ lỡ!

Video và slide

Video màn trình diễn (44 phút):

Trình bày báo cáo:

PS

Các báo cáo khác về Kubernetes trên blog của chúng tôi:

Nguồn: www.habr.com

Thêm một lời nhận xét