Инструменты VictoriaMetrics#

Настройка и использование VictoriaMetrics#

VictoriaMetrics - это система мониторинга и управления производительностью, которая позволяет отслеживать и анализировать метрики, события и журналы приложений и инфраструктуры. Предоставляет инструменты для визуализации данных, создания уведомлений и автоматического реагирования на проблемы. VictoriaMetrics может быть интегрирована с различными системами и инструментами, такими как Prometheus, Grafana и другими, что позволяет собирать и анализировать данные из различных источников.

VictoriaMetrics может быть установлена с помощью VictoriaMetrics-operator, который упрощает установку, масштабирование и обновление экземпляров VictoriaMetrics в кластере DropApp.

VictoriaMetrics предоставляет следующие инструменты:

  • vmctl - утилита командной строки, которая позволяет управлять компонентами VictoriaMetrics, такими как создание, удаление и обновление nodes, хранения данных, а также управление агентами сбора данных;

  • vmrestore - утилита командной строки, которая позволяет восстановить данные из резервной копии VictoriaMetrics;

  • vmauth - утилита командной строки, которая позволяет управлять аутентификацией и авторизацией в VictoriaMetrics;

  • vmagent - агент сбора данных, который устанавливается на хостах или серверах, откуда необходимо собирать метрики и события;

  • vmalert - утилита командной строки, которая позволяет управлять оповещениями в VictoriaMetrics;

  • vmbackup - утилита командной строки, которая позволяет создавать резервные копии данных VictoriaMetrics.

Сценарии использования VictoriaMetrics#

VictoriaMetrics#

