Инструменты Prometheus#
Prometheus#
Prometheus - это инструмент для мониторинга и оповещения систем. Prometheus собирает и хранит свои метрики в виде данных временных рядов, то есть информация о метриках хранится с меткой времени, на которой она была записана, наряду с необязательными парами ключ-значение, называемыми метками.
Общий принцип работы Prometheus:
Prometheus читает секцию конфигурационного файла
scrape_configs, согласно которой настраивает свой внутренний механизмService Discovery(обнаружения сервисов).Для каждой
target(цели мониторинга), каждыйscrape_interval(частота опрашивания цели мониторинга), выполняется HTTP-запрос к этой цели. В ответ получаются метрики в своем формате, которые сохраняются в базу.Каждый
evaluation_interval(оценка запроса для оповещения) обрабатываются правила, на основании которых:или отправляются alerts (оповещения);
или записываются новые метрики (результат выполнения правила).
Механизм
Service Discoveryвзаимодействует с DropApp API (в основном для получения endpoints).Механизм
Service Discoveryобновляетtargets(список целей).
Prometheus-operator автоматически обнаруживает изменения на сервере API DropApp в любом из вышеперечисленных объектов и обеспечивает синхронизацию сопоставления развертываний и конфигураций.
Prometheus хранит все данные в виде временных рядов: потоки значений с временными метками, принадлежащих одной и той же метрике, и один и тот же набор помеченных измерений. Помимо сохраненных временных рядов, Prometheus может генерировать временные производные рядов в результате запросов.
Имя метрики указывает на основной измеряемый показатель системы. Например, http_requests_total - итоговое число полученных запросов HTTP.
Имя метрики может содержать символы ASCII, цифры, подчеркивания и двоеточия. Проверку имени метрики можно выполнить с помощью регулярного выражения [a-zA-Z_:][a-zA-Z0-9_:]*.
Примечание
Двоеточие зарезервировано для пользовательских правил записи. Они не должны использоваться экспортерами или другими инструментами.
Метки позволяют использовать размерную модель данных Prometheus: любая заданная комбинация меток для одного и того же имени метрики идентифицирует конкретный размерный экземпляр этой метрики.
Например: все HTTP-запросы, в которых использовался метод POST, отправляются в обработчик /api/tracks. Язык запросов позволяет выполнять фильтрацию и агрегирование на основе этих измерений. Изменение любого значения метки, включая добавление или удаление метки, создаст новый временной ряд.
Имя метки может содержать символы ASCII, цифры и подчеркивания. Имена меток с двойным подчеркиванием (_name_) зарезервированы для внутреннего использования. Проверку имени метки можно выполнить с помощью регулярного выражения [a-zA-Z_][a-zA-Z0-9_]*. Значения меток могут содержать любые символы Unicode. Метка с пустым значением считается эквивалентной несуществующей метке.
Prometheus очищает метрики либо напрямую, либо через промежуточный шлюз для кратковременных заданий. Prometheus хранит все очищенные образцы локально и запускает правила над этими данными, чтобы либо агрегировать и записывать новые временные ряды из существующих данных, либо генерировать оповещения. Также возможно использование других совместимых инструментов сбора и визуализации данных.
Конфигурация Prometheus#
У сервера Prometheus есть config (конфигурационный файл) и rule files (файлы с правилами).
В config имеются следующие секции:
scrape_configs— настройки поиска целей для мониторинга;rule_files— список директорий с правилами, которые необходимо загрузить;alerting— настройки поиска Prometheus-alertmanager, в которые отправляются alerts (оповещения). Результатом работы является списокendpoints, в которые Prometheus будет отправлять предупреждения.
Пример scrape_configs:
scrape_configs.yaml
scrape_configs:
# Общие настройки
- job_name: kube-prometheus/custom/0 # Название scrape job
# Показывается в разделе Service Discovery
scrape_interval: 30s # Частота сбора данных в секундах
scrape_timeout: 10s # Таймаут в секундах на запрос
metrics_path: /metrics # Путь к метрикам
scheme: http # Выбор типа соединения, доступные значения `http` или `https`
# Настройки Service Discovery
kubernetes_sd_configs:
- api_server: null # Использовать адрес API-сервера из переменных
# Окружение (которые есть в каждом pod)
role: endpoints # Источник targets (endpoints)
namespaces:
names: # Поиск endpoints в указанных namespaces
- alice
- bob
# Настройки фильтрации enpoints и relabel
# Перечень меток для всех получаемых метрик
relabel_configs:
# Фильтр по значению метки prometheus_custom_target,
# полученного из service, связанного с endpoint
- source_labels: [__meta_kubernetes_service_label_prometheus_custom_target]
regex: .+ # Может использоваться любая не пустая метка
action: keep
# Фильтр по имени порта
- source_labels: [__meta_kubernetes_endpoint_port_name]
regex: http-metrics # Для имени порта http-metrics
action: keep
- source_labels: [__meta_kubernetes_service_label_prometheus_custom_target]
regex: (.*)
target_label: job
replacement: custom-$1
action: replace
# Метка namespace
- source_labels: [__meta_kubernetes_namespace]
regex: (.*)
target_label: namespace
replacement: $1
action: replace
# Метка service
- source_labels: [__meta_kubernetes_service_name]
regex: (.*)
target_label: service
replacement: $1
action: replace
# Метка instance (имя pod)
- source_labels: [__meta_kubernetes_pod_name]
regex: (.*)
target_label: instance
replacement: $1
action: replace
Метка job, используемое значение метки prometheus_custom_target в случае service, добавляется префикс custom.
Метка job — служебная в Prometheus. Определяет название группы, в которой будет показываться target на странице targets, а также она будет у каждой метрики, полученной у этих targets (для последующей фильтрации rules и dashboards)
Пример rule_files:
rule_files:
- /etc/prometheus/rules/rules-0/*
- /etc/prometheus/rules/rules-1/*
Prometheus отслеживает:
добавление и удаление pods (при добавлении/удалении pods DropApp изменяет
endpoints, в таком случае Prometheus добавляет/удаляет цели);добавление и удаление
endpointsв указанных namespaces.
Изменение конфигурационного файла требуется в следующих случаях:
добавление нового
scrape_config;изменение списка namespaces.
Prometheus-operator#
Prometheus-operator обеспечивает встроенное развертывание и управление Prometheus и связанными с ним компонентами мониторинга. Это сделано для упрощения и автоматизации настройки стека мониторинга на основе Prometheus для кластеров DropApp.
Основной особенностью Prometheus-operator является мониторинг сервера API DropApp на предмет изменений в объектах и обеспечение того, чтобы текущие развертывания Prometheus соответствовали этим объектам.
Prometheus-operator действует в соответствии со следующими определениями пользовательских ресурсов (CRD или Custom Resource Definitions):
Prometheus — определяет желаемое развертывание кластера Prometheus;
PrometheusAgent — определяет желаемое развертывание Prometheus, но работает в режиме агента;
Prometheus-alertmanager — определяет желаемое развертывание Prometheus-alertmanager;
ThanosRuler — определяет желаемое развертывание ThanosRuler;
ServiceMonitor — декларативно определяет, как следует контролировать группы сервисов DropApp. Оператор автоматически генерирует конфигурацию очистки Prometheus на основе текущего состояния объектов на сервере API;
PodMonitor — декларативно определяет, как следует контролировать группу pods. Автоматически генерирует конфигурацию очистки Prometheus на основе текущего состояния объектов на сервере API;
Probe — декларативно определяет группы входов или статических целей. Оператор автоматически генерирует конфигурацию Prometheus на основе определения;
ScrapeConfig — декларативно определяет конфигурации очистки, которые должны быть добавлены в Prometheus. Это
CustomResourceDefinitionпомогает очищать ресурсы за пределами кластера DropApp;PrometheusRule — определяет желаемый набор правил оповещений и/или записей Prometheus. Оператор генерирует файл правил, который может использоваться экземплярами Prometheus;
AlertmanagerConfig — декларативно определяет подразделы конфигурации Prometheus-alertmanager, позволяя маршрутизировать оповещения и устанавливать правила inhibit.
Prometheus-operator отслеживает ресурсы Prometheus и генерирует для каждого из них:
StatefulSet (с самим Prometheus);
Secret с
prometheus.yaml(конфигурационный файл Prometheus) иconfigmaps.json(конфигурационный файл для Prometheus-config-reloader).
Оператор также следит за ресурсами ServiceMonitor и за ConfigMaps с правилами, и на их основании обновляет конфиги prometheus.yaml и configmaps.json (они хранятся в secret).
Развертывание Prometheus-operator#
Для выполнения данного сценария необходимы права администратора.
Развертывание#
Первым шагом является установка пользовательских определений ресурсов оператора (CRD), а также самого оператора с необходимыми ресурсами RBAC.
Выполните следующие команды для установки CRD и развертывания оператора в namespace по умолчанию:
LATEST=$(curl -s https://<repoexample.ru>/repos/prometheus-operator/prometheus-operator/releases/latest | jq -cr .tag_name) curl -sL https://<repoexample.ru>/prometheus-operator/prometheus-operator/releases/download/${LATEST}/bundle.yaml | kubectl create -f - # Укажите актуальный путь до локального репозиторияДля запуска оператора может потребоваться несколько минут.
Проверьте результат, введите команду:
kubectl wait --for=condition=Ready pods -l app.kubernetes.io/name=prometheus-operator -n defaultВведите пользовательские ресурсы в DropApp:
apiVersion: apps/v1 kind: Deployment metadata: name: example-app spec: replicas: 3 selector: matchLabels: app: example-app template: metadata: labels: app: example-app spec: containers: - name: example-app image: fabxc/instrumented_app ports: - name: web containerPort: 8080В примере развертывания приложение с 3 копиями, которое прослушивает Prometheus и предоставляет метрики на порту
8080.Предоставьте объект Service:
kind: Service apiVersion: v1 metadata: name: example-app labels: app: example-app spec: selector: app: example-app ports: - name: web port: 8080Service выбирает все pod с меткой
app, имеющей значениеexample-app. Объект Service также указывает порт, на котором отображаются метрики.Создайте объект ServiceMonitor:
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: example-app labels: team: frontend spec: selector: matchLabels: app: example-app endpoints: - port: webServiceMonitor выбирает все объекты Service с меткой
app: example-app. Также объект ServiceMonitor присвоена меткаteam: frontendдля назначения команды, ответственной за наблюдение за приложением/сервисом.
Сценарий развертывания Prometheus#
Предварительные условия развертывания:
созданы правила RBAC для учетной записи службы Prometheus;
развернут Prometeus-operator.
Развертывание Prometeus#
Развертывание Prometeus:
Примените следующие манифесты для создания учетной записи службы и связки
ClusterRole/ClusterRoleBinding:apiVersion: v1 kind: ServiceAccount metadata: name: prometheusВыше приведен фрагмент кода, который описывает создание ServiceAccount в DropApp, где:
apiVersionуказывает версию API DropApp, к которой принадлежит этот объект. В данном случае это версия v1;kindопределяет тип объекта. В данном случае ServiceAccount;metadataсодержит информацию о ServiceAccount, такую как имя, которое может быть использовано для идентификации ServiceAccount.
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: [""] resources: - nodes - nodes/metrics - services - endpoints - pods verbs: ["get", "list", "watch"] - apiGroups: [""] resources: - configmaps verbs: ["get"] - apiGroups: - networking.k8s.io resources: - ingresses verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"]Выше приведено описание объекта ClusterRole в DropApp, который предоставляет разрешения для работы с ресурсами в кластере, где:
apiVersionопределяет версию API, к которой относится объект. В данном случае, это версия v1 для API группыrbac.authorization.k8s.io;kindопределяет тип объекта, в данном случаеClusterRole;metadataсодержит информацию об объекте, такую как его имя (name), которое может использоваться для его идентификации. Также здесь указаны правила, которые определяют, какие ресурсы и операции могут быть выполнены с ними;rulesопределяет правила доступа к ресурсам. В данном примере, правила доступа включают получение списка, чтение и наблюдение за следующими ресурсами:nodes,nodes/metrics,services,endpoints,podsиconfigmaps. Также здесь указаны правила доступа к ресурсам из группыnetworking.k8s.io, включаяingresses;nonResourceURLsопределяет список URL-адресов, к которым можно получить доступ без указания ресурсов. В данном случае указан только один URL-адрес -/metrics;verbsопределяет список операций, которые могут быть выполнены над ресурсами. В данном случае указаны операцииget,listиwatch.
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: defaultПользовательский ресурс Prometheus определяет характеристики StatefulSet (количество копий, запросы/ограничения ресурсов и т.д.), а также то, какие ServiceMonitors должны быть включены в поле
spec.serviceMonitorSelector.Добавьте возможность ввода новых сервисных мониторов без необходимости перенастройки Prometheus, примените манифест:
apiVersion: monitoring.operationsistem.com/v1 kind: Prometheus metadata: name: prometheus spec: serviceAccountName: prometheus serviceMonitorSelector: matchLabels: team: frontend resources: requests: memory: 400Mi enableAdminAPI: falseВ сценарии развертывания Prometheus-operator (представлен выше) создается объект
ServiceMonitorс меткойteam: frontend. Манифест определяет, что объект Prometheus должен выбирать всеServiceMonitorsс меткойteam: frontend.Убедитесь, что экземпляр был запущен, введите команду:
kubectl get -n default prometheus prometheus -wПо умолчанию Prometheus запустит
ServiceMonitorsиз текущего namespace. Чтоб выбратьServiceMonitorsиз другого namespace, обновите полеspec.serviceMonitorNamespaceSelectorв Prometheus.
Сценарий использования PodMonitors#
Для использования PodMonitors выполните шаги:
Используйте PodMonitor в качестве альтернативы ServiceMonitor без необходимости создания сервиса DropApp:
apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: example-app labels: team: frontend spec: selector: matchLabels: app: example-app podMetricsEndpoints: - port: webМетка
spec.selectorуказывает Prometheus, какие pods следует очистить.Определите выбор PodMonitors с помощью поля
thespecspec.podMonitorSelector:apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus spec: serviceAccountName: prometheus podMonitorSelector: matchLabels: team: frontend resources: requests: memory: 400Mi enableAdminAPI: false
Сценарий предоставления Prometheus service#
Чтобы получить доступ к интерфейсу Prometheus, сервис необходимо предоставить другим приложениям.
Определите службу
NodePort:apiVersion: v1 kind: Service metadata: name: prometheus spec: type: NodePort ports: - name: web nodePort: 30900 port: 9090 protocol: TCP targetPort: web selector: prometheus: prometheusПосле создания
Serviceвеб-сервер Prometheus доступен по IP-адресу node на порту30900.
Сценарий развертывания Kube Prometheus#
Инструмент kubeadm позволяет развертывать и управлять кластерами DropApp, а также автоматически настраивать кластер с некоторыми базовыми опциями.
В разделе приведены сценарии развертывания Prometheus, Prometheus-operator и Kube Prometheus, для мониторинга кластера, который был развернут с помощью kubeadm.
По умолчанию kubeadm не предоставляет доступ к сервисам. Исправить это можно путем внесения изменений в кластер DropApp.
Предоставьте доступ к кластеру
kube-controller-managerиkube-scheduler:apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration controlPlaneEndpoint: "<IP-address>:0001" api-server: extraArgs: authorization-mode: "Node,RBAC" controllerManager: extraArgs: bind-address: "0.0.0.0" scheduler: extraArgs: bind-address: "0.0.0.0" certificatesDir: "/etc/kubernetes/pki" etcd: # Локальный или внешний local: dataDir: "/var/lib/etcd" kubernetesVersion: "v1.23.0" networking: dnsDomain: "cluster.local" serviceSubnet: "<IP-address>/10" imageRepository: "registry.k8s.io"По умолчанию kubeadm запускает pods на устройстве на
127.0.0.1.В строках
scheduler.extraArgsиcontrollerManager.extraArgsпредоставляется доступ к службам kube-controller-manager и kube-scheduler для остальной части кластера.Убедитесь, что значения
spec.selectorслужб kube-prometheus-exporter-kube-scheduler и kube-prometheus-exporter-kube-controller-manager совпадают со значениями pods.Измените адреса прослушивания kube-controller-manager и kube-scheduler:
sed -e "s/- --bind-address=127.0.0.1/- --bind-address=0.0.0.0/" -i /etc/kubernetes/manifests/kube-controller-manager.yaml sed -e "s/- --bind-address=127.0.0.1/- --bind-address=0.0.0.0/" -i /etc/kubernetes/manifests/kube-scheduler.yaml
Сценарий настройки метрик кластера#
Метрики, которые относятся к состоянию кластера отображаются дополнительным компонентом kube-state-metrics.
Для обзора ресурсов nodes кластера используется Prometheus node_exporter. Node_exporter позволяет отслеживать ресурсы node: процессор, использование памяти и диска и многое другое.
После завершения настройки будут доступны для отслеживания:
состояние кластера через kube-state-metrics;
nodes через node_exporter;
kubelets;
api-server;
kube-scheduler;
kube-controller-manager.
Для настройки сбора метрик кластера выполните следующую последовательность:
Клонируйте репозиторий:
git clone https://<repoexample.ru>/coreos/kube-prometheus cd kube-prometheus/ # Укажите актуальный путь до локального репозиторияCоздайте namespace, в котором должен работать набор инструментов мониторинга:
export NAMESPACE='monitoring' kubectl create namespace "$NAMESPACE"Создайте компоненты для оператора Prometheus:
kubectl --namespace="$NAMESPACE" apply -f manifests/prometheus-operatorКомпоненты станут доступны в кластере спустя некоторое время.
Проверьте готовность компонентов, введите команду:
until kubectl --namespace="$NAMESPACE" get alertmanagers.monitoring.os.com > /dev/null 2>&1; do sleep 1; printf "."; doneУстановите node-exporter, а затем kube-state-metrics:
kubectl --namespace="$NAMESPACE" apply -f manifests/node-exporter kubectl --namespace="$NAMESPACE" apply -f manifests/kube-state-metricsРазверните приложение, а затем роли/ролевые привязки Prometeus:
find manifests/prometheus -type f ! -name prometheus-k8s-roles.yaml ! -name prometheus-k8s-role-bindings.yaml -exec kubectl --namespace "$NAMESPACE" apply -f {} \; kubectl apply -f manifests/prometheus/prometheus-k8s-roles.yaml kubectl apply -f manifests/prometheus/prometheus-k8s-role-bindings.yamlУстановите Prometheus-alertmanager:
kubectl --namespace="$NAMESPACE" apply -f manifests/alertmanagerВ результате выполнения сценария создан кластер, доступны пользовательские интерфейсы Prometheus и Prometheus-alertmanager на портах node 30900 и 30903.