Полное и структурированное техническое решение, включающее описание задачи, архитектурную схему и все необходимые конфигурационные файлы.
Цель: Построить отказоустойчивую иерархическую систему мониторинга (федерацию) для сбора метрик из кластера Kubernetes и их долговременного хранения в двух независимых центральных дата-центрах. Бизнес-требования и ограничения:
- Изоляция и автономность: Кластер Kubernetes должен собирать и хранить метрики локально, оставаясь независимым от доступности центральных ЦОДов.
- Отказоустойчивость 1+1: Центральное хранилище развернуто в двух независимых ЦОДах (ЦОД-1 и ЦОД-2). Данные должны записываться в оба ЦОДа параллельно. При падении одного из них сбор и историчность данных не нарушаются.
- Безопасность: Доступ к метрикам из Kubernetes наружу должен осуществляться по протоколу Gateway API с обязательной базовой аутентификацией (Basic Auth).
- Полнота данных: С локального кластера необходимо забирать абсолютно все метрики без фильтрации на этапе отдачи, но с возможностью их постобработки (очистки от тестового мусора) на стороне центрального сборщика.
[ KUBERNETES CLUSTER ]
+-----------------------------------+
| |
| [vmagent (K8s)] |
| │ |
| │ |
| ▼ |
| [vminsert] |
| │ |
| │ |
| ▼ |
| [vmstorage (K8s)] |
| │ |
| │ |
| ▼ |
| [vmselect (K8s)] :8481 |
+─────────┬─────────────────────────+
│
│
▼ (внутренний трафик)
[HTTPRoute / Gateway API] (Авторизация: federation_user / secure_password)
│
▲ (скрапинг наружу через порт :80/:443)
│
┌──────────┴───────────────────────────────────────────────────────┐
│ [ ЦЕНТРАЛЬНЫЙ КОНТУР ] │
│ │
│ ┌────────────────────────┐ │
│ │ Глобальный [vmagent] │ │
│ │ (сборщик в ЦОДах) │ │
│ └───────────┬────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ ▼ (remote_write) ▼ (remote_write) │
│ [ ЦОД-1 (1) ] [ ЦОД-2 (+1) ] │
│ ┌───────────────────────┐ ┌───────────────────────┐ │
│ │ [vminsert] │ │ [vminsert] │ │
│ │ │ │ │ │ │ │
│ │ ▼ │ │ ▼ │ │
│ │ [vmstorage (ЦОД-1)] │ │ [vmstorage (ЦОД-2)] │ │
│ │ ▲ │ │ ▲ │ │
│ │ │ (чтение) │ │ │ (чтение) │ │
│ │ [vmselect] │ │ [vmselect] │ │
│ │ └─ флаг -dedup │ │ └─ флаг -dedup │ │
│ └───────────────────────┘ └───────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Сгенерируйте зашифрованную строку для Kubernetes Secret (логин: federation_user, пароль: secure_password):
echo -n "federation_user:$(openssl passwd -apr1 secure_password)" | base64
# Ожидаемый результат: ZmVkZXJhdGlvbl91c2VyOiRhcHIxJHBDU1R4S1ZDJFhEVmlvT1E4dnUzQmhvRHUveHNLMS8K
Этот манифест разворачивает локальный VMCluster через оператор, создает секрет авторизации, включает фильтр аутентификации для Gateway API и настраивает маршрут до компонента vmselect.
---
# https://docs.victoriametrics.com/operator/resources/vmcluster/
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMCluster
metadata:
name: k8s-local-cluster
namespace: monitoringspec:
vminsert:
replicaCount: 2
resources:
limits: { cpu: "2", memory: 4Gi }
requests: { cpu: "500m", memory: 1Gi }
vmselect:
replicaCount: 2
cacheMountPath: "/cache"
storage:
volumeClaimTemplate:
spec:
resources:
requests: { storage: 10Gi }
resources:
limits: { cpu: "2", memory: 4Gi }
vmstorage:
replicaCount: 2
retentionPeriod: "1" # Локально храним данные всего 1 месяц
storage:
volumeClaimTemplate:
spec:
resources:
requests: { storage: 100Gi }
resources:
limits: { cpu: "4", memory: 8Gi }
---
apiVersion: v1
kind: Secret
metadata:
name: federation-auth-secret
namespace: monitoringtype: Opaquedata:
# Base64 строка, полученная на этапе генерации
auth: ZmVkZXJhdGlvbl91c2VyOiRhcHIxJHBDU1R4S1ZDJFhEVmlvT1E4dnUzQmhvRHUveHNLMS8K
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: AuthenticationFiltermetadata:
name: basic-auth-filter
namespace: monitoringspec:
type: Basic
basic:
secretRef:
name: federation-auth-secret
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vmselect-federation-route
namespace: monitoringspec:
parentRefs:
- name: global-gateway # Имя вашего шлюза Gateway API в кластере
namespace: gateway-system # Неймспейс шлюза
hostnames:
- "k8s-metrics.company.local"
rules:
- matches:
- path:
type: Exact
value: /select/0/prometheus/federate
filters:
- type: ExtensionRef
extensionRef:
group: gateway.envoyproxy.io
kind: AuthenticationFilter
name: basic-auth-filter
backendRefs:
- name: vmselect-k8s-local-cluster # Имя сервиса, генерируемое VictoriaMetrics Operator автоматически
port: 8481
Этот конфигурационный файл указывает центральному сборщику забирать абсолютно все метрики через эндпоинт федерации Gateway API и на лету отсекать мусорные данные.
global:
scrape_interval: 30s
external_labels:
datacenter: "global_core"
scrape_configs:
- job_name: 'federation_k8s_gateway'
metrics_path: '/select/0/prometheus/federate'
honor_labels: true
# Пулл всех метрик без исключения
params:
'match[]':
- '{__name__=~".+"}'
# Авторизация для прохождения шлюза Gateway API
basic_auth:
username: "federation_user"
password: "secure_password"
static_configs:
- targets: ['k8s-metrics.company.local:80']
labels:
environment: 'k8s-prod-cluster'
# Тонкая фильтрация потока меток после забора всех данных
metric_relabel_configs:
# Исключаем метрики из тестовых стендов для экономии диска в ЦОДах
- source_labels: [namespace]
regex: '(dev|test|sandbox)'
action: drop
# Удаляем тяжелую техническую метку
- regex: 'image_id'
action: labeldrop
Если вы хотите фильтровать метрики прямо во время выборки (скрапинга) на уровне параметров match[], а не после загрузки в память, то синтаксис остается в рамках языка PromQL. Вы можете комбинировать имя метрики и любые лейблы внутри фигурных скобок прямо в параметре match[]. Ниже приведен обновленный пример конфигурации глобального vmagent.
При таком подходе vmagent отправит запрос к vmselect в K8s, и vmselect отдаст только те метрики, которые соответствуют указанным лейблам. Это значительно экономит сетевой трафик между Кубом и ЦОДами.
global:
scrape_interval: 30s
external_labels:
datacenter: "global_core"
scrape_configs:
- job_name: 'federation_k8s_gateway'
metrics_path: '/select/0/prometheus/federate'
honor_labels: true
# ФИЛЬТРАЦИЯ НА ЭТАПЕ ВЫБОРКИ (Запрос к vmselect):
params:
'match[]':
# Вариант 1: Забрать ВСЕ метрики, но только из определенного неймспейса
- '{namespace="production"}'
# Вариант 2: Забрать только метрики определенного приложения с конкретным окружением
- '{app="myapp", env="prod"}'
# Вариант 3: Использовать регулярные выражения (забрать из нескольких неймспейсов)
- '{namespace=~"(production|stage|infrastructure)"}'
# Вариант 4: Фильтр по имени метрики И по метке одновременно
# Забираем только CPU-метрики контейнеров, игнорируя всё остальное
- '{__name__=~"container_cpu_.*", container!=""}'
# Вариант 5: Исключение по метке (забрать всё, кроме метрик с лейблом tier="frontend")
- '{tier!="frontend"}'
basic_auth:
username: "federation_user"
password: "secure_password"
static_configs:
- targets: ['k8s-metrics.company.local:80']
labels:
environment: 'k8s-prod-cluster'
Docs: https://docs.victoriametrics.com/victoriametrics/url-examples/
curl 'http://<vmsingle>:8428/federate' -d 'match[]=vm_http_request_errors_total'
curl 'http://<vmselect>:8481/select/0/prometheus/federate' -d 'match[]=vm_http_request_errors_total'
- Фильтрация в params (match[]) [Pull-фильтр]:
- Как работает: vmagent просит у vmselect только то, что написано в блоке.
- Плюсы: Минимальный сетевой трафик. vmselect в Кубе сам отсекает лишнее и отдает наружу компактный ответ.
- Минусы: Нельзя сделать сложные трансформации (переименовать метку, удалить конкретный лейбл из метрики).
- Фильтрация в metric_relabel_configs [Пост-фильтр]:
- Как работает: vmagent выкачивает вообще всё, а затем локально в своей памяти дропает ненужное.
- Плюсы: Можно гибко модифицировать структуру метрик, переименовывать лейблы и комбинировать их.
- Минусы: Нагрузка на сеть, так как из Куба в ЦОД изначально летят «сырые» гигабайты данных.
При запуске бинарного файла vmagent на серверах сбора в ЦОДах передаются флаги для дублирования потока данных в обе инсталляции:
/usr/local/bin/vmagent \
-config=/etc/vmagent/vmagent.yml \
-remoteWrite.url=http://company.local \
-remoteWrite.url=http://company.local \
-remoteWrite.tmpDataPath=/var/lib/vmagent/tmp
*Параметр -remoteWrite.tmpDataPath критически важен: если один из ЦОДов уйдет в оффлайн, агент начнет буферизировать данные на диск и дошлет их сразу после восстановления сети.
Для предотвращения дублирования графиков при отображении в Grafana из двух идентичных источников, каждый центральный vmselect в обоих ЦОДах запускается с флагом дедупликации:
-dedup.minScrapeInterval=30s
Вот полный практический пример для Шага 1 (настройка локального vmagent, который будет собирать метрики с локальных целей и отдавать их наружу для центрального сервера по pull-модели). В этом примере настроим vmagent так, чтобы он собирал метрики с самого себя и с локального node_exporter, сохранял их и ждал, пока центральный сервер заберет данные.
Создайте конфигурационный файл для vmagent, где укажите, откуда ему локально забирать метрики:
global:
scrape_interval: 15s # Как часто vmagent собирает метрики локально
scrape_configs:
# Задача 1: Сбор метрик производительности самого vmagent
- job_name: 'vmagent-local'
static_configs:
- targets: ['localhost:8429']
# Задача 2: Сбор системных метрик ОС (если запущен node_exporter)
- job_name: 'node-exporter-local'
static_configs:
- targets: ['localhost:9100']
Самый быстрый способ развернуть агент с открытым портом наружу:
docker run -d \
--name=vmagent-federation \
-p 8429:8429 \
-v $(pwd)/vmagent.yml:/etc/vmagent.yml \
victoriametrics/vmagent:v1.101.0 \
-promscrape.config=/etc/vmagent.yml \
-remoteWrite.tmpDataPath=/tmp/vmagent-cache
Параметр -remoteWrite.tmpDataPath обязателен, так как vmagent будет кэшировать собранные данные в этой директории, пока их кто-нибудь не заберет или пока не настроен remote write.
Если вы устанавливаете vmagent как бинарный файл, отредактируйте его unit-файл (обычно /etc/systemd/system/vmagent.service):
[Unit]
Description=VictoriaMetrics Agent
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/usr/local/bin/vmagent \
-promscrape.config=/etc/vmagent/vmagent.yml \
-httpListenAddr=0.0.0.0:8429 \
-remoteWrite.tmpDataPath=/var/lib/vmagent/cache
Restart=always
[Install]
WantedBy=multi-user.target
После создания файла выполните:
systemctl daemon-reload
systemctl enable --now vmagent
Чтобы убедиться, что vmagent успешно запустился, собирает метрики и готов отдавать их центральному серверу, выполните команду curl с любого доверенного сервера в сети (или локально):
- Проверить статус здоровья:
curl http://<IP_АДРЕС_VMAGENT>:8429/-/healthy# Ответ должен быть: VictoriaMetrics is Healthy
- Проверить эндпоинт федерации (доступность данных):
curl -G 'http://<IP_АДРЕС_VMAGENT>:8429/api/v1/federate' --data-urlencode 'match[]={job="vmagent-local"}'

