16 KiB
Задания
1. Prometheus
-
Обновите приложение
todo_app
из задания 08 сделавgit pull
веткиmain
.API-сервис приложения теперь отдает метрики Prometheus на порту
9123
(можно поменять через переменную средыMetrics__Port
) и по url/metrics
.Таким образом, полное URL для получения метрик, выглядит, например, как
http://todo_api:9123/metrics
.Дополните Compose-файл для
todo_app
так, чтобы в сетиtodo
запускался контейнер из образаprom/prometheus
, при этом:- Напишите для него конфигурацию, то есть файл
prometheus.yml
(который должен в итоге находится в контейнере на месте/etc/prometheus/prometheus.yml
),
таким образом чтобы Prometheus собирал метрики изtodo_api
каждые 5 секунд. - Прокиньте порт
9090
, на котором находится веб-интерфейс Prometheus по умолчанию, на хост машины с Docker. - Создайте том данных
todo_prometheus_data
, который бы хранил данные внутренней БД Prometheus, и который бы
монтировался на директорию/prometheus
внутри его контейнера.
Убедитесь, что веб-интерфейс Prometheus не был доступен извне. Для доступа к нему, сделайте SSH-туннель на вашу локальную машину.
- Напишите для него конфигурацию, то есть файл
-
Запустите систему в Compose-режиме, то есть не в режиме кластера, и без дополнительных реплик.
-
На веб-интерфейсе Prometheus, проверьте, что он собирает метрики из
todo_api
(на вкладкеTargets
) -
На веб-интерфейсе Prometheus, выведите значение метрики
dotnet_total_memory_bytes
- общее число байт, находящихся в управляемой(т.е. подотчетной сборщику мусора .NET) памяти API-сервиса. -
Выведите максимальное значение этой метрики за последние 15 минут.
-
Дополните compose-файл так, чтобы в сети
todo
запустить контейнер из образаbitnami/postgres-exporter
, при этом:- Установите для этого контейнера переменную среды
DATA_SOURCE_NAME
в значениеpostgresql://todo:todo@todo_postgres:5432/todo?sslmode=disable
(при необходимости поменяйте здесь порт, хост, итд.) - Отредактируйте конфигурацию
prometheus.yml
так, чтобы теперь также собирать метрики изpostgres-exporter
.
Postgres Exporter по умолчанию отдает метрики на порту9187
, и по URL/metrics
- Установите для этого контейнера переменную среды
-
Проверьте на веб-интерфейсе Prometheus метрику
pg_stat_user_tables_size_bytes
(она показывает количество памяти, занимаемой пользовательскими таблицами в PostgreSQL) -
Дополните compose-файл так, чтобы также запускать контейнер из образа
prom/node-exporter
.
Учтите, что так как этот exporter используется для мониторинга хост-машин, ему не нужна такая изоляция, как обычным приложениям, и даже наоборот:- Для этого контейнера необходимо примонтировать корневую директорию хост-машины в read-only режиме,
чтобы она была доступна например как директория/host
внутри контейнера. - При старте этого контейнера, передайте ему аргумент
--path.rootfs=/host
- Также, установите значение
--pid
вhost
(pid: host
в compose-файле) - Желательно также установить режим сети в
host
(network_mode: host
в compose-файле) (N.B.: Работает только на Linux, и не работает на Docker Desktop на macOS и Windows)
node-exporter по умолчанию отдает метрики на порту
9100
и по URL/metrics
.
Доступ кhost
-машине Docker изнутри контейнера Prometheus можно получить по адресу (host.docker.internal
)Дополните конфигурацию
prometheus.yml
так чтобы собирать метрики и изnode-exporter
- Для этого контейнера необходимо примонтировать корневую директорию хост-машины в read-only режиме,
-
Проверьте на веб-интерфейсе Prometheus метрику
node_memory_MemFree_bytes
- она показывает количество свободной оперативной памяти хост-машины(и берет ее из/proc/meminfo
).
1.1 PromQL
-
При выборке данных в PromQL, значение метрик можно фильтровать по меткам.
Например,
process_cpu_seconds_total{job="todo_api"}
- здесь метрики будут отфильтрованы по имени службы(job),
указанной в конфигурации Prometheus.На веб-интерфейсе Prometheus, выведите сначала все временные ряды, связаннные с этой метрикой, а потом только для API-сервиса.
-
Записывая метрику в запросе как
process_cpu_seconds_total
- мы получаем так называемыйinstant vector
. Это значение временного ряда(или рядов) за все время.Если же мы запишем метрику как
process_cpu_seconds_total[5m]
- мы получимrange vector
, то есть значения за определенный период времени.
Значения по диапазону нельзя напрямую вывести на экран того же веб-интерфейса Prometheus, но можно применить к нему какую-либо функцию.Одна из наиболее часто используемых функций, особенно с метриками типа
Counter
- это функцияrate
.
Она выводит среднее посекундное изменение значения какой-либо метрики, за определенное время, и получает на вход как разrange vector
.
Пример необходиомости ее использования: метрикаprocess_cpu_seconds_total
, которая сама по себе, говорит нам не очень о многом,
это всего лишь счетчик секунд процессорного времени, занимаемого процессом; зато вот скорость изменения этой метрики
за какое-то время - может нам показать нагрузку сервисов за это время.Выведите на веб-интерфейс Prometheus степень изменения метрики
process_cpu_seconds_total
за последние 5 минут. -
Метрики типа
Gauge
- самые простые метрики, они показывают текущее значение какого-либо параметра.node_memory_MemFree_bytes
- как раз метрика такого типа, показывает свободную память в операционной системе.
Если взять от нее значения по диапазону(range vector
), то к ним можно применить какие-либо функции PromQL, работающие с диапазонами.Используя функцию
avg_over_time
- выведите среднее значение этой метрики за последние 5 минут. -
API-сервис отдает метрику
http_request_duration_seconds
. Она собирает время обработки HTTP-запроса API-сервисом в секундах.http_request_duration_seconds_bucket
- значения метрики в виде гистограммы.
http_request_duration_seconds_sum
иhttp_request_duration_seconds_count
- части этой метрики, отдающие, соответственно сумму времени всех запросов, и общее количество запросов. Эти части - сами по себе метрики типаCounter
.Выведите среднее время обработки запроса за все время(подсказка: сумма времени деленное на количество запросов), так и за последние 5 минут(подсказка: примените функцию rate к диапазону значений за 5 минут).
-
Как видно, на веб-интерфейс Prometheus выводится несколько значений, сгруппированные по меткам, отображающим в частности URL метода API-сервиса.
Для того чтобы слить все эти значения в одно, вы можете применить к нему функции аггрегации из PromQL, такие как
sum()
. Функции аггрегации чем-то напоминают аггрегацию поgroup by
из SQL, и к ним тоже можно добавлять суффиксby
. Так, например, можно сгруппировать значенияhttp_request_duration_seconds_sum
или_count
по имени метода API-сервиса, обрабатывающего запрос(меткаaction
).Выведите среднее время обработки запроса за последние 5 минут, которое бы включало все метки без исключения.
-
http_request_duration_seconds_bucket
- непосредственно значения гистограммы времени HTTP-запросов, сгруппированное по диапазонам отражающим количество секунд, которое заняла обработка конкретного запроса.Так как значения гистограммы - это счетчики, то к ним также можно применять функции
rate
иsum
.
Если мы аггрегируем эту метрику с помощью суммы по меткеle
(собственно значения той оси гистограммы, которые показывают время обработки запроса),
то к полученному результату мы можем применить функции PromQL, работающие с гистограммами, напримерhistogram_quantile
.Функция
histogram_quantile
поможет посчитать время обработки запроса по заданному квантилю. Так, если первым параметром ей передать число 0.5,
то мы можем оценить примерное медианное время обработки запроса(половина запросов отрабатывает быстрее, половина медленнее).Выведите медианное время обработки запроса за последние 5 минут.
2. Grafana
-
Дополните compose-файл так, чтобы в сети
todo
запустить контейнер из образаgrafana/grafana
. \- Интерфейс grafana по умолчанию доступен на порту 3000, пробростье этот порт на хост машину.
- Также, создайте том данных
todo_grafana_data
, примонтированный в контейнер по пути/var/lib/grafana
- Установите для контейнера переменную окружения
GF_USERS_ALLOW_SIGN_UP
в значениеfalse
, чтобы отключить возможность регистрации пользователей.
-
Перезапустите систему. Убедитесь что
grafana
доступна извне. Для этого настройте конфигурациюnginx
на хост-системе, если вы используете его в качестве внешнего прокси. -
Зайдите на веб-интерфейс grafana. Логин и пароль по умолчанию -
admin
admin
(пароль можно поменять установив переменную окруженияGF_SECURITY_ADMIN_PASSWORD
).
Поменяйте пароль на свой, если вы не установили его как переменную среды. -
Добавьте пользователя с именем
viewer
, и разрешением на просмотр визуализаций(рольViewer
). -
Добавьте источник данных
Prometheus
, при этом установите его URL вhttp://todo_prometheus:9090
(поменяйте хост на имя контейнера, в котором запускается Prometheus) -
Создайте новый Dashboard, и добавьте на него новую визуализацию метрики
dotnet_total_memory_bytes
.- Выберите тип графика как
Time Series
- Назовите график с визуализацией
.NET Total Memory Bytes
- Поставьте единицу измерения
bytes(SI)
- Установите display name для выводимого поля, например в
.NET memory
- Сделайте так, чтобы на график выводилось значение за последние 5 минут.
- Добавьте вывод порогового значения(
threshold
) в 10 мегабайт, так чтобы график выше этого значения был закрашен желтым.
- Выберите тип графика как
-
Сохраните Dashboard под именем
My Dashboard
. Установите график обновления в 5 секунд. -
Добавьте визуализацию свободной памяти на хост-машине. Сделайте так чтобы визуализация показывала минимальное за последние 5 минут значение,
а сам график выводил показывал отрезок времени в последний час. Сохраните визуализацию и Dashboard. -
Добавьте визуализацию среднего времени обработки HTTP-запросов API-сервером за последние 5 минут. Сохраните Dashboard.
-
Перезапустите всю систему, но уже не в Docker Compose, а в Docker Swarm. Сделайте так, чтобы API-сервис работал на трех репликах.
Убедитесь, что Prometheus правильно собирает метрики со всех трех реплик одновременно(в Targets на интерфейсе Prometheus должны присутствовать все три).
Отредактируйте визуализации, связанные с API-сервисом так, чтобы они показывали средние значения по всем трем репликам.