Мониторинг — это сердце любой современной IT-инфраструктуры. Сегодня я хочу рассказать о нашем опыте построения и развития инфраструктуры мониторинга в одном из крупнейших банков России – Россельхозбанке.

Привет, Хабр! Меня зовут Сергей Смирнов, я DevOps экосистемы «Своё» в РСХБ.Цифра. Наша команда занимается поддержкой инфраструктуры проектов.
Речь пойдет не о всей гигантской IT-инфраструктуре банка, а о ее специфической части. Мы работаем с тем, что можно назвать «внешним облаком» РСХБ. В этой статье я расскажу об общей архитектуре, ключевых технологиях для сбора метрик, логов, трассировок, алертинга и визуализации, принципах настройки и развертывания, примерах и готовых решениях, в частности о том, как Victoria Metrics может стать центральным элементом системы мониторинга, охватывающей как Kubernetes, так и другие компоненты инфраструктуры.
Самое главное – я поделюсь конкретными примерами конфигурационных файлов, Helm-чартов или других манифестов, которые позволят вам развернуть базовый (или даже расширенный) стек мониторинга «из коробки» в вашей собственной среде.
Тема актуальна из-за растущей потребности в универсальных системах мониторинга, способных:
Обеспечивать глубокий анализ Kubernetes-кластеров,
Мониторить традиционные серверные инфраструктуры,
Работать с облачными сервисами,
Обрабатывать большие объемы данных,
Предоставлять гибкие возможности визуализации.
Victoria Metrics предлагает отличную альтернативу стандартному Prometheus: совместима с ним, но потребляет меньше ресурсов, быстрее обрабатывает запросы и лучше подходит для долгосрочного хранения метрик.
На практике развернем и настроим готовый вариант для мониторинга инфраструктуры.
Как работает система
Основные части системы:
VMSingle: Хранилище метрик.
VMAgent: Сборщик метрик.
VMAlert: Проверяет правила и создает алерты.
Alertmanager: Система управления оповещениями.
Grafana: Визуализация метрик, логов и прочего.
VMAuth: Прокси с авторизацией.
x509-certificate-exporter: Следит за сертификатами Kubernetes.
Prometheus Blackbox Exporter: Blackbox-мониторинг.

