[DevOps, Kubernetes] Рациональное использование ресурсов в Kubernetes (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 2 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
03-Июн-2021 16:38

Одна из важных задач при работе с Kubernetes — рациональное распределение ресурсов. Для этого необходимо правильно назначать контейнерам лимиты (limits) и запросы (requests). Но это не всегда простая задача!Может возникнуть ситуация, когда вы зарезервировали намного больше ресурсов, чем необходимо приложению, потому что хотите избежать проблем, связанных с недостаткам памяти в контейнерах, или возникновения троттлинга ЦП при запуске приложения. В таком случае вам придётся оплачивать неиспользуемые ресурсы. Учтите, что планировщику Kubernetes будет сложнее найти подходящий узел для таких рабочих нагрузок.
Примечание переводчикаЕсли при написании манифеста в шаблоне контейнера вы указываете request, то при планировании пода на узел запрашиваемые ресурсы резервируется за ним и уже не могут использоваться другими подами.
Эта статья поможет разобраться, как быстро находить неиспользуемые ресурсы с помощью PromQL.Не будьте жадным разработчикомПредположим, что вы зарезервировали для контейнера больше ресурсов, чем требуется. Если речь идёт лишь об одном контейнере, то это не должно сильно увеличить ваши расходы. Но если речь идёт о всех запущенных контейнерах, тогда счет за услуги облачного провайдера может существенно возрасти.К тому же, если контейнеры в подах запрашивают слишком много ресурсов, возможны проблемы с планированием таких подов на узлы кластера в соответствии с вашими приоритетами. Вам придётся потратить дополнительные усилия на отладку и решение проблем с планированием таких подов.Нам потребуется собирать метрики производительности, для этого подойдут два open-source решения:
  • kube-state-metrics: Дополнительный агент, который создаёт базовые метрики для всего кластера и предоставляет к ним доступ.
  • CAdvisor: Анализатор использования контейнерами ресурсов.

Как обнаружить неиспользуемые ресурсы?ПроцессорЕсли вы запросите слишком мало ресурсов ЦП, то можете столкнуться с троттлингом. С другой стороны, попытка решить эту проблему, указав в запросе слишком много ядер, в итоге приведёт к простаиванию ресурсов. Попробуем решить эту проблему.
Обнаружение простаивающих ядер ЦПС помощью Prometheus метрикcontainer_cpu_usage_seconds_total и kube_pod_container_resource_requests вы сможете легко определить количество простаивающих ядер:
sum((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0)

По графику видно, что более 7 ядер простаивают в течение длительного времени.Как определить, какой namespace потребляет наибольший объём ресурсов?Суммируя предыдущий запрос PromQL по namespace, вы можете получить более детальную картину. Теперь вы знаете, какой отдел злоупотребляет резервированием ресурсов:
sum by (namespace)((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0)

Топ-10 контейнеров с избыточным CPU RequestВ руководстве по началу работы с PromQL мы уже рассказывали про функцию topk которая возвращает первые n результатов вашего запроса. Например:
topk(10,sum by (namespace,pod,container)((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0))

ПамятьПравильное резервирование памяти не менее важная задача. Если при запуске приложения ему не хватит памяти, контейнер будет перезагружен. Также учтите, что узел начнёт вытеснять поды, когда ему перестанет хватать памяти, поэтому важно запрашивать оптимальный объем ресурсов, чтобы развернуть больше подов.
Обнаружение неиспользуемой контейнерами памятиВоспользуемся результатами запросов container_memory_usage_bytes и kube_pod_container_resource_requests, чтобы определить объём зарезервированной, но не утилизированной памяти:
sum((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="memory"})) * -1 >0 ) / (1024*1024*1024)

В приведённом выше примере виден объём неиспользуемой оперативной памяти.Определим, какие namespace самые расточительныеАгрегируем результаты предыдущего запроса по namespace так же, как мы это делали для ЦП:
sum by (namespace)((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="memory"})) * -1 >0 ) / (1024*1024*1024)

Найдём контейнеры с избыточным Memory RequestИспользуем уже знакомую нам функцию topk, чтобы определить 10 самых расточительных контейнеров:
topk(10,sum by (namespace,pod,container)((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="memory"})) * -1 >0 ) / (1024*1024*1024))

Как оптимизировать зарезервированные ресурсы?
Чтобы правильно рассчитать ресурсы, необходимые вашему кластеру Kubernetes, нужно проанализировать текущее использование ресурсов вашими контейнерами. Для этого воспользуйтесь запросом PromQL, который вычисляет среднюю загрузку ЦП для всех контейнеров, относящихся к одному и тому же объекту - DeploymentStatefulSet или DaemonSet.
avg by (namespace,owner_name,container)((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[5m])) * on(namespace,pod) group_left(owner_name) avg by (namespace,pod,owner_name)(kube_pod_owner{owner_kind=~"DaemonSet|StatefulSet|Deployment"}))

На графике вы можете увидеть среднюю загрузку ЦП для каждого контейнера. Как правило, стоит запрашивать от 85% до 115% среднего использования ЦП или памяти.Как измерить результаты после оптимизации параметров
После оптимизации резервирования ресурсов необходимо проверить, как изменения повлияли на вашу инфраструктуру. Для этого вы можете сравнить текущие значения со значениями за прошлую неделю:
sum((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0) - sum((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m] offset 1w) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"} offset 1w )) * -1 >0)

На приведенном выше графике вы можете увидеть, что после применения предыдущих оптимизаций в нашем кластере осталось меньше неиспользуемых ядер.ЗаключениеТеперь вам известны последствия проблемы "жадного разработчика" и способы обнаружения чрезмерного резервирования ресурсов платформы. Кроме того, вы узнали, как правильно настроить запросы ваших контейнеров и как измерить влияние ваших оптимизаций.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Jesus Ángel Samitier
===========
Похожие новости: Теги для поиска: #_devops, #_kubernetes, #_kubernetes, #_devops, #_docker, #_sistemnoe_administrirovanie (системное администрирование), #_prometheus, #_promql, #_monitoring, #_monitoring (мониторинг), #_proizvoditelnost (производительность), #_resursy (ресурсы), #_blog_kompanii_timeweb (
Блог компании Timeweb
)
, #_devops, #_kubernetes
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 30-Апр 00:14
Часовой пояс: UTC + 5