Три распространенных ошибки с метриками Kubernetes в PromQL

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Миллионы разработчиков пишут запросы PromQL и создают пользовательские дашборды Grafana для Kubernetes. И все используют одинаковые метрики из node-exporter, kubelet и kube-state-metrics. К сожалению, не все знают, как при работе с метриками обойти некоторые подводные камни.‍

Команда VK Cloud перевела статью, в которой автор разбирает ошибки в одном простом с виду запросе Prometheus для Kubernetes. Он должен возвращать сведения об использовании памяти пода:

container_memory_working_set_bytes{pod="agency-dashboard-api-89b7f557c-xd4l7"}

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

Ошибка №1: повторяющиеся временные ряды

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

Вместо этого я получаю два результата (я отредактировал несколько меток с конфиденциальными данными или поменял их значения):

container_memory_working_set_bytes{__replica__="replica-0", cluster="dev-cluster", container="agency-dashboard-api", endpoint="https-metrics", id="/kubepods/burstable/pod66a2c312-6066-42e9-99f8-6e045b863e9d/d24d2a7b79f4fac2f51ab2d9126b9be9a58bd122b18c6928faac463882df7ef0", instance="10.128.0.79:10250", job="cadvisor", metrics_path="/metrics/cadvisor", name="d24d2a7b79f4fac2f51ab2d9126b9be9a58bd122b18c6928faac463882df7ef0", namespace="default", node="gke-dev-cluster-lg-workloads-addf1-44", pod="agency-dashboard-api-89b7f557c-xd4l7", project="dev-k8s", service="kubelet"}

container_memory_working_set_bytes{__replica__="replica-0", cluster="dev-cluster", endpoint="https-metrics", id="/kubepods/burstable/pod66a2c312-6066-42e9-99f8-6e045b863e9d/d24d2a7b79f4fac2f51ab2d9126b9be9a58bd122b18c6928faac463882df7ef0", instance="10.128.0.79:10250", job="cadvisor", metrics_path="/metrics/cadvisor", name="d24d2a7b79f4fac2f51ab2d9126b9be9a58bd122b18c6928faac463882df7ef0", namespace="default", node="gke-dev-cluster-lg-workloads-addf1-44", pod="agency-dashboard-api-89b7f557c-xd4l7", project="dev-k8s", service="kubelet"}

Изначально я подозревал, что проблема в настройках мониторинга: может быть, несколько заданий извлекают одни и те же данные. Чтобы правильно построить графики, в Prometheus нужно использовать верные метки в запросе. (Prometheus добавляет в запрос несколько меток, в частности job и instance.) Я решил выяснить: может быть, одни и те же данные извлекают несколько заданий или выдают разные инстансы. Ведь если одинаковые данные поступают из разных мест, запрос выдает непонятные или неверные результаты. (Подробнее об этом в видео на YouTube об ошибках мониторинга в Prometheus.)

Я добавил метку задания:

container_memory_working_set_bytes{pod="agency-dashboard-api-89b7f557c-xd4l7", job="kubelet"}

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

Проблема №2: Ошибки группирования/суммирования

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

sum(container_memory_working_set_bytes{pod=”my-pod-123”, job=”kubelet”}) by (pod) / 2

Но когда я перепроверил результаты этого запроса по данным у себя в консоли GKE, выяснилось, что запрос выдавал результаты, разнящиеся по времени. Это отчасти объяснялось тем, как метрики рассчитываются в GKE: GKE учитывает только Non-evictable memory.

Какой урок из этого можно извлечь? Не надо делать дедупликацию метрик, выводя их среднеарифметическое — по крайней мере, пока вы не разберетесь в подробностях, как они рассчитываются и почему вообще появились дубликаты.

Проблема №3: неожиданное количество элементов множества

Давайте вернемся к нашим дублированным временным рядам и рассмотрим их подробнее. Чем один временной ряд отличается от другого?

Ответ нам подскажет метка container. Эта метка есть у одного временного ряда и отсутствует у другого.

Чтобы понять почему, нужно пойти в обход и выяснить, что такое контейнер pause. Из документации Kubernetes:

«В поде Kubernetes для размещения контейнера сначала создается так называемый инфраструктурный, или Pause-контейнер. В Linux для поддержания существования cgroups и пространств имен, входящих в под, нужен процесс — он называется Pause-процесс. У контейнеров, относящихся к одному поду, включая инфраструктурные и рабочие контейнеры, общая конечная точка сети (один и тот же IPv4 и/или Ipv6-адрес, одни и те же пространства сетевого порта). В Kubernetes Pause-контейнеры нужны, чтобы при сбое и перезапуске рабочих контейнеров сохранялись их сетевые настройки».

Когда создается под в Kubernetes, число контейнеров, созданных на ноде, всегда больше, чем число подов, указанных в манифесте пода. Чтобы это проверить, выполните SSH на ноде и запустите docker ps. У Pause-контейнера имеются все сетевые настройки пода. При удалении Pause-контейнера удаляется также и контейнер приложения, а под перезапускается.

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

После этого я подправил запрос и наконец получил верные метрики.

container_memory_working_set_bytes{pod=”agency-dashboard-api-89b7f557c-xd4l7”, job=”kubelet”, container!=”}

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

Заключение

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

Присоединяйтесь к телеграм-каналу «Вокруг Kubernetes», чтобы быть в курсе новостей из мира K8s!

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

Источник: https://habr.com/ru/companies/vk/articles/849606/


Интересные статьи

Интересные статьи

Приветствую всех неравнодушных!Хочу поделиться с вами историей о том, как мы рефакторили код проекта на Битрикс под DDD архитектуру. Возможно кому-то это будет полезно, а возможно, и сам подчерпну что...
Приветствую всех на Хабре. Я Сергей Михнов, CEO компании Пуск, интегратора Битрикс24. В свое время мы выбрали особый путь – специализацию на коробочной версии Битрикс24. В коммуникациях на сайте или п...
Во многих компаниях задумываются о внедрении больших больших языковых моделей для векторизации и в качестве классификатора. Однако здесь есть несколько моментов, которые обычно отпугивают. Во-первых, ...
Предлагаю ознакомиться с ранее размещенными материалами по проекту Starlink (SL): ‣ Часть 20. Внутреннее устройство терминала SL ‣ Часть 21. SL и проблемы поляризаци ‣ Часть 22. Пробл...
Здравствуйте. Я уже давно не пишу на php, но то и дело натыкаюсь на интернет-магазины на системе управления сайтами Битрикс. И я вспоминаю о своих исследованиях. Битрикс не любят примерно так,...