Мониторинг Stronghold строится на трёх источниках данных:

  • метрики телеметрии: доступны через эндпоинт /v1/sys/metrics и, если настроено, отправляются во внешние системы (StatsD, DogStatsD и другие);
  • эндпоинт проверки состояния /v1/sys/health;
  • серверные журналы и журналы аудита.

Полный перечень метрик с типами и лейблами приведён в разделе «Каталог метрик».

Варианты подключения

У Stronghold один источник метрик (подсистема телеметрии) и несколько способов доставки метрик в систему мониторинга. Приёмник в памяти, на котором строится JSON-ответ sys/metrics, включён всегда. Приёмник Prometheus включён по умолчанию (prometheus_retention_time = 24h), а push-приёмники включаются параметрами блока telemetry. Все включённые приёмники работают одновременно.

ВариантКогда использоватьГде настраиваетсяЧто требуется
Pull Prometheus с sys/metrics?format=prometheus (standalone)Автономная установка с Prometheus (или совместимым сборщиком)Блок telemetry (prometheus_retention_time) и, при необходимости, блок telemetry в listenerСетевой доступ Prometheus к API-порту каждого узла; токен с правом read на sys/metrics либо unauthenticated_metrics_access = true в listener
DP: встроенный Prometheus (PodMonitor и kube-rbac-proxy)Stronghold в DP с включённым модулем prometheus: метрики собираются без дополнительной настройкиУправляется модулем, настройка не требуетсяМодуль prometheus; CRD PodMonitor monitoring.coreos.com/v1
DP: внешний PrometheusМетрики должен собирать Prometheus вне стека мониторинга DPМодулем не настраивается: доступ создаётся вручную, как описано в разделе «Внешний Prometheus в DP»Сетевой доступ к порту 9889 подов; токен Kubernetes с правом get на statefulsets/prometheus-metrics
Push StatsD (statsd_address)Уже есть StatsD-совместимый сборщик, нужна отправка по UDPБлок telemetryАдрес сборщика, доступный с узла
Push Statsite (statsite_address)Используется Statsite, нужна отправка по TCPБлок telemetryАдрес Statsite, доступный с узла
Push DogStatsD (dogstatsd_addr)На узлах установлен Datadog Agent (DogStatsD), нужны тегиБлок telemetryАдрес DogStatsD, доступный с узла
Push Circonus (circonus_*)Метрики нужно отправлять в CirconusБлок telemetryAPI-токен Circonus или URL отправки (submission URL)
Push Stackdriver (stackdriver_*)Метрики нужно отправлять в Google Cloud MonitoringБлок telemetryПроект Google Cloud; учётные данные, доступные процессу (Application Default Credentials)

Примечания:

  • Все перечисленные приёмники доступны во всех редакциях Stronghold.
  • Push-приёмники можно сочетать с Prometheus и друг с другом. Если включено больше одного приёмника, задайте disable_hostname = true: иначе при запуске Stronghold выводит предупреждение, так как имена метрик с именем узла неудобны для Prometheus.
  • Push-приёмники настраиваются только в конфигурационном файле, поэтому доступны только в автономной установке. В DP блок telemetry формирует модуль и не предоставляет его параметры. Подробнее — в разделе «Мониторинг в DP».

Включение телеметрии

Этот раздел и следующие до «Мониторинг в DP» описывают автономную (standalone) установку. В DP конфигурацией управляет модуль через ConfigMap stronghold-config. Подробнее — в разделе «Мониторинг в DP».

Параметры телеметрии задаются в блоке telemetry конфигурационного файла сервера. Допускается только один блок telemetry. Полный перечень параметров приведён в разделе «Параметры конфигурации».

Prometheus

Приёмник Prometheus включён по умолчанию: время хранения по умолчанию равно 24h. Задайте его явно и отключите добавление имени узла, чтобы имена метрик на всех узлах совпадали:

telemetry {
  prometheus_retention_time = "24h"
  disable_hostname          = true
}
  • prometheus_retention_time — время, в течение которого метрики хранятся для выдачи в формате Prometheus. Значение 0 отключает Prometheus-формат.
  • disable_hostname — не добавлять имя узла в префикс метрик.
  • metrics_prefix — префикс имён метрик. По умолчанию метрики имеют префикс stronghold.

