company_banner

Рабочие узлы Kubernetes: много маленьких или несколько больших?

Автор оригинала: Daniel Weibel
  • Перевод

При создании кластера Kubernetes могут возникать вопросы: сколько настроить рабочих узлов и какого типа? Что лучше для кластера on-premise: купить несколько мощных серверов или задействовать десяток старых машин в вашем дата-центре? А в облаке лучше взять восемь одноядерных или два четырехъядерных инстанса?

Ответы на эти вопросы — в статье Даниэля Вайбеля, инженера-программиста и преподавателя обучающего проекта Learnk8s в переводе команды Kubernetes aaS от Mail.ru.

Емкость кластера


В целом, кластер Kubernetes можно рассматривать как большой «суперузел». Его общая вычислительная мощность является суммой мощностей всех составляющих узлов.

Существует несколько способов достичь желаемой целевой емкости кластера. Например, нам нужен кластер с общей емкостью 8 процессорных ядер и 32 ГБ оперативной памяти, потому что набор приложений требует такого количества ресурсов. Тогда можно установить два узла по 16 ГБ памяти или четыре узла по 8 ГБ памяти, два четырехъядерных процессора или четыре двухъядерных.

Вот только два возможных способа создания кластера:


Обе опции дают кластер с одинаковой емкостью, но в конфигурации снизу установлено четыре меньших узла, а в конфигурации сверху — два больших.

Какой вариант лучше?


Чтобы ответить на этот вопрос, рассмотрим преимущества обоих вариантов. Мы свели их в таблицу.