Для выполнения данного сценария необходимы права администратора, а также установленный Helm.

  1. Добавьте репозиторий VictoriaMetrics для установки компонентов, выполнив команду:

    Copyhelm repo add vm https://<repoexample.ru>/helm-charts/
    # Укажите актуальный путь до локального репозитория
    
  2. Обновите репозиторий Helm:

    Copyhelm repo update
    
  3. Проверьте корректность настроек, введите команду:

    Copyhelm search repo vm/
    

    Вывод будет следующим:

    NAME                           CHART           VERSION     APP VERSION DESCRIPTION                                       
    vm/victoria-metrics-agent      0.7.20        v1.87.6     Victoria Metrics Agent - collects metrics from ...
    vm/victoria-metrics-alert      0.3.34        v1.87.6     Victoria Metrics Alert - executes a list of giv...
    vm/victoria-metrics-auth       0.2.23        v1.87.6       Victoria Metrics Auth - is a simple auth proxy ...
    vm/victoria-metrics-cluster    0.8.32        v1.87.6       Victoria Metrics Cluster version - high-perform...
    vm/victoria-metrics-k8s-stack  0.2.9         v1.87.6       Kubernetes monitoring on VictoriaMetrics stack....
    vm/victoria-metrics-operator   0.1.17        0.32.0      Victoria Metrics Operator                         
    vm/victoria-metrics-single     0.7.5         v1.87.6     Victoria Metrics Single version - high-performa...
    
  4. Установите кластер VictoriaMetricss с помощью Helm. Для переопределения образов для Helm можно использовать флаг --set в команде helm install:

       cat <<EOF | helm install vmcluster vm/victoria-metrics-cluster -f -
    vmselect:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8481"
    
    vminsert:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8480"
    
    vmstorage:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8482"
    EOF
    

    Запуск команды helm install vmcluster vm/victoria-metrics-cluster устанавливает кластер VictoriaMetrics в namespace по умолчанию внутри созданного кластера.

    Команда podAnnotations: prometheus.io/scrape: "true" и podAnnotations:prometheus.io/port: "some_port" запускает сбор метрик из pod vmselect, vminsert и vmstorage и из их портов.

    Вывод будет следующим:

    NAME: vmcluster
    LAST DEPLOYED: Thu Jun  1 09:41:57 2023
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    Write API:
    

    Примечание

    Все образы в манифестах пользователей будут содержать информацию из registry DropApp.

  5. Получите URL-адрес службы вставки vminsert VictoriaMetrics, выполнив команды:

    export POD_NAME=$(kubectl get pods --namespace default -l "app=vminsert" -o jsonpath="{.items[0].metadata.name}")
      kubectl --namespace default port-forward $POD_NAME 8480
    
  6. Обновите файл конфигурации Prometheus и добавьте в него следующие строки:

    prometheus.yml
        remote_write:
          - URL: "http://<insert-service>/insert/0/prometheus/"
    
  7. Получите доступ к API VictoriaMetrics через порт 8481 со следующим DNS-именем из кластера:

    vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local
    
  8. Получите URL-адрес службы VictoriaMetrics, выполнив команду:

    export POD_NAME=$(kubectl get pods --namespace default -l "app=vmselect" -o jsonpath="{.items[0].metadata.name}")
    kubectl --namespace $POD_NAME 8481
    
  9. Укажите URL-адрес службы в Grafana:

    Примечание

    В качестве источника данных необходимо выбрать Prometheus.

    Введите это поле URL в Grafana:

    http://<select-service>/select/0/prometheus/
    
  10. Убедитесь, что pods кластера VictoriaMetrics запущены и работают, выполнив следующую команду:

    kubectl get pods
    

    Вывод будет следующим:

    NAME                                                           READY   STATUS    RESTARTS   AGE
    vmcluster-victoria-metrics-cluster-vminsert-689cbc8f55-95szg   1/1     Running   0          16m
    vmcluster-victoria-metrics-cluster-vminsert-689cbc8f55-f852l   1/1     Running   0          16m
    vmcluster-victoria-metrics-cluster-vmselect-977d74cdf-bbgp5    1/1     Running   0          16m
    vmcluster-victoria-metrics-cluster-vmselect-977d74cdf-vzp6z    1/1     Running   0          16m
    vmcluster-victoria-metrics-cluster-vmstorage-0                 1/1     Running   0          16m
    vmcluster-victoria-metrics-cluster-vmstorage-1                 1/1     Running   0          16m
    
  11. Установите vmagent из Helm, выполните следующую команду:

    helm install vmagent vm/victoria-metrics-agent -f https://<repoexample.ru>.ru/guides/victoriametrics.yaml
    # Укажите актуальный путь до локального репозитория
    

    Полное содержание файла victoriametrics.yaml:

    victoriametrics.yaml
    remoteWriteUrls: http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/
    
       config:
         global:
           scrape_interval: 10s
    
         scrape_configs:
           - job_name: vmagent
             static_configs:
               - targets: ["localhost:8429"]
           - job_name: "kubernetes-api-servers"
             kubernetes_sd_configs:
               - role: endpoints
             scheme: HTTPs
             tls_config:
               ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
               insecure_skip_verify: true
             bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
             relabel_configs:
               - source_labels:
                   [
                     __meta_kubernetes_namespace,
                     __meta_kubernetes_service_name,
                     __meta_kubernetes_endpoint_port_name,
                   ]
                 action: keep
                 regex: default;kubernetes;HTTPs
           - job_name: "kubernetes-nodes"
             scheme: HTTPs
             tls_config:
               ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
               insecure_skip_verify: true
             bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
             kubernetes_sd_configs:
               - role: node
             relabel_configs:
               - action: labelmap
                 regex: __meta_kubernetes_node_label_(.+)
               - target_label: __address__
                 replacement: kubernetes.default.svc:443
               - source_labels: [__meta_kubernetes_node_name]
                 regex: (.+)
                 target_label: __metrics_path__
                 replacement: /api/v1/nodes/$1/proxy/metrics
           - job_name: "kubernetes-nodes-cadvisor"
             scheme: HTTPs
             tls_config:
               ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
               insecure_skip_verify: true
             bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
             kubernetes_sd_configs:
               - role: node
             relabel_configs:
               - action: labelmap
                 regex: __meta_kubernetes_node_label_(.+)
               - target_label: __address__
                 replacement: kubernetes.default.svc:443
               - source_labels: [__meta_kubernetes_node_name]
                 regex: (.+)
                 target_label: __metrics_path__
                 replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
             metric_relabel_configs:
               - action: replace
                 source_labels: [pod]
                 regex: '(.+)'
                 target_label: pod_name
                 replacement: '${1}'
               - action: replace
                 source_labels: [container]
                 regex: '(.+)'
                 target_label: container_name
                 replacement: '${1}'
               - action: replace
                 target_label: name
                 replacement: k8s_stub
               - action: replace
                 source_labels: [id]
                 regex: '^/system\.slice/(.+)\.service$'
                 target_label: systemd_service_name
                 replacement: '${1}'
           - job_name: "kubernetes-service-endpoints"
             kubernetes_sd_configs:
               - role: endpoints
             relabel_configs:
               - action: drop
                 source_labels: [__meta_kubernetes_pod_container_init]
                 regex: true
               - action: keep_if_equal
                 source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_scrape]
                 action: keep
                 regex: true
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_scheme]
                 action: replace
                 target_label: __scheme__
                 regex: (HTTPs?)
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_path]
                 action: replace
                 target_label: __metrics_path__
                 regex: (.+)
               - source_labels:
                   [
                     __address__,
                     __meta_kubernetes_service_annotation_prometheus_io_port,
                   ]
                 action: replace
                 target_label: __address__
                 regex: ([^:]+)(?::\d+)?;(\d+)
                 replacement: $1:$2
               - action: labelmap
                 regex: __meta_kubernetes_service_label_(.+)
               - source_labels: [__meta_kubernetes_namespace]
                 action: replace
                 target_label: kubernetes_namespace
               - source_labels: [__meta_kubernetes_service_name]
                 action: replace
                 target_label: kubernetes_name
               - source_labels: [__meta_kubernetes_pod_node_name]
                 action: replace
                 target_label: kubernetes_node
           - job_name: "kubernetes-service-endpoints-slow"
             scrape_interval: 5m
             scrape_timeout: 30s
             kubernetes_sd_configs:
               - role: endpoints
             relabel_configs:
               - action: drop
                 source_labels: [__meta_kubernetes_pod_container_init]
                 regex: true
               - action: keep_if_equal
                 source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow]
                 action: keep
                 regex: true
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_scheme]
                 action: replace
                 target_label: __scheme__
                 regex: (HTTPs?)
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_path]
                 action: replace
                 target_label: __metrics_path__
                 regex: (.+)
               - source_labels:
                   [
                     __address__,
                     __meta_kubernetes_service_annotation_prometheus_io_port,
                   ]
                 action: replace
                 target_label: __address__
                 regex: ([^:]+)(?::\d+)?;(\d+)
                 replacement: $1:$2
               - action: labelmap
                 regex: __meta_kubernetes_service_label_(.+)
               - source_labels: [__meta_kubernetes_namespace]
                 action: replace
                 target_label: kubernetes_namespace
               - source_labels: [__meta_kubernetes_service_name]
                 action: replace
                 target_label: kubernetes_name
               - source_labels: [__meta_kubernetes_pod_node_name]
                 action: replace
                 target_label: kubernetes_node
           - job_name: "kubernetes-services"
             metrics_path: /probe
             params:
               module: [HTTP_2xx]
             kubernetes_sd_configs:
               - role: service
             relabel_configs:
               - source_labels:
                   [__meta_kubernetes_service_annotation_prometheus_io_probe]
                 action: keep
                 regex: true
               - source_labels: [__address__]
                 target_label: __param_target
               - target_label: __address__
                 replacement: blackbox
               - source_labels: [__param_target]
                 target_label: instance
               - action: labelmap
                 regex: __meta_kubernetes_service_label_(.+)
               - source_labels: [__meta_kubernetes_namespace]
                 target_label: kubernetes_namespace
               - source_labels: [__meta_kubernetes_service_name]
                 target_label: kubernetes_name
           - job_name: "kubernetes-pods"
             kubernetes_sd_configs:
               - role: pod
             relabel_configs:
               - action: drop
                 source_labels: [__meta_kubernetes_pod_container_init]
                 regex: true
               - action: keep_if_equal
                 source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
               - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
                 action: keep
                 regex: true
               - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
                 action: replace
                 target_label: __metrics_path__
                 regex: (.+)
               - source_labels:
                   [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
                 action: replace
                 regex: ([^:]+)(?::\d+)?;(\d+)
                 replacement: $1:$2
                 target_label: __address__
               - 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
    

    Где remoteWriteUrls: - http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/ настраивает vmagent для записи очищенных метрик в файл vmselect service.

    Вторая часть этого yaml-файла добавляет раздел metric_relabel_configs, выводит метрики на панели управления Grafana.

  12. Выполните команду и убедитесь, что vmagent запущен:

    kubectl get pods | grep vmagent
    

    Вывод отобразит следующее:

    vmagent-victoria-metrics-agent-69974b95b4-mhjph                1/1     Running   0          11m
    
  13. Добавьте репозиторий Grafana:

    Copyhelm repo add grafana https://<repoexample.ru>/helm-charts
    helm repo update
    # Укажите актуальный путь до локального репозитория
    
  14. Добавьте источник данных VictoriaMetrics с названием релиза my-grafana:

my-grafana.yaml
   cat <<EOF | helm install my-grafana grafana/grafana -f -
datasources:
   datasources.yaml:
      apiVersion: 1
      datasources:
      - name: victoriametrics
         type: prometheus
         orgId: 1
         url: http://vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local:8481/select/0/prometheus/
         access: proxy
         isDefault: true
         updateIntervalSeconds: 10
         editable: true

dashboardProviders:
   dashboardproviders.yaml:
   apiVersion: 1
   providers:
   - name: 'default'
      orgId: 1
      folder: ''
      type: file
      disableDeletion: true
      editable: true
      options:
         path: /var/lib/grafana/dashboards/default

dashboards:
   default:
      victoriametrics:
      gnetId: 11176
      revision: 18
      datasource: victoriametrics
      vmagent:
      gnetId: 12683
      revision: 7
      datasource: victoriametrics
      kubernetes:
      gnetId: 14205
      revision: 1
      datasource: victoriametrics
EOF

В результате применения манифеста выполнена следующая последовательность:

* установлена **Grafana** из репозитория **Helm**;
* подготовлен источник данных **VictoriaMetrics** с URL-адресом из шага 4;
* добавлена информационная панель **VictoriaMetrics**: `https://<repoexample.ru>m/grafana/dashboards/11176-victoriametrics-cluster/`;
* добавлена информационная панель для агента **VictoriaMetrics**: `https://<repoexample.ru>/grafana/dashboards/12683-victoriametrics-vmagent/`;
* добавлена панель мониторинга для наблюдения метрик кластера DropApp: `https://<repoexample.ru>/grafana/dashboards/14205-kubernetes-cluster-monitoring-via-prometheus/`.

15. Просмотрите журнал вывода, скопируйте, вставьте и запустите адреса из шага 14.
16. Чтобы получить пароль администратора **Grafana**, выполните команду:

~~~bash
kubectl get secret --namespace default my-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
~~~

18. Сохраните пароль в файл на компьютере.

19. Чтобы получить доступ к сервису **Grafana** в веб-браузере, выполните следующую команду:

~~~bash
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=my-grafana" -o jsonpath="{.items[0].metadata.name}")
~~~

20. Используйте команду для прослушивания порта `3000` на pod с именем, указанным в переменной окружения `POD_NAME`:

~~~bash
kubectl --namespace default port-forward $POD_NAME 3000
~~~

21. Откройте в браузере `http://127.0.0.1:3000/dashboards` и выберите панель мониторинга `Cluster Monitoring (via Prometheus)`. Используйте логин `admin` для входа и пароль который был получен в шаге 15.

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

## VictoriaMetrics-operator

**VictoriaMetrics-operator** - инструмент для управления конфигурацией мониторинга приложений в DropApp. У **VictoriaMetrics-operator** есть возможности API.

Существует поддержка CRD (Custom Resource Definition) **VictoriaMetrics**:

* `VMServiceScrape` - определяет конфигурацию метрик извлечения из модулей, поддерживаемых сервисами;
* `VMPodScrape` - определяет конфигурацию извлечения метрик из pods;
* `VMRule` - определяет правила оповещения или записи;
* `VMProbe` - отслеживает состояние виртуальных машин, таких как загрузка процессора, использование памяти и дискового пространства. `VMProbe` также может использоваться для установки и настройки сетевых интерфейсов и управления питанием виртуальных машин.

**VictoriaMetrics-operator** управляет приложениями **VictoriaMetrics** внутри кластера DropApp и упрощает быстрый запуск этого процесса. С помощью CRD определите конфигурацию приложения и примените ее к CRD-объектам кластера.

**VictoriaMetrics-operator** имеет возможность делегировать настройку мониторинга приложений конечным пользователям.

Определите конфигурацию очистки метрик и предупреждений `app_deployment.yaml`, `app_vmpodscrape.yaml` и `app_vmrule.yaml`, примените их к кластеру DropApp:

1. Определите ресурсы:

~~~bash
kubectl apply -f release/crds
~~~

2. Создайте RBAC для оператора, соответствующую конфигурацию для выпуска можно найти в файле `release/operator/rbac.yaml`. Этот файл описывает роль пользователя DropApp, который предоставляет RBAC, управление доступом на основе ролей для ресурсов DropApp.
3. Измените конфигурацию для **VictoriaMetrics-operator** в `release/operator/manager.yaml` и примените, используя команду:

~~~bash
kubectl apply -f release/operator/manager.yaml
~~~

4. Проверьте статус оператора:

~~~bash
kubectl get pods -n monitoring-system
~~~

Вывод будет следующим:

 ~~~bash
 NAME                           READY   STATUS    RESTARTS   AGE
 vm-operator-667dfbff55-cbvkf   1/1     Running   0          1s
 ~~~

Вывод отображает информацию о состоянии виртуальной машины. Каждый столбец представляет собой определенную характеристику виртуальной машины:

 * `NAME` - имя виртуальной машины;
 * `READY` - статус готовности виртуальной машины. В данном случае, значение `1` означает, что виртуальная машина готова к использованию;
 * `STATUS` - текущее состояние виртуальной машины. В этом случае значение `Running` означает, что виртуальная машина работает;
 * `RESTARTS` - количество раз, когда виртуальная машина была перезапущена. В данном случае значение `0` означает, что перезапусков не было;
 * `AGE` - время, прошедшее с момента создания виртуальной машины. В данном случае это значение 1s (1 секунда), так как виртуальная машина была создана только что.

## VictoriaMetrics-cluster

**VictoriaMetrics-cluster** - это система мониторинга и управления событиями, которая позволяет собирать, хранить и анализировать метрики и события из различных источников.

**VictoriaMetrics-cluster** состоит из следующих сервисов:

* `vmstorage` — сохраняет необработанные данные и возвращает запрошенные данные в заданном диапазоне времени для заданных фильтров меток;
* `vminsert` — принимает полученные данные и распределяет их между nodes `vmstorage` в соответствии с последовательным хешированием имени метрики и всех ее меток;
* `vmselect` — выполняет входящие запросы, извлекая необходимые данные со всех настроенных nodes `vmstorage`.

## Config-reloader

**Config-reloader** — это альтернативная версия `prometheus-config-reloaded`. Основное отличие заключается в возможности считывать `Secret` напрямую из DropApp и записывать его в локальную файловую систему. Это ускоряет процесс перезагрузки конфигурации и делает его более предсказуемым.

### Синхронизация конфигурации

#### Основные понятия

Приложения **VictoriaMetrics**, как и многие другие приложения с файлом конфигурации, развернутые в Kubernetes, используют `ConfigMaps` и `Secrets` для файлов конфигурации. Обычно приложения не отслеживают изменений конфигурации. Приложения перезагружают свою конфигурацию по сигналу от пользователя или другого инструмента, который умеет следить за обновлениями. В Kubernetes для этого случая наиболее популярным решением является sidecar-контейнер, который следит за изменениями конфигурационного файла и отправляет HTTP-запрос приложению.

`Configmap` или `Secret`, установленный в pod, хранит копию его содержимого. Компонент **Kubelet**, входящий в DropApp, отвечает за синхронизацию содержимого между объектом в Kubernetes API и файлом на диске. Синхронизировать содержимое сразу неэффективно, и **Kubelet** со временем синхронизирует его. Существует конфигурационная опция, которая управляет этим периодом.

Поэтому приложения, управляемые оператором, получают изменения не сразу. Обычно проходит 1-2 минуты, прежде чем содержимое будет обновлено.

Могут возникать ошибки, когда приложение было удалено, но `vmagent` все равно пытается его отсканировать.

#### Включение config-reloader

Решение таких ошибок — уменьшение периода синхронизации. Оно настраивается глобально и может быть сложным для пользователя.

Для обновления `Configmap` оператор изменяет аннотацию со временем обновления содержимого `Configmap`. Это немедленно запускает синхронизацию содержимого `ConfigMap` агентом **Kubelet**. Это касается `vmalert`, он использует `ConfigMap` в качестве источника конфигурации.

Однако это не работает для `Secret`. Оператор предлагает свою реализацию для sidecar-контейнера. Его можно настроить с помощью переменной `env` для оператора:

~~~yaml
- name: VM_USECUSTOMCONFIGRELOADER
value: "true"
~~~

Если это условие задано, оператор использует свой собственный `Config-reloader` вместо `prometheus-config-reload`.

Он отслеживает изменения в соответствующем `Secret` с помощью Kubernetes API, отслеживает вызовы и записывает содержимое в `emptyDir`. Этот пустой каталог используется совместно с приложением. В случае изменений содержимого `config-reloader` отправляет HTTP-запросы в приложение. Это значительно сокращает время синхронизации конфигурации.

Для включения `config-reloader` добавьте в команду на запуск контейнера в манифесте компонентов **VictoriaMetrics**:

~~~yaml
containers:
- name: config-reloader
command:
  - /usr/local/bin/config-reloader
~~~