Затем настройте доступ к эндпоинту, как описано в разделе «Доступ к эндпоинту sys/metrics».

Push-приёмники

Push-приёмники отправляют метрики во внешний сборщик. Каждый приёмник включается наличием его адреса (или учётных данных) в блоке telemetry.

StatsD (UDP):

telemetry {
  statsd_address   = "127.0.0.1:8125"
  disable_hostname = true
}

Statsite (TCP):

telemetry {
  statsite_address = "127.0.0.1:8125"
  disable_hostname = true
}

DogStatsD:

telemetry {
  dogstatsd_addr   = "127.0.0.1:8125"
  dogstatsd_tags   = ["env:prod", "service:stronghold"]
  disable_hostname = true
}

Circonus. Приёмник включается, если задан circonus_api_token или circonus_submission_url:

telemetry {
  circonus_api_token           = "<API_TOKEN>"
  circonus_api_app             = "stronghold"
  circonus_submission_interval = "10s"
  circonus_check_tags          = "env:prod"
  circonus_broker_select_tag   = "dc:dc1"
  disable_hostname             = true
}

В этом примере <API_TOKEN> — API-токен Circonus.

Google Stackdriver (Cloud Monitoring). Приёмник включается, если задан stackdriver_project_id; учётные данные берутся из окружения процесса (Application Default Credentials, например, переменная GOOGLE_APPLICATION_CREDENTIALS):

telemetry {
  stackdriver_project_id = "my-project"
  stackdriver_location   = "europe-west1"
  stackdriver_namespace  = "stronghold-prod"
  disable_hostname       = true
}

Если нужна только push-доставка, приёмник Prometheus можно отключить значением prometheus_retention_time = 0.

После изменения конфигурации перезапустите службу (standalone):

systemctl restart stronghold

Проверка сбора метрик

Standalone, на узле (используйте токен с правом read на sys/metrics либо listener с unauthenticated_metrics_access):

curl -s --header "X-Vault-Token: ${STRONGHOLD_TOKEN}" "${STRONGHOLD_ADDR}/v1/sys/metrics?format=prometheus" | grep '^stronghold_core_unsealed'

Ожидаемый вывод:

stronghold_core_unsealed 1

Проверка сбора в Prometheus:

  1. Откройте страницу Status → Targets (или /targets) и убедитесь, что цели задания stronghold находятся в состоянии UP.

  2. Выполните запрос, например:

    stronghold_core_unsealed

    Результат должен содержать по одной серии на каждый узел.

Для push-приёмников проверьте принимающую сторону: метрики должны появиться с префиксом, заданным в metrics_prefix (по умолчанию stronghold). Ошибки инициализации приёмников сервер выводит при запуске (Error initializing telemetry). Проверка в DP описана в разделе «Проверка сбора в DP».

Доступ к эндпоинту sys/metrics

Эндпоинт GET /sys/metrics возвращает метрики узла, получившего запрос. Он регистрируется по точному пути /v1/sys/metrics каждого listener.

Форматы ответа

Правила выбора формата:

  • параметр запроса format: prometheus возвращает текстовый формат Prometheus, любое другое непустое значение возвращает 400 с текстом metric response format "..." unknown;
  • если format не задан, проверяется заголовок Accept: если первое значение Accept начинается с application/openmetrics-text либо любое значение Accept содержит prometheus/telemetry, возвращается формат Prometheus;
  • иначе возвращается JSON.
ФорматКак запроситьContent-TypeСодержимое
Prometheus?format=prometheus (или заголовок Accept, как описано выше)Текстовый формат PrometheusМетрики, собранные за время хранения prometheus_retention_time
JSONбез formatapplication/jsonСводка за последний завершённый 10-секундный интервал приёмника в памяти

Чтобы получить метрики в формате Prometheus, выполните команду:

curl --header "X-Vault-Token: ${STRONGHOLD_TOKEN}" "${STRONGHOLD_ADDR}/v1/sys/metrics?format=prometheus"

Пример вывода:

# HELP stronghold_core_handle_request stronghold_core_handle_request
# TYPE stronghold_core_handle_request summary
stronghold_core_handle_request{quantile="0.5"} 0.071
stronghold_core_handle_request{quantile="0.9"} 0.139
stronghold_core_handle_request{quantile="0.99"} 0.612
stronghold_core_handle_request_sum 1203.4
stronghold_core_handle_request_count 8417
# HELP stronghold_core_unsealed stronghold_core_unsealed
# TYPE stronghold_core_unsealed gauge
stronghold_core_unsealed 1