Несколько больших узлов
Много маленьких узлов
Проще управление кластером (если он on-premise)
Плавное автомасштабирование
Дешевле (если on-premise)
Цена мало отличается (в облаке)
Можно запускать ресурсоемкие приложения
Полноценная репликация
Ресурсы используются эффективнее (меньше оверхед на системные демоны Выше отказоустойчивость кластера

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

Итак, обсудим подробнее каждый пункт из таблицы.

Первый вариант: несколько больших узлов


Самый экстремальный вариант — один рабочий узел на всю емкость кластера. В примере выше это был бы один рабочий узел с 16 ядрами ЦП и 16 ГБ оперативной памяти.

Плюсы


Плюс № 1. Проще управление
Проще управлять несколькими машинами, чем целым парком. Быстрее накатывать обновления и исправления, проще синхронизировать. Количество сбоев в абсолютных цифрах тоже меньше.

Обратите внимание, что все вышесказанное относится к своему железу, своим серверам, а не к облачным инстансам.

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

Маршрутизация трафика и распределение нагрузки между подами в облаке выполняется автоматически: приходящий из интернета трафик направляется на основной балансировщик нагрузки, тот направляет трафик на порт одного из узлов (сервис NodePort выставляет порт в диапазоне 30000-32767 в каждом узле кластера). Правила, установленные kube-proxy, перенаправляют трафик с узла на под. Вот как это выглядит для десяти подов на двух узлах:


Плюс № 2. Меньше затрат на узел
Мощная машина дороже, но рост цены не обязательно линейный. Другими словами, один десятиядерный сервер с 10 ГБ памяти обычно дешевле, чем десять одноядерных с тем же количеством памяти.

Но обратите внимание, что это правило обычно не работает в облачных сервисах. В текущих схемах ценообразования у всех основных поставщиков облачных услуг цены растут линейно с увеличением емкости.

Таким образом, в облаке обычно нельзя сэкономить на более мощных серверах.

Плюс № 3. Можно запускать ресурсоемкие приложения
Некоторым приложениям необходимы мощные серверы в кластере. Например, если система машинного обучения требует 8 ГБ памяти, вы не сможете запустить ее на узлах по 1 ГБ, а только при наличии хотя бы одного большого рабочего узла.

Минусы


Минус № 1. Много pod'ов на узел
Если одна и та же задача выполняется на меньшем количестве узлов, то на каждом из них, естественно, будет больше pod'ов.

Это может стать проблемой.

Причина в том, что каждый модуль вносит некоторые накладные расходы на среду выполнения контейнера (например, Docker), а также kubelet и cAdvisor.

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

CAdvisor собирает статистику использования ресурсов всех контейнеров на узле, а kubelet регулярно запрашивает эту информацию и предоставляет ее через API. Опять же, чем больше контейнеров, тем больше работы и для cAdvisor, и для kubelet.

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


В репозитории Kubernetes некоторые жаловались, что узлы скачут между статусами Ready/NotReady, поскольку регулярные проверки kubelet всех контейнеров на узле занимают слишком много времени.
По этой причине Kubernetes рекомендует размещать не более 110 pod'ов на узел. В зависимости от производительности узла вы можете запускать больше подов на узел, но трудно предсказать, возникнут проблемы или все будет работать хорошо. Стоит заранее протестировать работу.

Минус № 2. Ограничение на репликацию
Слишком малое число узлов ограничивает эффективную степень репликации приложений. Например, если у вас приложение высокой доступности из пяти реплик, но только два узла, то эффективная степень репликации приложения уменьшается до двух.

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

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

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

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

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

Таким образом, чем больше узлов — тем меньше влияние аппаратных сбоев.

Минус № 4. Больше шаги автомасштабирования
В Kubernetes работает система автомасштабирования кластера для облачной инфраструктуры, что позволяет автоматически добавлять или удалять узлы в зависимости от текущих потребностей. С большими узлами автомасштабирование становится более резким и неуклюжим. Например, на двух узлах добавление дополнительного узла увеличит емкость кластера сразу на 50%. И вам придется заплатить за эти ресурсы, даже если они вам не нужны.

Таким образом, если вы планируете использовать автоматическое масштабирование кластера, то чем меньше узлы — тем более гибкое и экономичное масштабирование вы получите.

Теперь рассмотрим преимущества и недостатки большого количества маленьких узлов.

Второй вариант: множество маленьких узлов


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

Плюсы


Плюс № 1. Меньше последствия сбоя
Чем больше узлов, тем меньше pod'ов на каждом узле. Например, если у вас сто модулей на десять узлов, то на каждом узле будет в среднем по десять модулей.

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

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

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

Минусы


Минус № 1. Труднее управление
Большим количеством узлов труднее управлять. Например, каждый узел Kubernetes должен взаимодействовать со всеми остальными, то есть число связей растет квадратично, и все эти связи нужно отслеживать.

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

Растет нагрузка и на базу данных etcd — каждый kubelet и kube-proxy вызывает watcher для etcd (через API), которому etcd должен транслировать обновления объекта.

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


Официально Kubernetes поддерживает кластеры с числом узлов до 5000. Однако на практике уже 500 узлов могут вызвать нетривиальные проблемы.

Для управления большим количеством рабочих узлов следует выбирать более производительные главные узлы. Например, kube-up автоматически устанавливает правильный размер VM для главного узла в зависимости от количества рабочих узлов. То есть чем больше рабочих узлов, тем более производительными должны быть главные узлы.

Для решения этих специфических проблем есть специальные разработки, такие как Virtual Kubelet. Эта система позволяет обойти ограничения и строить кластеры с огромным количеством рабочих узлов.

Минус № 2. Больше накладные расходы
На каждом рабочем узле Kubernetes запускает набор системных демонов — к ним относятся среда выполнения контейнера (например, Docker), kube-proxy и kubelet, включая cAdvisor. Все вместе они потребляют определенное фиксированное количество ресурсов.

Если у вас много небольших узлов, доля этих накладных расходов на каждом узле больше. Например, представьте, что все системные демоны одного узла вместе используют 0,1 ядра ЦП и 0,1 ГБ памяти. Если у вас один десятиядерный узел с 10 ГБ памяти, то демоны потребляют 1% емкости кластера. С другой стороны, на десяти одноядерных узлах по 1 ГБ памяти демоны заберут 10% емкости кластера.

Таким образом, чем меньше узлов, тем эффективнее используется инфраструктура.

Минус № 3. Неэффективное использование ресурсов
На маленьких узлах может сложиться ситуация, что оставшиеся фрагменты ресурсов слишком малы, чтобы назначить им какую-то рабочую нагрузку, поэтому они остаются неиспользуемыми.

Например, каждый pod требует 0,75 ГБ памяти. Если у вас десять узлов, и на каждом по 1 ГБ памяти, можно запустить десять pod'ов — в итоге на каждом узле останется 0,25 ГБ неиспользуемой памяти.

Это означает, что 25% памяти всего кластера тратится впустую.

На большом узле с 10 ГБ памяти вы можете запустить 13 таких модулей — и останется всего один неиспользуемый фрагмент 0,25 ГБ.

В этом случае впустую расходуется только 2,5% памяти.

Таким образом, на больших узлах оптимальнее расходуются ресурсы.

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


Итак, что же лучше: несколько больших узлов в кластере или много маленьких? Как всегда, однозначного ответа нет. Многое зависит от типа приложения.

Например, если приложению требуется 10 ГБ памяти, очевиден выбор в пользу больших узлов. А если приложение требует десятикратной репликации для высокой доступности, вряд ли стоит рисковать, размещая реплики всего на двух узлах — в кластере должно быть минимум десять узлов.

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

И вовсе не обязательно делать все узлы одинакового размера. Ничто не мешает экспериментировать сначала с узлами одного размера, потом добавить к ним узлы другого размера, сочетая их в кластере. Рабочие узлы кластера Kubernetes могут быть полностью гетерогенными. Так что можно попробовать совместить преимущества обоих подходов.

Единого рецепта не существует, а у каждой ситуации свои нюансы, и только продакшн покажет правду.

Перевод подготовлен командой облачной платформы Mail.ru Cloud Solutions.

Mail.ru Group
Строим Интернет

Комментарии 19

    +1
    добавление ядер-процессоров не бесплатное — шина памяти ограничена, например.
      +3

      Мне кажется, проблема в данном случае в том, что выбор делается между 2 серверами или 4. При таком количестве серверов в целом использование Kubernetes мне кажется весьма сомнительной идеей. В случае же когда нужно выбрать, скажем, 50 более мощных серверов или 100 более слабых, как правило более мощные сервера предпочительны, поскольку добавление 1 сервера увеличивает емкость незначительно, так что не обязательно иметь маленькие сервера, чтобы плавнее масштабировать расходы на железо/виртуалки, и при этом возможна более полная утилизация ресурсов.

        +1

        Думаю на цифрах 50, 100 и т.д. в первую очередь будет важен вопрос цены и затрат на электроенергию (в случае своего железа), чем логика управления k8s.

          +4

          Сложный вопрос. Я бы исходил из оценки, что один разработчик обходится примерно в такое же количество денег, сколько и 10-20 физических серверов (всё зависит от конфигурации серверов, конечно же, от их общего количества и т.д.), так что по факту 50-100 серверов будут эквивалентны 5-10 разработчикам. Поддержка живого Kubernetes кластера, даже в весьма простых случаях, насколько я могу судить, обычно требует пару full-time инженеров (или отдавать на аутсорс, но не все компании готовы так делать, и не факт, что это покроет все use-кейсы). То есть, условно, по моим очень грубым оценкам, минимальная «цена Kubenetes» в плане стоимости поддержки этого решения в продакшене может составлять эквивалент 20-40 физических серверов :). То есть, электроэнергия в этом случае вряд ли является определяющим фактором.

            +2
            Один инженер нужной квалификации и владеющий автоматизацией может обслуживать до 5-10 кластеров, даже не самых простых. Кубер сейчас довольно устойчив к автопилоту из коробки, если настроен мониторинг, логирование и алерты.
              +1

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


              если настроен мониторинг, логирование и алерты.

              Как будто сделать это два пальца обоссать, извините.

                +1
                Это автоматизируется, причем неплохо — как установка ELK+fluentd для логов, так и прометеус с базовыми алертами из коробки. Используя тот же Terraform production-ready кластер представляет собой небольшой yaml. И да, это касается только самого кластера k8s.
                Деплои и построение структуры это совсем другой разговор, тут пока что все очень индивидуально
                  +1

                  Все очень индивидуально. Я соглашусь, что вряд ли в отдельно взятой организации ХХХ будут раскатывать сильно разные кластера — это реально дорого с точки зрения обслуживания. Но если у парней баре метал — про терраформ скорее всего придется забыть. Есть, конечно, монстры вроде Г-на Халупа из Тинькофф, которые свой провайдер пишут, но у них масштабы сотни узлов — до этого ещё дорасти надо. А для бытовых нужд, коллеги подсказывают, и кьюбспрей ок.

          +1
          У меня он (сервер) вообще один. Просто при использовании k8s резко упрощается конфигурация приложения — мне достаточно создать ветку в мерке и через 2-3 минуты на сервере доступна версия приложения собранная из этой ветки со своей базой, доменным именем, сертификатом и.т.д.
            0

            Докер + ансибл позволяют сделать все то же самое ))

              +2
              Наверняка вы правы, но k8s тоже использует докер и если посмотреть на этот докер, то там просто помойка. Думаю, что ансибл сделает тоже самое из докера, но не предоставит того уровня абстракции, который дает k8s.
          +1
          За on-premise не скажу, не использовал, но в облаке кажется куда выгоднее и надежнее использовать множество серверов например per product, чем один большой с кучей продуктов per namespace. Kubernetes-on-Kubernetes типа Gardener — это вообще вершина оркестрации, но слишком большой оверхэд, если небольшая компания и нет своего KaaS
            +1

            Вообще в облаке можно кластер per product делать, заодно не болит голова о rbac в кластере

            +1

            Статья странная. Главные узлы? Модули? Я бы все-таки переводил по-другому

              +1

              Еще я совсем забыл — совершенно не рассмотрен вопрос компоновки кластера из год с разными параметрами cpu (в первую очередь — частота процессора)

              +1
              Хорошая тема, как раз по ней копаю, только азы пока.
              В связи с этим есть вопрос — буду признателен за ссылки и подсказки. Ситуация такая — есть свой небольшой проект — фронт на Angular, бек на NodeJS и облако на Яше. Пилил всегда все на локал хосте, ибо деплоем и т.д никогда не занимался. Но вот пришло время все это дело не просто перенести в облако, но и админить и обновлять и т.д С фронтом все понятно — его можно куда угодно вставить — хоть с беком вместе, хоть где угодно. А вот с беком вопрос — как и с помощью каких инструментов все организовать по уму?
              Сейчас вот как сделал — фронт у меня отдельно, на отдельном домене — с ним нет проблем. А вот с беком печаль — пока временно у меня так — поднял сервак на nginx, подключил SSL. Рабочая скомпиленная версия бека у меня запущена на 7000 порту через PM2 и на нее nginx направляет путь мойдомен.ру/api.
              А дев версию также запускаю в облаке через nodemon на 3000 порту и nginx направляет путь мойдомен.ру/dev. А редактирую файлы редактором через SSH напрямую. nodemon после сохранения автоматом перезапускает приложуху и становится доступны изменения. Но печаль в том что компилится и перезапускается это все тоже в облаке и забирает часть ресурсов.
              Можно конечно пилить типа все на локалке, а в облако заливать уже компиленную версию — но сейчас как раз буду делать яндекс кассу и там вроде как запросы надо делать со своего сервака с SSL а не с локалхоста и надо сразу же пилить и тестить одновременно.
              В связи с этим вопрос — как все это правильно организовать по уму? Что бы и пилить можно было, и тестить сразу же, и выкатывать обновления и в дальнейшем расширять потом.
              В телеграм группах общался на эту тему — там толку 0 — одни разрабы сидят — каждый пилит как хочет.
                +1

                все правильно — организовывать в кубернетесе несколько окружений. Можно по неймспейсам распихать и каждому окружению свои ресурсы выделить. Редактирование кода — только через гит. Никаких больше хотрелоадов и прочей дичи. Код в гитлабе — новая версия — оно собирается в образы, из них в кубернетесе разворачиваются сервисы. Далее тестируете. Потом обновляете прод. Не сложно, в общем

                  +1
                  Может и не сложно, если уже с этим работаешь ))
                  А пока кубернетес для меня темный лес )
                  Спасибо за подсказки.
                +3
                Единого рецепта не существует, а у каждой ситуации свои нюансы, и только продакшн покажет правду.


                Как хорошо, что я читаю статьи с конца.

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

                Самое читаемое