Добрый день, меня зовут Евгений Кузаков.

В силу рода деятельности (я руководитель DevOps-практики) периодически встают задачи сайзинга оборудования для новых кластеров Заказчиков.

Обычно разработка начинается на кластерах разработки в недрах компании.

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

В противном случае будут наблюдаться как минимум следующие проблемы:

  • будет некорректно работать kube-scheduler (очень сложно выбрать ноду для pod, который неизвестно сколько ресурсов потребует)

  • с учётом того, что на нодах нет swap, а у pod отсутствуют ограничения, то ноды кластера могут просто повисать раньше, чем сработает OOM

Но это я немного отвлёкся.

Когда работа комплекта микросервисов проекта более менее стабилизируется, пройдёт нагрузочное тестирование, оптимизируются resource limits/requests на стадии нагрузочного тестирвоания, limits/requests станут в равными (для продуктива burstable в большинстве случаев не применим), то можно подходить сайзингу серверов.

На просторах интернета я не нашёл более менее готового инструмента, который ответит на простой вопрос - а сколько ядер/памяти потребуется на рабочих нодах?

Вот и пришлось пару часов потренировать клавиатуру.

Скрипт позволяет визуализировать фактические limits, за одно проконтролировать - вдруг где-то не установлены лимиты.

Пример работы скрипта:

Инсталляция и запуск тривиальные:

git clone --recurse-submodules

./kube-limits-cals.sh

Огромное спасибо автору prettytable (https://github.com/jakobwesthoff/prettytable.sh)

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

  1. Скрипт совершенно безопасен. Он в текущем кластерном контексте запускает kubectl get ns/deploy/sts/etc

  2. Для его работы потребуется утилита jq

  3. При запуске ключом --tabbed вместо красивой таблицы выведутся данные с разделителями, которые удобно вставлять в Excel/LibreOffice.

  4. Если коммунити поддержит, то не сложно будет добавить как минимум следующий функционал:

    1. уменьшение количества запусков kubectl (перенести больше логики в части парсинга JSON)

    2. Ключ -n namespace

    3. Указание кластерного контекста

    4. Сделать поддержку kube-state-metrics

    5. Запрашивать исторические данные у Prometheus

Комментарии (10)


  1. saboteur_kiev
    04.08.2022 23:06

    Прежде всего вопрос - а как считалось все что было перед этим? И почему не визуализировать графаной/кибаной? Или не генерировать хотя бы html? их удобнее скроллить, если подов много, плюс легко также копируется в excel с возможностью сортировки. А так получается 2/3 скрипта - импорт из преттитейбл.

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


    P.S. это я придираюсь, но

    куча if

    OP

    Разве не лучше вместо if цикл и case, чтобы можно было и несколько опций обработать, и проще это делать?


    1. korkin25 Автор
      06.08.2022 00:35

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


    1. korkin25 Автор
      06.08.2022 00:40

      лимиты были оттюнены.

      дальше просто. вывод скрипта с ключом --tabbed я складывал в excel с считал требованияк нодам с учетом запаса можностей на каждой ноде, N+1. +мастера, etcd и ресурсы внешних относительно кубера сервисах в наших проектах (minio, bind9, postgres/stolon и т.д. case depends)


  1. alexesDev
    05.08.2022 00:57
    +1

    Я давно в кубе не копался... В метрики лимиты не попадают?

    Помню, что вытаскивал через prometheus стату по ресурсам и прямо в запросе можно было найти поды, которые за месяц не потребляли больше 50-80% памяти и пойти порезать им лимиты. Так точно не получится найти эту инфу?


    1. strangeman
      05.08.2022 09:45

      Попадают, я именно так и сделал у себя.
      sort(max_over_time((sum(rate(container_cpu_usage_seconds_total{namespace="prod",container!="POD",container!="istio-proxy", pod!~".*-job-.*"}[2m])) by (container, namespace) / sum(kube_pod_container_resource_requests_cpu_cores) by (container, namespace)) [30d:5m]) < 0.5) типа такого запрос просто в таблицу в графане вывел и всё.


      1. strangeman
        05.08.2022 09:49

        Также полезно выводить приложения с большим отношением limit к request (больше 40x например), это тоже помогает бороться с неадекватными значениями


        1. korkin25 Автор
          06.08.2022 00:41

          давай добавлю;)


    1. korkin25 Автор
      06.08.2022 00:36

      про лимиты на вскидку не скажу. посмотрю


  1. numbernot
    05.08.2022 09:04
    +3

    Так уже давно есть krew-capacity для этих целей

    https://github.com/robscott/kube-capacity


    1. korkin25 Автор
      06.08.2022 00:42

      Мил человек! где ты раньше был! спасибочки! я этого проекта не видел.