Несколько больших узлов или много маленьких узлов?

Управление кластером Kubernetes - не универсальная проблема. Есть много способов оптимизировать ваш кластер, и очень важно спроектировать ваше приложение таким образом, чтобы оно было надежным и устойчивым.

Как инженеры по надежности сайта и DevOps, вам часто нужно понимать требования к приложениям, которые вы будете запускать в своем кластере, а затем учитывать различные факторы при его проектировании.

Выбор правильного размера узла имеет решающее значение при создании приложений для масштабирования. Множество меньших узлов и несколько больших узлов образуют два конца спектра. Учитывая, что кластеру требуется в общей сложности 24 ГБ памяти и 12 процессоров, следует ли выбрать 12 машин с 1 ЦП / 2 ГБ или две машины с 6 ЦП / 12 ГБ?

Здравый смысл подсказывает нам, что нужно выбирать где-то посередине, но давайте разберемся, что нужно учитывать при принятии решения. Давайте посмотрим, что предлагают нам оба конца спектра, прежде чем выбирать подход.

Высокая доступность

Kubernetes по умолчанию обеспечивает высокую доступность ваших приложений, если вы используете как минимум два рабочих узла. Однако с точки зрения выбора между несколькими большими рабочими узлами или множеством небольших рабочих узлов нам нужно понимать, что мы получаем.

Если у нас есть кластер с двумя большими рабочими узлами и мы теряем один, мы теряем половину емкости кластера. Если вы не увеличите емкость узла на 100%, это приведет к катастрофе, поскольку ваш кластер не сможет справиться с двойной нагрузкой. Наличие нескольких рабочих узлов снижает риск на n. Например, если у вас есть кластер с десятью узлами и вы потеряете один, вы потеряете всего 10% емкости кластера.

Победитель: множество мелких узлов.

Накладные расходы на управление

С большим количеством узлов на картинке вы должны заботиться о большем количестве серверов, исправлять и обновлять их и поддерживать их. Чем меньше узлов, тем проще управлять. С DevOps и SRE использование таких инструментов, как Ansible или Puppet может упростить вам задачу, автоматизируя эти аспекты.

Если вы используете управляемый кластер Kubernetes, ваш облачный провайдер позаботится об установке исправлений и обновлении. Поэтому с современными инструментами это не дает значительного преимущества.

Победитель: Нет

Простота планирования контейнеров

Kubernetes рассматривает несколько аспектов при планировании контейнеров на рабочих узлах. Некоторые из них - доступность ресурсов, а также запросы и ограничения ресурсов контейнера. При большом количестве ресурсов, выделенных узлу, Kubernetes может легко запланировать узел в кластере с меньшим количеством больших рабочих узлов по сравнению с меньшими узлами.

Победитель: несколько крупных узлов.

Автоматическое масштабирование узла

Многие облачные провайдеры позволяют автоматическое горизонтальное масштабирование ваших рабочих узлов Kubernetes. Если у вас большие рабочие узлы, масштабирование будет немного неудобным. Например, если вы добавляете третий узел в двухузловой кластер, вы увеличиваете емкость на колоссальные 33%, а в десятиузловом кластере добавление еще одного увеличивает емкость всего на 9%. Это приводит к более плавному масштабированию и меньшим потерям ресурсов.

Победитель: множество мелких узлов.

Легкость обслуживания

Все узлы в кластере Kubernetes не остаются в рабочем состоянии бесконечно. Вам нужно будет отключить их для установки исправлений ОС, обновления версии Kubernetes и других мероприятий по обслуживанию. Если у вас меньше рабочих узлов, становится трудно выполнять обслуживание, не нарушая работу ваших приложений. Кроме того, отключение одного узла сильно перегружает другие, поэтому в большинстве случаев вам потребуется время простоя. То же самое не требуется, если у вас несколько небольших узлов. Вы можете обслуживать по одному узлу за раз, а Kubernetes может легко перенести ваши контейнеры в другие свободные узлы.

Победитель: множество мелких узлов.

Кубелет Накладные расходы