Чтобы получить метрики в формате JSON, выполните команду:

curl --header "X-Vault-Token: ${STRONGHOLD_TOKEN}" "${STRONGHOLD_ADDR}/v1/sys/metrics"

Пример вывода (значения условные):

{
  "Timestamp": "2026-01-15 10:21:30 +0000 UTC",
  "Gauges": [
    { "Name": "stronghold.core.unsealed", "Value": 1, "Labels": {} },
    { "Name": "stronghold.token.count", "Value": 12, "Labels": { "namespace": "root" } }
  ],
  "Points": [],
  "Counters": [
    {
      "Name": "stronghold.audit.log_request_failure",
      "Count": 0, "Rate": 0, "Sum": 0, "Min": 0, "Max": 0,
      "Mean": 0, "Stddev": 0, "Labels": {}
    }
  ],
  "Samples": [
    {
      "Name": "stronghold.core.handle_request",
      "Count": 42, "Rate": 4.2, "Sum": 3.1, "Min": 0.04, "Max": 0.3,
      "Mean": 0.074, "Stddev": 0.05, "Labels": {}
    }
  ]
}

В JSON-ответе части имени разделены точками, в формате Prometheus — подчёркиваниями. В Gauges находятся gauge-метрики, в Counters — счётчики, в Samples — таймеры и выборки (тип summary в Prometheus).

Требования к доступу

  • Токен. По умолчанию для запроса нужен токен (заголовок X-Vault-Token или Authorization: Bearer), политика которого разрешает возможность read на путь sys/metrics. Возможность sudo не требуется. Без токена ответ — 403 (permission denied).
  • Распечатанный узел. Запрос с токеном к запечатанному узлу возвращает 503.
  • Standby-узлы. Запрос не перенаправляется на активный узел принудительно, так как токен можно проверить только на активном узле. Standby-узел отвечает на запрос с токеном кодом 307 и заголовком Location, указывающим на активный узел. Prometheus по умолчанию следует перенаправлениям, поэтому при сборе со standby-узла по токену возвращаются метрики активного узла. Чтобы получать метрики каждого узла, используйте доступ без аутентификации.
  • TLS. Эндпоинт обслуживается listener по настроенному для него протоколу: если для listener включён TLS, используйте HTTPS и укажите сертификат CA (--cacert).
  • Метод. Для варианта без аутентификации допустим только GET: другие методы возвращают 405.
  • Приёмник Prometheus отключён. При prometheus_retention_time = 0 запрос с format=prometheus возвращает 400 с текстом prometheus is not enabled. JSON-формат продолжает работать.

Доступ по токену

Создайте отдельную политику с минимальными правами для сборщика метрик:

path "sys/metrics" {
  capabilities = ["read"]
}

Сохраните политику в файл prometheus-metrics.hcl, запишите её в Stronghold и создайте токен с этой политикой:

d8 stronghold policy write prometheus-metrics prometheus-metrics.hcl
d8 stronghold token create -policy=prometheus-metrics -orphan -period=24h

Используйте периодический токен и настройте его продление либо выдавайте токен через метод аутентификации (например, Kubernetes или AppRole).

Доступ без аутентификации

Если метрики собираются из доверенной сети, разрешите доступ без аутентификации на уровне listener:

listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/opt/stronghold/tls/node-1-cert.pem"
  tls_key_file  = "/opt/stronghold/tls/node-1-key.pem"

  telemetry {
    unauthenticated_metrics_access = true
  }
}

Особенности параметра unauthenticated_metrics_access:

  • значение по умолчанию — false;
  • действует только на тот listener, в блоке telemetry которого задан, и только на путь /v1/sys/metrics (остальные пути sys/ по-прежнему требуют токен);
  • запрос обрабатывается самим узлом без проверки токена и перенаправления, поэтому standby-узлы (и запечатанные узлы) тоже отдают собственные метрики;
  • допускается только метод GET.

Метрики раскрывают сведения об устройстве хранилища (пути монтирования, количество аренд и токенов). Разрешайте доступ без аутентификации только при ограниченном сетевом доступе к listener, например, на отдельном listener, привязанном к адресу управления.