Предварительные требования
Требования к установке:
Kubernetes-кластер 1.25+
Helm 3+
Предустановленный Vault для секретов и External Secrets (включая External Secrets Operator). По настройке оставлю ссылку на свою предыдущую статью.
Зависимости для Helm: В боевом решении мы используем Argo CD для автоматизации, но для этого гайда упростим задачу и возьмем Helm. Чарт зависит от следующих пакетов:
victoria-metrics-k8s-stack— Helm charts · GitHubgrafana-operator— Helm charts · GitHubprometheus-blackbox-exporter— Helm charts · GitHubx509-certificate-exporter— Helm charts · GitHub
Пример Chart.yaml
apiVersion: v2
name: lab
description: Lab Kubernetes monitoring stack
type: application
version: 0.1.0
appVersion: "0.1.0"
dependencies: # Список зависимостей от других чартов
- name: victoria-metrics-k8s-stack # Зависимость от стека VictoriaMetrics
version: 0.x.x
repository: https://victoriametrics.github.io/helm-charts/
# ... другие зависимости
Конфигурация lab_values.yaml
Файл разделён на части по блокам.
Начнём с конфигурации victoria-metrics-k8s-stack. В чарт «из коробки» входят следующие компоненты:
VM Operator
VMSingle
VMAgent
VMAlert
Alertmanager
Общая конфигурация
Helm-чарт victoria-metrics-k8s-stack поставляет из коробки необходимые дашборды и правила для мониторинга Kubernetes. Мы вынесли их из этого чарта в целевой чарт для управления и дальнейшей доработки.
Если вы пользовались CRD от Prometheus, VM Operator конвертирует их в свои CRD.
Конфигурация lab_values.yaml
global:
cluster:
# Суффикс DNS кластера (обычно cluster.local.). Здесь lab. — просто тестовый пример.
dnsDomain: lab.
victoria-metrics-k8s-stack:
fullnameOverride: "k8s"
victoria-metrics-operator: # Оператор для управления VM ресурсами
serviceAccount:
create: true
operator:
prometheus_converter_add_argocd_ignore_annotations: true
enable_converter_ownership: true
grafana: # Настройка встроенной в VM k8s stack Grafana (отключена)
enabled: false
defaultRules: # Дефолтные правила алертинга (отключены)
create: false
defaultDashboards: # Дефолтные дашборды (отключены)
enabled: false
defaultTimezone: msk
labels: {}
annotations: {}
grafanaOperator:
enabled: true
spec:
instanceSelector:
matchLabels:
dashboards: grafana
allowCrossNamespaceImport: false
dashboards:
victoriametrics-vmalert:
enabled: false
victoriametrics-operator:
enabled: false
node-exporter-full:
enabled: false
Настройка VMSingle
Для наших задач хватает VMSingle — компонент для развертывания одноузловой версии (приём, хранение, обработка данных, API) VictoriaMetrics в Kubernetes.
Если скорость обработки данных более миллиона точек в секунду(взято из документации), нужна мультитенантность или retention для разных метрик/тенантов — используйте VMCluster.
Конфигурация lab_values.yaml
vmsingle:
enabled: true
spec:
# По умолчанию VMSingle слушает на 8428.
port: "8428"
# Если единица не указана, то значение в месяцах: "1" = 1 месяц.
retentionPeriod: "1"
extraArgs:
dedup.minScrapeInterval: 30s
# Ресурсы произвольные, взяты для теста
resources:
requests:
memory: "800Mi"
cpu: "600m"
limits:
memory: "1600Mi"
cpu: "1200m"
storage: # По умолчанию использует дефолтный storage class
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Настройка VMAgent
VMAgent — агент для сбора метрик из различных источников.
Настроим VMAgent и таргеты для мониторинга. Метрики Kubernetes собираются из коробки. Для внешних таргетов необходимо настроить volumes и volumeMounts.
Конфигурация из lab_values.yaml
vmagent:
enabled: true
spec:
resources:
limits:
cpu: "300m"
memory: "600Mi"
requests:
cpu: "150m"
memory: "300Mi"
scrapeInterval: 30s
scrapeTimeout: 25s
externalLabels:
env: lab-infra # Дополнительный лейбл для фильтрации, если у вас несколько VMAgent в других кластерах/VM и т.п.
replicaCount: 2
selectAllByDefault: true
secrets: ["etcd-secret"] # Нужен для аутентификации в etcd
extraArgs:
promscrape.streamParse: "true"
promscrape.maxScrapeSize: 50MB
promscrape.maxDroppedTargets: "5000"
promscrape.dropOriginalLabels: "false"
loggerTimezone: Europe/Moscow
promscrape.suppressScrapeErrorsDelay: 5s
additionalScrapeConfigs:
name: vault-secrets # имя секрета из Vault, где лежит конфигурационный файл
key: additional-scrape-configs.yaml
remoteWrite:
# URL VMSingle (ниже lab — тестовый cluster domain из примера выше).
# Имя `vmsingle-k8s` — это пример для релиза с именем `k8s` (обычно шаблон: `<component>-<releaseName>`).
# В вашем случае подставьте фактическое имя сервиса/CR или задайте `fullnameOverride`.
- url: "http://vmsingle-k8s.mon.svc.lab:8428/api/v1/write"
volumes:
- name: node-exporter-targets
configMap:
name: k8s-vmagent-targets-node-exporter # `k8s` — пример префикса из `fullnameOverride` (или имени Helm-релиза)
volumeMounts:
- mountPath: /etc/vmagent/targets/node-exporter
name: node-exporter-targets
Генерация секрета для etcd
kubectl create secret --namespace mon generic etcd-secret \
--from-file=etcd-client-ca.crt=/etc/kubernetes/pki/etcd/ca.crt \
--from-file=etcd-client.key=/etc/kubernetes/pki/etcd/peer.key \
--from-file=etcd-client.crt=/etc/kubernetes/pki/etcd/peer.crt
Секрет additional-scrape-configs.yaml из Vault
- job_name: 'node-exporter'
# node exporter использует basic auth для доступа к эндпоинту :9100/metrics
basic_auth:
username: 'username'
password: 'password'
honor_labels: true
file_sd_configs:
- files:
- /etc/vmagent/targets/node-exporter/*.yaml
Целевые группы для VMAgent из lab_values.yaml
targetGroups:
node-exporter:
- address: "192.168.20.2:9102"
labels:
host: "lab-01"
configMap для volumes cобирается из шаблона. configmap.yaml находится в директории templates нашего чарта.
configmap.yaml
{{- range $name, $targets := .Values.targetGroups }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ $.Release.Name }}-vmagent-targets-{{ $name }}
labels:
app: {{ $.Release.Name }}-vmagent
data:
targets-{{ $name }}.yaml: |
{{- range $index, $target := $targets }}
{{- if $index }}{{ end }}
- targets: [{{ $target.address }}]
labels:
{{- range $key, $value := $target.labels }}
{{ $key }}: {{ $value }}
{{- end }}
{{- end }}
{{- end }}
Добавим в конфигурационный файл сбор метрик с etcd, scheduler, controllermanager. VM Operator создаст ресурс VMServiceScrape для каждого компонента.
Конфигурация из lab_values.yaml
kubeEtcd: # Скрейпинг метрик etcd
enabled: true
endpoints: #[ ]
- 192.168.1.3 # Адрес(а) Ваших control-plane нод
service:
enabled: true
port: 2379
targetPort: 2379
selector:
component: etcd
vmScrape:
spec:
jobLabel: jobLabel
namespaceSelector:
matchNames: [kube-system]
endpoints:
- port: http-metrics
scheme: https
tlsConfig:
insecureSkipVerify: false
caFile: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
# Секрет etcd, прописанный в конфигурации vmagent
certFile: "/etc/vm/secrets/etcd-secret/etcd-client.crt"
keyFile: "/etc/vm/secrets/etcd-secret/etcd-client.key"
kubeScheduler: # Скрейпинг метрик kube-scheduler
endpoints:
- 192.168.1.3 # Адрес(а) Ваших control-plane нод
vmScrape:
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
port: http-metrics
scheme: https
tlsConfig:
caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecureSkipVerify: false
serverName: kubernetes
kubeControllerManager: # Скрейпинг метрик kube-controller-manager
endpoints:
- 192.168.1.3 # Адрес(а) Ваших control-plane нод
vmScrape:
spec:
endpoints:
- bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
port: http-metrics
scheme: https
tlsConfig:
caFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecureSkipVerify: false
serverName: kubernetes
Настройка алертинга
VMAlert — компонент для обработки алертов.
Alertmanager — система управления оповещениями. Занимается дедупликацией, группировкой и маршрутизацией уведомлений в нужные каналы.
Настроим VMAlert, Alertmanager, правила для мониторинга и отправку сообщений в Telegram.
Конфигурация из lab_values.yaml
alertmanager: # Конфигурация Alertmanager для обработки алертов
enabled: true
monzoTemplate:
enabled: false
config:
global:
resolve_timeout: 3m
route:
receiver: blackhole
group_by: [alertname, severity]
group_wait: 30s
group_interval: 1m
repeat_interval: 8737h
routes:
- matchers:
- severity="critical"
receiver: telegram-critical
continue: true
- matchers:
- alertname="Watchdog"
- alertname="InfoInhibitor"
receiver: blackhole
receivers:
- name: telegram-critical
telegram_configs:
- bot_token: "" # Токен вашего телеграм чата
chat_id: # ID вашего телеграм чата
send_resolved: true
parse_mode: MarkdownV2 # Можно также: HTML
disable_notifications: false
message_thread_id: 4 # ID топика Telegram-группы (если используете)
- name: blackhole
templateFiles: # Шаблоны для Alertmanager (например, для форматирования сообщений)
telegram.tmpl: "" # Сокращено для краткости. Можно в markdown/html.
vmalert: # Конфигурация VMAlert для обработки правил алертинга
annotations: {}
enabled: true
Настроим алерты, используя ресурс VictoriaMetrics Operator — VMRule.
Конфигурация ресурса VMRule из nodeexporter_rule.yaml
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMRule
metadata:
name: k8s-stack-node-exporter
namespace: mon
spec:
groups:
- name: node-exporter # Имя группы
params: {} # Параметры
rules:
# ... полные правила опущены
Настройка Grafana
Grafana — это платформа для сбора, мониторинга и визуализации данных.
Grafana разворачивается через Grafana Operator.
Настроим следующие ресурсы:
Grafana
GrafanaFolder
GrafanaDatasource
GrafanaDashboard
GrafanaFolder и GrafanaDatasource создаются из шаблонов в директории templates/ нашего чарта. Для GrafanaDashboard это нецелесообразно, потому что количество строк JSON может быть огромным.
Конфигурация из lab_values.yaml
grafana: # Конфигурация Grafana
enabled: true
ingress:
host: grafana.lab.local
folders:
- name: victoria-metrics # имя папки
permissions:
- role: Admin # в данном варианте пользователи с правами viewers не увидят ее
permission: 4
- role: Editor
permission: 2
- name: infra # директория доступна всем
- name: node-exporter # можно создавать поддиректории
parentFolder: infra
datasources: # список источников данных для Grafana
- name: prometheus
access: proxy
type: prometheus
datasourceName: VictoriaMetrics
# Если не хотите завязываться на FQDN, можно использовать просто http://<service>:<port> внутри namespace.
url: http://vmsingle-k8s.mon.svc.lab:8428
isDefault: true
- name: alertmanager
access: proxy
type: alertmanager
datasourceName: Alertmanager
url: http://vmalertmanager-k8s.mon.svc.lab:9093
jsonData:
implementation: prometheus
handleGrafanaManagedAlerts: false
Шаблоны для ресурсов Grafana, GrafanaFolder, GrafanaDatasource.
Секреты для пользователя admin тянутся из Vault.
Файл grafana-core.yaml
{{- if .Values.grafana.enabled -}}
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
labels:
dashboards: "grafana"
spec:
config:
log:
mode: "console"
deployment:
spec:
template:
spec:
containers:
- name: grafana
image: docker.io/grafana/grafana:12.0.0
env:
- name: GF_SECURITY_ADMIN_USER
valueFrom:
secretKeyRef:
key: admin-user
name: vault-secrets
- name: GF_SECURITY_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
key: admin-password
name: vault-secrets
volumeMounts:
- mountPath: /opt/secrets/
name: grafana-secrets
readOnly: false
volumes:
- name: grafana-secrets
secret:
secretName: vault-secrets
ingress:
spec:
ingressClassName: nginx
rules:
- host: {{ .Values.grafana.ingress.host }}
http:
paths:
- backend:
service:
name: grafana-service
port:
number: 3000
path: /
pathType: Prefix
{{- end }}
Файл grafana-datasource.yaml
{{- if .Values.grafana.enabled -}}
{{- range .Values.grafana.datasources }}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: {{ .name }}
spec:
instanceSelector:
matchLabels:
dashboards: grafana
datasource:
access: {{ .access }}
type: {{ .type }}
name: {{ .datasourceName }}
url: {{ .url }}
{{- if .isDefault }}
isDefault: {{ .isDefault }}
{{- end }}
{{- if .jsonData }}
jsonData:
{{- range $index, $target := .jsonData}}
{{ $index }}: {{ $target }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
Файл grafana-folder.yaml
{{- if .Values.grafana.enabled -}}
{{- range .Values.grafana.folders }}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: {{ .name }}
namespace: {{ $.Release.Namespace }}
spec:
title: {{ .name }}
instanceSelector:
matchLabels:
dashboards: "grafana"
{{- if .parentFolder }}
parentFolderRef: {{ .parentFolder }}
{{- end }}
{{- if .permissions }}
permissions: |
{
"items": [
{{- range $index, $target := .permissions }}
{{- if $index }},{{ end }}
{
"role": "{{ .role }}",
"permission": {{ .permission }}
}
{{- end }}
]
}
{{- end }}
{{- end }}
{{- end }}
Конфигурация ресурса GrafanaDashboard из nodeexporter_dashboard.yaml
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: node-exporter
namespace: mon
spec:
folderRef: infra # директория из ресурса GrafanaFolder
instanceSelector:
matchLabels:
dashboards: "grafana" # лейбл, по которому grafana определяет дашборды, настраиваем в файле grafana-core
json: |
# ... здесь JSON дашборда или ссылка на файл
Настройка VMAuth
VMAuth — это прокси-сервер с функциями аутентификации, маршрутизации и балансировки нагрузки для системы мониторинга VictoriaMetrics. Он обеспечивает безопасный доступ к данным и распределяет нагрузку между серверами. Мы настраиваем его в extraObjects для аутентификации.
Секреты для пользователей тянутся из Vault.
Пример настройки доступа для компонентов VMSingle и VMAgent:
Конфигурация из lab_values.yaml
extraObjects:
- apiVersion: operator.victoriametrics.com/v1beta1
kind: VMAuth # Аутентификация для VM
metadata:
name: lab
namespace: mon
spec:
ingress:
annotations:
nginx.ingress.kubernetes.io/client-body-buffer-size: 2m
class_name: nginx
host: vmauth.lab.local
selectAllByDefault: true
- apiVersion: operator.victoriametrics.com/v1beta1
kind: VMUser # Пользователь для VMSingle
metadata:
name: admin-vmsingle
namespace: mon
spec:
username: admin
passwordRef:
name: vault-secrets
key: vmsingle-password
targetRefs:
- crd:
kind: VMSingle
# Имя `vmsingle-k8s` — пример; подставьте фактическое имя VMSingle в вашем кластере.
name: vmsingle-k8s
namespace: mon
paths: [ "/.*" ]
- apiVersion: operator.victoriametrics.com/v1beta1
kind: VMUser # Пользователь для VMAgent
metadata:
name: admin-vmagent
namespace: mon
spec:
username: admin-vmagent
passwordRef:
name: vault-secrets
key: vmagent-password
targetRefs:
- crd:
kind: VMAgent
# Имя `vmagent-k8s` — пример; подставьте фактическое имя VMAgent в вашем кластере.
name: vmagent-k8s
namespace: mon
paths: [ "/.*" ]
Чтобы helm распарсил extraObjects, создадим файл extraobjects.yaml в директории templates нашего целевого чарта.
Файл extraobjects.yaml
{{ range .Values.extraObjects }}
---
{{ tpl (toYaml .) $ }}
{{ end }}
Настройка x509-certificate-exporter
x509-certificate-exporter следит за сертификатами в кластере. Мы настраиваем его для control-plane-нод и worker-нод, чтобы мониторить файлы.
Конфигурация из lab_values.yaml
x509-certificate-exporter: # Экспортер для мониторинга сертификатов
hostPathsExporter:
daemonSets:
cp: # Для control-plane нод
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
watchFiles: # Пути расположения сертификатов k8s
- /var/lib/kubelet/pki/kubelet-client-current.pem
- /etc/kubernetes/pki/apiserver.crt
- /etc/kubernetes/pki/apiserver-etcd-client.crt
- /etc/kubernetes/pki/apiserver-kubelet-client.crt
- /etc/kubernetes/pki/ca.crt
- /etc/kubernetes/pki/front-proxy-ca.crt
- /etc/kubernetes/pki/front-proxy-client.crt
- /etc/kubernetes/pki/etcd/ca.crt
- /etc/kubernetes/pki/etcd/healthcheck-client.crt
- /etc/kubernetes/pki/etcd/peer.crt
- /etc/kubernetes/pki/etcd/server.crt
watchKubeconfFiles: # Kubeconfig файлы
- /etc/kubernetes/admin.conf
- /etc/kubernetes/controller-manager.conf
- /etc/kubernetes/scheduler.conf
nodes: # Для worker нод
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/ingress
operator: Exists
watchFiles: # Пути расположения сертификатов k8s
- /var/lib/kubelet/pki/kubelet-client-current.pem
- /etc/kubernetes/pki/ca.crt
Мониторинг внешних сервисов
Blackbox Exporter — это инструмент мониторинга, являющийся частью экосистемы Prometheus, предназначенный для проверки доступности и работоспособности сетевых сервисов.
Настроим blackbox-exporter.
Конфигурация из lab_values.yaml
prometheus-blackbox-exporter:
configExistingSecretName: "vault-secrets"
Сокращенный секрет blackbox.yaml из Vault
modules:
http_2xx:
prober: http
timeout: 30s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2", "HTTP/2.0"]
valid_status_codes: [200] # Defaults to 2xx
method: GET
no_follow_redirects: false
fail_if_ssl: false
fail_if_not_ssl: false
tls_config:
insecure_skip_verify: true
preferred_ip_protocol: "ip4" # defaults to "ip6"
VMProbe — это компонент VictoriaMetrics Operator, предназначенный для настройки конфигураций проб (проверок) целевых объектов с использованием blackbox exporter.
Файл lab_host.yaml
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMProbe
metadata:
name: lab
spec:
jobName: blackbox # Имя джобы VMAgent
vmProberSpec:
url: prometheus-blackbox-exporter.mon.svc.lab:9115 # URL к Blackbox Exporter
module: http_2xx # Модуль проверки (HTTP 2xx статус)
targets:
staticConfig:
labels: # Лейблы для метрик
module: http_2xx
project: lab
targets: # Список URL для проверки
- https://lab.test.local
interval: 15s
Установка чарта
Структура рабочей директории:
main/
charts/
grafana-operator-v0.0.0.tgz
prometheus-blackbox-exporter-0.0.0.tgz
victoria-metrics-k8s-stack-0.0.0.tgz
x509-certificate-exporter-0.0.0.tgz
templates/
configmap.yaml
extraobjects.yaml
grafana-core.yaml
grafana-datasource.yaml
grafana-folder.yaml
Chart.yaml
lab_values.yaml
files/
grafana-dashboards/
nodeexporter_dash.yaml
rules/
nodeexporter_rule.yaml
probes/
lab_host.yaml
# Установка чарта с именем 'monitoring' в namespace 'mon', используя values из lab_values.yaml
helm install monitoring . -n mon -f lab_values.yaml
# либо
helm upgrade -i monitoring . -n mon -f lab_values.yaml
Файлы из директории files/ применяем через kubectl apply -f ....
В продакшене мы используем Argo CD: у нас всё автоматизировано, ручного труда минимум — чего и вам советуем.
Заключение
Мы рассмотрели процесс установки и настройки стека мониторинга с VictoriaMetrics, но у каждого из вас наверняка есть свои секреты по настройке. Поделитесь в комментариях.
Интересно услышать мнение тех, кто перешёл с других систем мониторинга на VictoriaMetrics — поделитесь своим опытом миграции.
Обмен опытом — ключ к профессиональному росту!