Kubelet отвечает за взаимодействие с базовой средой выполнения контейнера для запуска контейнеров на рабочих узлах. Если у вас есть несколько контейнеров, работающих на одном рабочем узле, что является типичным случаем с большими кластерами узлов, это может привести к зависанию Kubelet, поскольку он должен заботиться о нескольких контейнерах.

Kubelet не оптимизирован для управления более чем определенным количеством контейнеров, и многие облачные провайдеры ограничивают количество контейнеров, которые вы можете иметь на одном рабочем узле. Поэтому меньшее количество больших рабочих узлов может быть неправильным решением, когда у вас есть множество меньших контейнеров.

Победитель: множество мелких узлов.

Системные накладные расходы

И наоборот, несколько узлов заглушают ваши главные серверы, поскольку им приходится взаимодействовать с многочисленными рабочими узлами и управлять ими. Kubernetes не оптимизирован для обработки более 500 узлов на кластер (хотя они утверждают, что могут управлять до 5000 узлов).

Следовательно, вы должны быть осторожны с тем, сколько узлов вы добавляете в свой кластер, и оптимизировать размер узла с требуемым числом. В большинстве случаев такое количество узлов может не потребоваться, но нередко можно увидеть такие настройки в высокопроизводительных приложениях.

Победитель: несколько крупных узлов.

Оптимизация ваших узлов

Ну как всегда! Правильный ответ находится где-то посередине, и вам не следует выбирать ни одну из двух крайностей.

Вот некоторые из правил, которым я следую, и они мне очень подходят. Вам следует поискать ответы на приведенные ниже вопросы, чтобы выбрать нужный размер.

Какие типы приложений вы используете?

Вы запускаете приложение микросервисов, которое содержит несколько контейнеров, каждый из которых занимает мало места, или несколько монолитов, требующих ГБ памяти и ядер ЦП? Базы данных? Или смешанная нагрузка?

Можете ли вы объединить похожие рабочие нагрузки?

Можно ли разделить нагрузки по категориям для смешанных рабочих нагрузок? Например, если вы планируете запустить приложение микросервисов, которое взаимодействует с несколькими базами данных MySQL, вы можете создать группу для каждой из ваших микросервисов и баз данных. Точно так же, если вы используете смесь монолитов и микросервисов, например стек ELK для мониторинга кластера, вы можете поместить его в другую группу. Для простоты я только что упомянул три категории, но вы можете создавать их сколько угодно.

Максимальное использование ресурсов конкретной категории приложений

Если вы можете сгруппировать свои приложения в несколько скобок, тогда вам необходимо понять максимальные требования к ресурсам для одного приложения в каждой категории. Например, если вы запускаете микросервисы, монолиты и базы данных в кластере, вам необходимо получить максимальное использование одного экземпляра базы данных, микросервиса и монолита.

Получите количество приложений по категории

Следующим шагом будет получение запланированного количества приложений для каждого типа приложения. Вы можете использовать, например, восемь баз данных MySQL, 200 микросервисов и девять монолитов. Запишите их. Не переоценивайте. Kubernetes разработан для масштабируемости, и вы всегда можете использовать функцию автомасштабирования кластера у некоторых поставщиков. В противном случае вы можете добавить узлы вручную позже.

Поместите каждую категорию в отдельные пулы узлов

Лучший способ настроить ваш узел - создать пул узлов для каждой категории. Большинство кластеров Kubernetes поддерживают несколько пулов узлов, а гетерогенные узлы разрешены в локальных настройках.

Планируйте высокую доступность

Нам необходимо иметь как минимум два узла на пул узлов, чтобы гарантировать высокую доступность. Kubernetes рекомендует максимум 110 контейнеров на узел. Имейте в виду, что на узлах также работают некоторые системные контейнеры.

Возможно, вам придется отрегулировать это значение в соответствии с вашим облачным провайдером, поскольку большинство из них предлагает различные уровни жестких ограничений на количество подов, которые вы можете запускать на каждом узле. Идея состоит в том, чтобы запланировать меньше модулей, чем установлено.

Выровняйте контейнеры по узлам для управления емкостью

Если мы планируем сбой одного узла за раз, вам следует избыточно выделить каждый узел таким образом, чтобы они могли справиться с дополнительными требованиями к емкости для рабочих нагрузок, выполняемых на этом узле.