Пример задания для Prometheus

Следующее задание Prometheus собирает метрики с трёх узлов кластера с доступом по токену:

scrape_configs:
  - job_name: stronghold
    metrics_path: /v1/sys/metrics
    params:
      format: ["prometheus"]
    scheme: https
    tls_config:
      ca_file: /etc/prometheus/stronghold-ca.pem
    authorization:
      credentials_file: /etc/prometheus/stronghold-token
    static_configs:
      - targets:
          - raft-node-1.demo.tld:8200
          - raft-node-2.demo.tld:8200
          - raft-node-3.demo.tld:8200

Собирайте метрики с каждого узла кластера, а не только с адреса балансировщика: часть метрик (Raft, runtime) относится к конкретному узлу. Учитывайте поведение standby-узлов, описанное выше: при доступе по токену цели, которые являются standby-узлами, перенаправляются на активный узел.

Мониторинг в DP

В DP Stronghold работает в неймспейсе d8-stronghold, а его конфигурацией (включая телеметрию) управляет модуль через ConfigMap stronghold-config. Метрики собираются следующим образом:

  • в настройках телеметрии заданы metrics_prefix = "stronghold" (а также prometheus_retention_time = "1m" и disable_hostname = true), поэтому все метрики имеют префикс stronghold_ (например, stronghold_core_unsealed);
  • метрики отдаёт loopback-listener 127.0.0.1:8400 (без TLS, с unauthenticated_metrics_access = true), недоступный снаружи пода;
  • sidecar kube-rbac-proxy публикует их на порту 9889 (https-metrics, путь /metrics; запрос передаётся на /v1/sys/metrics?format=prometheus loopback-listener); для доступа требуется право get на statefulsets/prometheus-metrics (ресурс stronghold, группа API apps) в неймспейсе d8-stronghold. Модуль создаёт Role access-to-stronghold-metrics с этим правом и, если включён модуль prometheus, связывает её с ServiceAccount prometheus в d8-monitoring и пользователем d8-monitoring:scraper.

Объекты мониторинга модуль создаёт сам, настраивать ничего не нужно:

  • PodMonitor stronghold в неймспейсе d8-monitoring (создаётся, только если в кластере есть CRD PodMonitor monitoring.coreos.com/v1);
  • PrometheusRule с алертами модуля;
  • три дашборда Grafana: stronghold.json, replication.json и snapshot_auto.json.

Используйте этот вариант, если в DP включён модуль prometheus: ничего дополнительно не требуется.

Проверка сбора в DP

Чтобы проверить наличие объекта сбора метрик, выполните команду:

d8 k -n d8-monitoring get podmonitor stronghold

Чтобы проверить, что Prometheus собирает метрики, откройте интерфейс Prometheus (Status → Targets): у задания d8-monitoring/stronghold должна быть по одной цели в состоянии UP на каждый под Stronghold. Затем выполните запрос:

stronghold_core_unsealed{job="d8-monitoring/stronghold"}

Ручной запрос метрик в DP

Чтобы получить метрики вручную, отправьте запрос на порт 9889 пода изнутри кластера с токеном ServiceAccount, у которого есть право get на statefulsets/prometheus-metrics. Выдайте право, связав субъект с Role модуля:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: access-to-stronghold-metrics-my-sa
  namespace: d8-stronghold
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: access-to-stronghold-metrics
subjects:
  - kind: ServiceAccount
    name: my-sa
    namespace: my-namespace

Затем отправьте запрос из пода, который использует этот ServiceAccount. Прокси использует собственный сертификат, поэтому в команде указан --insecure, как и в PodMonitor модуля:

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl --insecure --header "Authorization: Bearer ${TOKEN}" "https://<POD_IP>:9889/metrics"

В этой команде <POD_IP> — IP-адрес пода Stronghold. Чтобы получить IP-адреса подов, выполните команду:

d8 k -n d8-stronghold get pods -l app.kubernetes.io/name=stronghold,component=server -o wide

Внешний Prometheus в DP

Модуль настраивает сбор метрик только для Prometheus из стека мониторинга DP. Внешний Prometheus может собирать метрики, если:

  • он имеет сетевой доступ к порту 9889 подов Stronghold по HTTPS;
  • он обращается к пути /metrics и передаёт bearer-токен Kubernetes субъекта с правом get на statefulsets/prometheus-metrics (RoleBinding приведён выше);
  • конфигурацию сбора вы создаёте самостоятельно: PodMonitor модуля предназначен для Prometheus main стека мониторинга DP.

