Я развертываю Prometheus в своем кластере minikube, который имеет 5 узлов. Я также развертываю микросервис в кластере. Prometheus может нормально собирать данные.
Я использую wrk2, который является генератором рабочей нагрузки для отправки запросов в мои микросервисы. Jaeger показывает, что запросы обрабатываются нормально.
Меня смущает следующее. После того, как я протестирую сервис в течение duration секунд, я попытаюсь использовать sum(irate(container_cpu_usage_seconds_total{{{constraint}}}[{duration}s])) by (container, pod), чтобы получить загрузку процессора модулями. Однако подавляющее большинство модулей не используют ЦП, что означает отсутствие результатов запроса. Меня это очень удивило, потому что за duration секунд я увеличил нагрузку на сервис (т.е. отправил к нему много запросов), но это не увеличило загрузку процессора по сравнению с тем, когда нагрузки не было.
Ниже приведена функция Python, которую я использовал для запроса Prometheus:
# endtime=starttime+duration, starttime is the time when I start wrk2 to generate workload
def get_cpu_usage(self, starttime, endtime, duration, diaplay=False):
# Define Prometheus query to get CPU usage for each service
constraint = f'namespace = "{self.namespace}", container! = "POD", container! = ""'
prometheus_query = (
f"sum(irate(container_cpu_usage_seconds_total{{{constraint}}}[{duration}s])) by (container, pod)"
+ " / " + f"(sum(container_spec_cpu_quota{{{constraint}}}/({duration}*1000)) by (container, pod)) * 100"
)
# Send query to Prometheus endpoint
sleep(1)
response = requests.get(self.prometheus_url + '/api/v1/query_range', params = {
'query': prometheus_query,
'start': starttime,
'end': endtime,
'step': 1
})
# Parse response
usage = response.json()
cpu_result = pd.DataFrame(columns=["microservice", "pod", "usage"])
Есть ли ошибка в коде или в настройках Prometheus?
Кроме того, вы пробовали вручную вводить эти запросы (и их части) в пользовательском интерфейсе Prometheus?
Извините за путаницу, я не получил результатов запроса, поэтому я подумал, что значение равно 0 (что кажется неправильным). Я также попробовал это в веб-интерфейсе и получил тот же результат, что и с моим скриптом Python, только один или два модуля имели значения. Я также попробовал часть запросов, и я могу получить результаты с помощью container_cpu_usage_seconds_total, но это значение остается неизменным для большинства модулей в нагрузочном тесте, что, как я думаю, приводит к тому, что irate не дает результатов. Я не могу понять причину этого.
В случае Прометея 0 и отсутствие результата — это совершенно разные случаи. irate частично может быть причиной неправильного вывода, так как считает скорость между двумя последними выборками. Вместо этого попробуйте rate. Но irate не может быть причиной отсутствия данных.
Пройдитесь по своему выражению шаг за шагом наизнанку и проверьте, на каком шаге вам не хватает данных.
Итак, если я запрошу irate(container_cpu_usage_seconds_total{{constraint}}[{duration}s]), у меня должны быть результаты, даже если они равны нулю? Если container_cpu_usage_seconds_total есть результаты, но нет результатов с irate, значит ли это, что я установил неправильную продолжительность (или шаг) или неправильно использую irate?
Да, вы должны получить 0. Рассмотрим после демонстрации. Возможно, вы установили маленькую продолжительность, например

Я меняю duration на 1m, и это работает хорошо.
Prometheus требует не менее двух необработанных выборок в окне просмотра назад, указанном в квадратных скобках, для вычисления irate(). В противном случае он возвращает пустой результат.
P.S. Рекомендуется использовать rate() вместо irate(), так как irate() не ловит всплески. Подробности смотрите в этой статье.
Что означает «Подавляющее большинство модулей не используют ЦП, что означает отсутствие результатов запроса». иметь в виду? Если метрика имеет значение 0, она все равно вернет результат.