Выровняйте свои контейнеры и узлы для оптимального управления емкостью. Например, если у нас есть 20 контейнеров, лучший способ запланировать их - иметь четыре модуля на узел, так как в этом случае мы должны избыточно выделить каждый узел только на 20% вместо 100%, если мы выберем два узла.

Как я пришел к этой цифре? Просто посмотрите на ближайшее меньшее квадратное число и извлеките из него корень. Это должно дать вам максимальное количество контейнеров, которое у вас должно быть на узел.

Учитывайте накладные расходы системы Kubernetes

Учтите тот факт, что системные ресурсы Kubernetes потребляют некоторый объем ЦП и памяти на узел, поэтому доступная память меньше выделенной. Узнайте у поставщика облачных услуг это значение и добавьте его к емкости узла.

Подводя итоги

Учитывая все, вы можете использовать следующее, чтобы прийти к оптимальной цифре:

Количество контейнеров на узел = квадратный корень из ближайшего наименьшего полного квадрата к общему количеству контейнеров, при условии, что количество контейнеров на узел не превышает рекомендуемого значения.

Количество узлов = Общее количество контейнеров / Количество контейнеров на узел

Коэффициент избыточности = количество контейнеров на узел * максимальный ресурс на контейнер / (количество узлов - максимальное запланированное количество недоступных узлов)

Емкость узла = максимальный ресурс, требуемый на контейнер * количество контейнеров на узел + коэффициент избыточности + требования к системным ресурсам Kubernetes

Пример

Чтобы понять, как это работает, давайте рассмотрим пример.

Допустим, нам нужно два пула узлов:

  1. Микросервисы - 200 микросервисов с 0,1 ядром и максимальными требованиями к ресурсам ОЗУ 100 МБ на контейнер.
  2. Базы данных - 20 баз данных PostgreSQL с 2 ядрами и максимальным требованием к ресурсам ОЗУ 4 ГБ на контейнер

Предполагая, что системные ресурсы Kube используют 0,5 ядра и 0,5 ГБ ОЗУ, и мы планируем сбой одного узла за раз.

Для пула узлов микросервисов:

Ближайший нижний точный квадрат = 196

Количество контейнеров на узел = sqrt (196) = 14

Количество узлов = 200/14 = 14,28 ~ 15

Максимальное количество запланированных недоступных узлов = 1

Коэффициент избыточного выделения ресурсов = 14 * (0,1 ядра + 100 МБ ОЗУ) / (15–1) = 0,1 ядра + 100 МБ ОЗУ

Емкость узла = (0,1 ядра + 100 МБ ОЗУ) * 14 + 0,1 ядра + 100 МБ ОЗУ + 0,5 ядра + 500 МБ ОЗУ = 2 ядра + 2 ГБ ОЗУ

Для пула баз данных:

Ближайший нижний точный квадрат = 16

Количество контейнеров на узел = sqrt (16) = 4

Количество узлов = 20/4 = 5

Максимальное количество запланированных недоступных узлов = 1

Фактор избыточного выделения ресурсов = 4 * (2 ядра + 4 ГБ ОЗУ) / (5–1) = 2 ядра + 4 ГБ ОЗУ.

Емкость узла = (два ядра + 4 ГБ ОЗУ) * 4 + 2 ядра + 4 ГБ ОЗУ + 0,5 ядра + 0,5 ГБ ОЗУ = 10,5 ядра + 20,5 ГБ ОЗУ

Следовательно, для пула микросервисов вам потребуется 15 рабочих узлов с 2 ядрами и 2 ГБ ОЗУ каждый, а для пула базы данных вам потребуется пять рабочих узлов с 10,5 ядрами и 20,5 ГБ ОЗУ каждый. Для простоты можно округлить числа до следующего более высокого доступного типа машины.

Заключение

Проектирование кластера Kubernetes - это больше искусство, чем точная наука. Хотя приведенные выше рекомендации являются полезными, они по-прежнему являются руководящими принципами, и лучший способ научиться этому - подготовить свой кластер и оптимизировать его по мере того, как вы узнаете больше.

Спасибо за прочтение! Надеюсь, вам понравилась статья!