Отправка метрик в StatsD, DogStatsD, Circonus и Stackdriver в DP недоступна, так как блок telemetry формирует модуль, и изменить его через параметры модуля нельзя.

Алерты модуля в DP

Алерты заданы в PrometheusRule модуля и используют лейбл severity_level, как и остальные алерты DP:

АлертУсловиеforseverity_level
D8StrongholdNoReadyPodНи один под StatefulSet stronghold не находится в состоянии Ready3m4
D8StrongholdNoActiveNodesstronghold_core_active равна 0 на всех узлах (или метрики отсутствуют)1m3
D8StrongholdSealedNodesPresentКоличество узлов, отдающих метрики, больше количества распечатанных узлов5m7
D8StrongholdClusterNotHealthyСумма stronghold_autopilot_healthy равна 05m7
D8StrongholdQuorumInCriticalStatestronghold_autopilot_failure_tolerance равна 0; создаётся только если в кластере больше 2 master-узлов (clusterMasterCount > 2)3m4
D8StrongholdAbsentMetricsКоличество готовых контейнеров kube-rbac-proxy больше количества узлов, отдающих метрики1m3
D8StrongholdAutoSnapshotFailedstronghold_core_snapshot_auto_failed равна 1 для конфигурации автоматических снимков5m6
D8StrongholdAutoSnapshotRotationFailedstronghold_autosnapshots_rotate_failed равна 1: ротация старых снимков не удалась после успешного снимка15m8

Собственные алерты в DP задаются в CustomPrometheusRules: перенесите в него содержимое spec.groups из примеров ниже. Например, для алертов на ошибки автоматических снимков используйте группу stronghold.snapshots.

Параметры модуля, влияющие на мониторинг

Отдельных параметров мониторинга у модуля нет. На мониторинг и алерты влияют следующие настройки:

ПараметрВлияние
global.discovery.clusterMasterCount (параметр кластера, не модуля)Алерт D8StrongholdQuorumInCriticalState создаётся, только если значение больше 2
diskSizeGigabytesМодуль extended-monitoring автоматически отслеживает процент занятого дискового пространства
enableAuditLogВключает журнал аудита (только в Stronghold EE; требует management.mode = Automatic). Сбои аудит-устройств видны по метрикам stronghold_audit_log_*_failure

Блок telemetry конфигурации DP формирует модуль, и он содержит только значения: prometheus_retention_time = "1m", disable_hostname = true, metrics_prefix = "stronghold". У listener 127.0.0.1:8400 задано unauthenticated_metrics_access = true. Остальные параметры telemetry в DP недоступны.

Параметры конфигурации

Блок telemetry

Параметры блока telemetry конфигурационного файла сервера (standalone). В DP эти параметры изменить нельзя. Подробнее — в разделе «Параметры модуля, влияющие на мониторинг».

