====== Prometheus ======
===== Общая информация =====
Основа мониторинга: 4 золотых сигнала (задержка, трафик, ошибки и насыщение), см. книгу Site reliability engineering (SRE).
- Задержка — время, необходимое для обработки пользовательского запроса. Используется //перцентиль// — значение, ниже которого падает определённый процент наблюдений.
- Трафик - количество HTTP-запросов в секунду к страницам сайта/API/и т. п.
- Ошибка - частота неуспешных запросов (ошибка HTTP 500 и т .п.). Полезно разделять критические ошибки и обычные (429 too many requests).
- Насыщение - интенсивность использования сервиса и запас ресурсов (CPU, memory, disk IO).
===== Архитектура =====
* Сервер Прометея
* Хранилище метрик - TSDB (Time series database, БД временн**ы**х рядов)
* Exporter - источник данных, есть для кучи систем.
* Alertmanager
Сервер работает по модели Pull - сервер сам ищет точки экспортёров (exporter endpoints) для сбора метрик, т. к. работа идёт в очень изменяющихся средах (контейнеры постоянно исчезают и появляются). Сервер опрашивает список целей сам, основываясь на списке агентов-экспортёров в его конфигурации и заданной периодичности их опроса.
Временн**ы**е ряды - значение метрики и метка времени + ярлыки (сервер-источник, имя приложения, окружения и т. д.)
http_requests_total{status_code="200"} 15:00--15:03--15:06----
http_requests_total{status_code="403"} -15:01--15:04--15:07---
http_requests_total{status_code="500"} --15:02--15:05--15:08--
Метрики можно посмотреть на экспортёре с помощью curl или браузером, например, ''curl http://host:9100/metrics''.\\
Формат метрик:
* # HELP - описание
* # TYPE - [[https://prometheus.io/docs/concepts/metric_types/|тип]]
* ''%%имя_метрики{ярлык="значение ярлыка",ярлык="значение ярлыка"} значение_метрики%%''
У одной метрики могут быть разные значения ярлыков, также метрика может быть вообще без ярлыков.
==== Конфиг ====
prometheus.yml
* global - глобальные параметры, также служат значениями по умолчанию для других разделов конфигурации
* scrape_configs - настройки поиска целей мониторинга
global:
scrape_interval: 15s
scrape_configs:
# Значение job_name добавляется ярлыком "job=" ко всем метрикам из этой конфигурации
- job_name: 'just_another_exporter'
metrics_path: '/metrics'
static_configs:
- targets: ['example.com:8080']
В Кубере Прометей обнаруживает экспортеры автоматически. В ''scrape_configs'' надо добавить разделы ''kubernetes_sd_configs'' — что искать и ''relabel_configs'' — как искать.
scrape_configs:
- job_name: kubernetes-pods
# Настройки Service Discovery
kubernetes_sd_configs:
- role: pod # целью (target) будет каждый подходящий Pod
namespaces:
names:
-
# Фильтрация и динамическое назначение ярлыков
relabel_configs:
# Аннотации-фильтры для поиска подов
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_ip, __meta_kubernetes_pod_annotation_prometheus_io_port]
regex: (.+);(.+)
replacement: $1:$2
target_label: __address__
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
regex: (.+)
target_label: __metrics_path__
# Добавление полезных ярлыков временному ряду этого конфига
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- source_labels: [__meta_kubernetes_namespace]
action: replace
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
action: replace
target_label: kubernetes_pod_name
Прометей автоматически добавляет метаярлыки при нахождении целей. Для Кубера эти метаярлыки формируются из пространства имён, аннотаций и ярлыков подов. Получается что-то вроде
__meta_kubernetes_pod_annotation_prometheus_io_scrape
__meta_kubernetes_pod_annotation_prometheus_io_port
__meta_kubernetes_pod_annotation_prometheus_io_path
, поэтому их заменяют на что-то более короткое и удобное, выше ''%%__meta_kubernetes_namespace%%'' заменяется на ''kubernetes_namespace''.
Тут для подов нужно задать аннотации
spec:
template:
metadata:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
, которые преобразуются Прометеем в метаярлыки, что были даны выше. Если в конфигурации ''action: keep'' будет несоответствие регулярке или аннотация будет отсутствовать, то под будет проигнорирован механизмом Service Discovery.
===== Мониторинг Докера =====
sudo nano /etc/docker/daemon.json
# добавить перед последней закрывающей }
# если файла нет, то нужно его создать
{
"metrics-addr" : "0.0.0.0:9323",
"experimental": true
}
# Потом нужно дать права группе docker на этот файл, если он был создан
sudo chown user:docker /etc/docker/daemon.json
# перезапустить Докер
sudo systemctl restart docker
После этого метрики будут доступны по адресу http://docker:9323/metrics
После этого можно ставить самого Прометея
# так в книжке, базовая процедура инсталляции - ссылка ниже.
# здесь переменная указывает на хост, чтобы брать с него метрики
docker run -e DOCKER_HOST=192.168.1.10 -dp 9090:9090 diamol/prometheus:2.13.1
https://prometheus.io/docs/prometheus/latest/installation/#using-docker
===== Мониторинг хоста =====
# На хосте нужно поставить Node exporter
sudo apt install prometheus-node-exporter
# Метрики
http://host:9100/metrics
# prometheus.yml
- job_name: 'host'
static_configs:
- targets: ['172.17.0.1:9100']
https://prometheus.io/docs/guides/node-exporter/\\
https://github.com/prometheus/node_exporter
===== Мониторинг SMART =====
Поставить smartctl-exporter для экспорта метрик. Docker-compose:
smartctl-exporter:
image: prometheuscommunity/smartctl-exporter
container_name: smartctl-exporter
privileged: true
user: root
Внести в prometheus.yml
- job_name: 'smartctl-exporter'
metrics_path: '/metrics'
static_configs:
- targets: ['smartctl-exporter:9633']
https://hub.docker.com/r/prometheuscommunity/smartctl-exporter\\
https://github.com/prometheus-community/smartctl_exporter\\
Метрики начинаются на ''smartctl_''
{__name__=~"smartctl.*"}
===== Мониторинг nginx =====
Для nginx нужно включить там метрики ''stub_status on;''
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /stub_status {
stub_status on;
}
}
Dockerfile
FROM nginx:1.25.0-alpine
COPY default.conf.template /etc/nginx/templates/
Публиковать nginx-prometheus-exporter наружу необязательно, здесь только для примера. Хотя, смотря как расположен Прометей и экспортер.
---
services:
nginx:
build: ./nginx
container_name: nginx
ports:
- 80:80
# source https://prometheus.io/docs/prometheus/latest/installation/
prometheus:
image: prom/prometheus:v2.45.6
container_name: prometheus
user: root
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- ./prometheus/data:/prometheus
ports:
- 9090:9090
# source https://github.com/nginxinc/nginx-prometheus-exporter
nginx-prometheus-exporter:
image: nginx/nginx-prometheus-exporter:1.1.2
container_name: nginx-prometheus-exporter
depends_on:
- prometheus
environment:
- SCRAPE_URI=http://nginx/stub_status
ports:
- 9113:9113
# expose:
# - 9113
# source https://prometheus.io/docs/prometheus/latest/getting_started/
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'nginx-monitor'
scrape_configs:
# The job name is added as a label `job=` to any timeseries scraped from this config.
- job_name: 'nginx'
# Override the global default and scrape targets from this job every 5 seconds.
# scrape_interval: 5s
static_configs:
# prometheus
- targets: ['localhost:9090']
# prometheus-nginx-exporter
- targets: ['nginx-prometheus-exporter:9113']
Как выглядит страница ''%%http:///stub_status%%'' у nginx:
Active connections: 4
server accepts handled requests
26 26 14840
Reading: 0 Writing: 1 Waiting: 3
Страница ''%%http:///metrics%%'' (фрагмент)
# HELP nginx_connections_accepted Accepted client connections
# TYPE nginx_connections_accepted counter
nginx_connections_accepted 26
# HELP nginx_connections_active Active client connections
# TYPE nginx_connections_active gauge
nginx_connections_active 3
# HELP nginx_connections_handled Handled client connections
# TYPE nginx_connections_handled counter
nginx_connections_handled 26
# HELP nginx_connections_reading Connections where NGINX is reading the request header
# TYPE nginx_connections_reading gauge
nginx_connections_reading 0
# HELP nginx_connections_waiting Idle client connections
# TYPE nginx_connections_waiting gauge
nginx_connections_waiting 2
# HELP nginx_connections_writing Connections where NGINX is writing the response back to the client
# TYPE nginx_connections_writing gauge
nginx_connections_writing 1
# HELP nginx_exporter_build_info A metric with a constant '1' value labeled by version, revision, branch, goversion from which nginx_exporter was built, and the goos and goarch for the build.
# TYPE nginx_exporter_build_info gauge
nginx_exporter_build_info{branch="HEAD",goarch="amd64",goos="linux",goversion="go1.22.3",revision="fce2d387946038e4199eab79ad9e7b809abab330",tags="unknown",version="1.1.2"} 1
# HELP nginx_http_requests_total Total http requests
# TYPE nginx_http_requests_total counter
nginx_http_requests_total 14995
# HELP nginx_up Status of the last metric scrape
# TYPE nginx_up gauge
nginx_up 1
Литература:
https://hub.docker.com/r/nginx/nginx-prometheus-exporter\\
https://hub.docker.com/r/prom/prometheus\\
[[https://kamaok.org.ua/?p=3224|Мониторинг Nginx в Prometheus]]\\
===== Howto =====
==== unixtime to datetime ====
Значение * 1000, выставить формат отображения Datetime (Field -> Unit -> Datetime).