ПараметрТипПо умолчаниюДопустимые значения и назначение
prometheus_retention_timeдлительность24hВремя хранения метрик для формата Prometheus. Строка длительности ("24h", "30m", "2d") или число секунд. 0 отключает приёмник Prometheus: запрос с format=prometheus возвращает 400
disable_hostnamebooleanfalsetrue — не добавлять имя узла в имя метрики, чтобы имена метрик на всех узлах совпадали. Если включён единственный приёмник, имя узла не добавляется независимо от значения
enable_hostname_labelbooleanfalsetrue — добавлять имя узла в лейбл host вместо префикса имени
metrics_prefixстрокаstrongholdПрефикс имён всех метрик
usage_gauge_periodдлительность10mПериод сбора usage-gauge (токены, аренды, секреты KV, сущности identity). "none" или 0 отключает сбор. Gauge собираются только на активном узле (не на standby-узлах и не на DR-вторичных кластерах)
maximum_gauge_cardinalityцелое500Максимальное количество комбинаций лейблов, которое один usage-gauge отдаёт за сбор; при превышении остаются комбинации с наибольшими значениями
lease_metrics_epsilonдлительность1hРазмер временного интервала (bucket) для агрегации аренд по времени истечения. "none" задаёт 0
num_lease_metrics_bucketsцелое168Количество временных интервалов для агрегации аренд
add_lease_metrics_namespace_labelsbooleanfalsetrue — добавлять лейбл пространства имён в метрики истечения аренд
filter_defaultbooleantrueРазрешать ли метрики, не подпадающие ни под одно правило prefix_filter
prefix_filterсписок строкпустоПравила фильтрации метрик по префиксу имени. Правило начинается с + (разрешить) или - (запретить), далее префикс. Префикс сопоставляется с полным именем через точки, включая metrics_prefix, например "-stronghold.expire". Пустое правило или правило без +/- — ошибка конфигурации
statsd_addressстрокапустоАдрес StatsD (host:port, UDP). Включает приёмник StatsD
statsite_addressстрокапустоАдрес Statsite (host:port, TCP). Включает приёмник Statsite
dogstatsd_addrстрокапустоАдрес DogStatsD. Включает приёмник DogStatsD
dogstatsd_tagsсписок строкпустоГлобальные теги для каждого пакета DogStatsD в формате name:value
circonus_api_tokenстрокапустоAPI-токен Circonus. Приёмник Circonus включается, если задан он или circonus_submission_url
circonus_submission_urlстрокапустоURL отправки ранее созданной проверки HTTPTRAP
circonus_api_appстрокаstrongholdИмя приложения, связанного с API-токеном
circonus_api_urlстроказначение по умолчанию библиотеки CirconusБазовый URL API Circonus
circonus_submission_intervalстроказначение по умолчанию библиотеки Circonus (10s)Интервал отправки метрик
circonus_check_idстрокапустоИдентификатор ранее созданной проверки
circonus_check_force_metric_activationстрокаfalseПринудительно активировать метрики, уже существующие в проверке
circonus_check_instance_idстроказначение по умолчанию библиотеки CirconusИдентификатор этого экземпляра в проверке
circonus_check_search_tagстрокаservice:strongholdТег для поиска существующей проверки
circonus_check_tagsстрокапустоСписок тегов проверки через запятую
circonus_check_display_nameстрокаStrongholdНазвание проверки в интерфейсе Circonus
circonus_broker_idстрокапустоИдентификатор брокера, используемого при создании проверки
circonus_broker_select_tagстрокапустоТег для выбора брокера, если не задан circonus_broker_id
stackdriver_project_idстрокапустоПроект Google Cloud. Включает приёмник Stackdriver
stackdriver_locationстрокапустоРегион GCP или AWS наблюдаемого ресурса
stackdriver_namespaceстрокапустоИдентификатор пространства имён, например имя кластера
stackdriver_debug_logsbooleanfalseПисать дополнительные отладочные журналы Stackdriver в stderr

Параметры-длительности принимают строку с суффиксом единицы (s, m, h, а также d для дней) или целое число секунд.

Параметры circonus_* подробнее описаны в документации Circonus gometrics.

Блок telemetry в listener

Блок telemetry внутри listener "tcp" имеет собственный параметр:

ПараметрТипПо умолчаниюНазначение
unauthenticated_metrics_accessbooleanfalsetrue — эндпоинт /v1/sys/metrics этого listener доступен без токена. Подробнее — в разделе «Доступ без аутентификации»

Ключевые метрики

Названия метрик приведены с префиксом stronghold_: по умолчанию Stronghold использует его и в standalone-установке, и в DP. Префикс можно изменить параметром metrics_prefix блока telemetry. Полный перечень метрик приведён в разделе «Каталог метрик».

Тип указан как в формате Prometheus: тип summary включает лейбл quantile (0.5, 0.9, 0.99) и серии _sum и _count.

МетрикаТипЛейблыЧто показываетНа что обратить внимание
stronghold_core_unsealedgaugeнетУзел распечатан (1) или запечатан (0)Любое значение 0
stronghold_core_activegaugeнетУзел является активным (1)Сумма по кластеру должна быть равна 1
stronghold_core_handle_requestsummaryнетВремя обработки запросов, мсРост 99-го перцентиля
stronghold_core_handle_login_requestsummaryнетВремя обработки запросов аутентификации, мсРост 99-го перцентиля
stronghold_expire_num_leasesgaugeнетКоличество активных арендПостоянный рост без снижения
stronghold_token_countgaugenamespaceКоличество токенов (метрику отдаёт только активный узел раз в usage_gauge_period)Постоянный рост без снижения
stronghold_audit_log_request_failurecounterнетОшибки записи запросов в аудит-устройстваЛюбое ненулевое приращение
stronghold_audit_log_response_failurecounterнетОшибки записи ответов в аудит-устройстваЛюбое ненулевое приращение
stronghold_raft_leader_lastContactsummaryнетВремя с последнего контакта лидера Raft с ведомым узлом, мс. Метрику отдаёт лидер, по одному замеру на каждый ведомый узелЗначения выше сотен миллисекунд
stronghold_raft_state_candidatecounterнетПереходы узла в состояние кандидата RaftЧастые приращения — признак нестабильных выборов лидера
stronghold_raft_commitTimesummaryнетВремя фиксации записи в Raft на лидере, мсРост — признак медленного диска или сети
stronghold_autopilot_healthygaugeнетСостояние кластера по данным Autopilot (отдаёт лидер)Значение 0
stronghold_autopilot_failure_tolerancegaugeнетКоличество узлов, отказ которых не приведёт к потере кворума (отдаёт лидер)Значение 0
stronghold_runtime_alloc_bytesgaugeнетИспользуемая процессом памятьПриближение к лимиту памяти
stronghold_autosnapshots_save_errorscountersnapshot_config_nameНеудачные попытки создать автоматический снимок (Stronghold EE)Любое ненулевое приращение
stronghold_autosnapshots_last_success_timegaugesnapshot_config_nameВремя последнего успешного автоматического снимка, Unix-время в секундах (Stronghold EE)Значение старше интервала создания снимков в конфигурации
stronghold_core_snapshot_auto_failedgaugeconfigПризнак ошибки автоматического снимка, используется алертом D8StrongholdAutoSnapshotFailed (Stronghold EE)Значение 1
stronghold_autosnapshots_rotate_failedgaugesnapshot_config_nameПризнак ошибки ротации снимков, используется алертом D8StrongholdAutoSnapshotRotationFailed (Stronghold EE)Значение 1

Примеры правил алертинга

Пример ресурса PrometheusRule с базовым набором алертов. Это шаблон для standalone-установки: он использует лейбл severity и пути standalone. Алерты для DP описаны в разделе «Алерты модуля в DP». Пороговые значения подберите под свою нагрузку.

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: stronghold
spec:
  groups:
    - name: stronghold.availability
      rules:
        - alert: StrongholdSealed
          expr: stronghold_core_unsealed == 0
          for: 1m
          labels:
            severity: critical
          annotations:
            summary: "Узел Stronghold {{ $labels.instance }} запечатан"
            description: "Узел не обслуживает запросы. Выполните распечатывание или проверьте auto unseal."
        - alert: StrongholdNoActiveNode
          expr: sum(stronghold_core_active) < 1
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "В кластере Stronghold нет активного узла"
            description: "Проверьте состояние Raft и кворума командой d8 stronghold operator raft list-peers."
        - alert: StrongholdLeaderFlapping
          expr: increase(stronghold_raft_state_candidate[15m]) > 3
          labels:
            severity: warning
          annotations:
            summary: "Частые выборы лидера Raft на {{ $labels.instance }}"
            description: "Проверьте сетевую связность между узлами и задержки диска."
        - alert: StrongholdAutopilotUnhealthy
          expr: stronghold_autopilot_healthy == 0
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Autopilot сообщает о неработоспособном кластере Stronghold"
    - name: stronghold.performance
      rules:
        - alert: StrongholdHighRequestLatency
          expr: stronghold_core_handle_request{quantile="0.99"} > 500
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "99-й перцентиль времени обработки запросов выше 500 мс"
        - alert: StrongholdLeaseCountGrowth
          expr: delta(stronghold_expire_num_leases[1h]) > 10000
          labels:
            severity: warning
          annotations:
            summary: "Количество аренд выросло более чем на 10000 за час"
            description: "Проверьте TTL аренд и клиентов, которые не переиспользуют токены."
        - alert: StrongholdLeaseCountHigh
          expr: stronghold_expire_num_leases > 250000
          for: 15m
          labels:
            severity: warning
          annotations:
            summary: "Количество активных аренд превышает 250000"
    - name: stronghold.audit
      rules:
        - alert: StrongholdAuditFailures
          expr: increase(stronghold_audit_log_request_failure[5m]) > 0 or increase(stronghold_audit_log_response_failure[5m]) > 0
          labels:
            severity: critical
          annotations:
            summary: "Ошибки записи в аудит-устройства Stronghold"
            description: "При отказе всех аудит-устройств Stronghold перестаёт обслуживать запросы."
    - name: stronghold.snapshots
      rules:
        - alert: StrongholdAutoSnapshotFailed
          expr: increase(stronghold_autosnapshots_save_errors[1h]) > 0
          labels:
            severity: warning
          annotations:
            summary: "Ошибка автоматического снимка {{ $labels.snapshot_config_name }}"
            description: "Проверьте серверные журналы и хранилище снимков."
    - name: stronghold.certificates
      rules:
        - alert: StrongholdTLSCertificateExpiringSoon
          expr: (probe_ssl_earliest_cert_expiry{job="stronghold-tls"} - time()) / 86400 < 21
          for: 1h
          labels:
            severity: warning
          annotations:
            summary: "TLS-сертификат Stronghold {{ $labels.instance }} истекает менее чем через 21 день"
    - name: stronghold.storage
      rules:
        - alert: StrongholdRaftDiskUsageHigh
          expr: |
            (1 - node_filesystem_avail_bytes{mountpoint="/opt/stronghold/data"}
              / node_filesystem_size_bytes{mountpoint="/opt/stronghold/data"}) > 0.8
          for: 15m
          labels:
            severity: warning
          annotations:
            summary: "Раздел с данными Raft на {{ $labels.instance }} заполнен более чем на 80%"

Комментарии к примеру:

  • Алерт на срок действия TLS-сертификата использует метрику probe_ssl_earliest_cert_expiry из blackbox_exporter, который опрашивает HTTPS-адрес Stronghold. Аналогично контролируйте срок действия корневых и промежуточных сертификатов PKI, выпущенных в Stronghold, например с помощью экспортера сертификатов, проверяющего файлы или адреса сервисов.
  • Алерт на заполнение диска использует метрики node-exporter. Укажите точку монтирования директории, заданной в параметре path блока storage "raft". В DP данные каждой реплики хранятся в PVC data-stronghold-N, который смонтирован в /stronghold/data внутри пода. Если параметр storageClass в конфигурации модуля не задан, PVC привязан к локальному PV в директории /var/lib/deckhouse/stronghold/<LOCAL_PATH_UUID> на master- или arbiter-узле: укажите точку монтирования файловой системы, в которой находится эта директория. Если storageClass задан, том создаётся этим классом хранения, и точка монтирования из примера неприменима.
  • Для DP перенесите spec.groups в CustomPrometheusRules.

Stronghold не экспортирует метрики срока действия сертификатов PKI (есть только метрики очистки secrets_pki_tidy_*). Контролируйте сроки сертификатов внешними средствами, например с помощью blackbox-exporter.

Проверка состояния через sys/health

Эндпоинт GET /sys/health доступен без аутентификации и подходит для проверок балансировщика и внешнего мониторинга:

curl -s -o /dev/null -w "%{http_code}\n" "${STRONGHOLD_ADDR}/v1/sys/health"

Коды ответа:

КодСостояние
200Инициализирован, распечатан, активный узел
429Распечатан, standby-узел
472Узел — вторичный кластер DR-репликации
473Performance standby-узел
423Активный узел ещё не готов (только при isleaderreadyok=true)
425Raft Autopilot ещё не готов (только при raftautopilotok=true)
501Не инициализирован
503Запечатан

Коды ответа можно переопределить параметрами запроса:

  • standbyok=true — возвращать 200 для standby-узлов. Используйте для балансировщика, который распределяет запросы на все распечатанные узлы;
  • activecode, standbycode, sealedcode, uninitcode, drsecondarycode, performancestandbycode, isleaderreadycode, raftautopilotcode — задать собственный код для соответствующего состояния;
  • perfstandbyok=true — возвращать 200 для узлов performance standby.

Пример проверки для балансировщика, который должен направлять трафик только на активный узел:

curl -s -o /dev/null -w "%{http_code}\n" "${STRONGHOLD_ADDR}/v1/sys/health?standbycode=503"

Для проверки состояния Raft используйте команды:

d8 stronghold operator raft list-peers
d8 stronghold operator raft autopilot state