Подключение и конфигурирование#

Перед началом работы с Единым коллектором ваш проект должен быть зарегистрирован в Abyss. Доступ к Push API Единого коллектора осуществляется по технологии API-key. Ключ выдается администраторами Abyss. После получения ключа можно обращаться к Push API Единого коллектора передавая ключ в заголовке X-PVM-API-KEY. Также необходимо настроить Egress на клиенте для исходящего трафика на Push API Единого коллектора. Также в конфигурации Push Collector параметр AUTHENTICATION_ENABLED должен быть выставлен, как true.

Сбор Prometheus метрик: Настройка Prometheus агентов (Unimon-agent) в клиентском NameSpace#

Все примеры приведены на базе сбора собственных метрик/логов/трассировок!

Чтобы обеспечить сбор прикладных метрик, приложение должно выставить метрики через HTTP-endpoint, например, /metrics (путь может быть любым). Prometheus-agent (или unimon-agent) находит HTTP-endpoint, собирает и обогащает метрики, а затем передает их в приложение. Данные предоставляются в формате Actuator Prometheus. Prometheus читает секцию конфигурации scrape_configs, согласно которой настраивает свой внутренний механизм обнаружения сервисов (Service Discovery). Механизм Service Discovery взаимодействует с Kubernetes API (в основном для получения endpoints). На основании данных из Kubernetes механизм Service Discovery обновляет Targets (список целей).

Структура конфигурации:

global:
  # How frequently to scrape targets by default.
  [ scrape_interval: <duration> | default = 1m ]

  # How long until a scrape request times out.
  [ scrape_timeout: <duration> | default = 10s ]

  # How frequently to evaluate rules.
  [ evaluation_interval: <duration> | default = 1m ]

  # The labels to add to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    [ <labelname>: <labelvalue> ... ]

  # File to which PromQL queries are logged.
  # Reloading the configuration will reopen the file.
  [ query_log_file: <string> ]

# A list of scrape configurations.
scrape_configs:
  [ - <scrape_config> ... ]

# Settings related to the remote write feature.
remote_write:
  [ - <remote_write> ... ]

Global секция определяет параметры, которые действительны во всех других контекстах конфигурации. Они также служат значениями по умолчанию для других разделов конфигурации.

Секция scrape_config определяет список заданий сбора.

Секция relabel_configs позволяет добавлять настройки «фильтрации» - какие endpoints будет брать, а какие — нет, и "relabeling" - какие лейблы добавить или удалить (для всех получаемых метрик). Конфигурация Service discovery Kubernetes определяется в секции kubernetes_sd_configs.

Секция remote_write определяет URL-адрес endpoint, на который отправляются метрики.

Подробная структура описана на странице конфигурации Prometheus.

Пример конфигурации Prometheus-агента (фактически в scrape_configs нужно оставить kubernetes-pods и kubernetes-pods-https и далее задать endpoint).

kind: ConfigMap
apiVersion: v1
metadata:
  name: unimon-agent-config.r4
  labels:
    app: unimon-agent
data:
  prometheus.yml: |-
    global:
        scrape_interval: %GLOBAL_SCRAPE_INTERVAL%
        scrape_timeout: %GLOBAL_SCRAPE_TIMEOUT%
    scrape_configs:
        - job_name: 'kubernetes-pods'
          kubernetes_sd_configs:
            - role: endpoints
              namespaces:
                names:
                  - "ci02707148-idevgen-audit-mmv"
          relabel_configs:
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
              regex: true
              action: keep
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
              regex: (.+)
              target_label: __metrics_path__
              action: replace
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
              action: drop
              regex: https
            - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
              action: replace
              target_label: __address__
              regex: ([^:]+)(?::\d+)?;(\d+)
              replacement: $1:$2
            - source_labels: [__meta_kubernetes_namespace]
              separator: ;
              regex: (.*)
              target_label: namespace
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_pod_name]
              separator: ;
              regex: (.*)
              target_label: pod
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_service_name]
              separator: ;
              regex: (.*)
              target_label: service
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_pod_node_name]
              separator: ;
              regex: (.*)
              target_label: nodeName
              replacement: $1
              action: replace
            - action: labelmap
              regex: __meta_kubernetes_pod_label_(.+)
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: unimonVersion
              action: replace
              replacement: "D-04.000.00-2373_client"
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: tenant
              action: replace
              replacement: "undefined"
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: source
              action: replace
              replacement: OpenShift
        - job_name: 'kubernetes-pods-https'
          scheme: https
          tls_config:
            ca_file: /etc/prom-certs/root-cert.pem
            cert_file: /etc/prom-certs/cert-chain.pem
            key_file: /etc/prom-certs/key.pem
            insecure_skip_verify: true
          kubernetes_sd_configs:
            - role: endpoints
              namespaces:
                names:
                  - "ci02707148-idevgen-audit-mmv"
          relabel_configs:
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
              regex: true
              action: keep
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
              regex: (.+)
              target_label: __metrics_path__
              action: replace
            - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
              action: keep
              regex: https
            - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
              action: replace
              target_label: __address__
              regex: ([^:]+)(?::\d+)?;(\d+)
              replacement: $1:$2
            - source_labels: [__meta_kubernetes_namespace]
              separator: ;
              regex: (.*)
              target_label: namespace
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_pod_name]
              separator: ;
              regex: (.*)
              target_label: pod
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_service_name]
              separator: ;
              regex: (.*)
              target_label: service
              replacement: $1
              action: replace
            - source_labels: [__meta_kubernetes_pod_node_name]
              separator: ;
              regex: (.*)
              target_label: nodeName
              replacement: $1
              action: replace
            - action: labelmap
              regex: __meta_kubernetes_pod_label_(.+)
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: unimonVersion
              action: replace
              replacement: "D-04.000.00-2373_client"
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: tenant
              action: replace
              replacement: "undefined"
            - source_labels: [__address__]
              separator: ;
              regex: (.*)
              target_label: source
              action: replace
              replacement: OpenShift
    remote_write:
      - url: "http://{host}:{port}/push/project/{projectName}/pipeline/{pipelineName}/prometheus-proto"

, где http://{host}:{port}/push/project/{projectName}/pipeline/{pipelineName}/prometheus-proto - это http-endpoint push-коллектора для отправки метрик, {projectName} - имя проекта, используемого для сбора данных, {pipelineName} - имя pipeline.

Конфигурация pipeline для импорта:

{
  "quota": {
    "limitTrafficPerMin": 10000
  },
  "name": "self-monitoring-pipe",
  "input": {
    "typeName": "standard-http-api",
    "config": "{}"
  },
  "processors": [
    {
      "typeName": "prometheus-unimon-converter",
      "config": "{\"allowNan\": false, \"required\": false, \"headersToEnrich\": []}",
      "order": 1
    },
    {
      "typeName": "jackson-mapper-processor",
      "config": "{}",
      "order": 2
    },
    {
      "typeName": "pipeline-data-enrichment-processor",
      "config": "{}",
      "order": 3
    },
    {
      "typeName": "json-flattener-processor",
      "config": "{\"flattenMode\": \"KEEP_ARRAYS\", \"standardFlatteningForFieldsWithDots\": false}",
      "order": 4
    }
  ],
  "outputs": [
    {
      "typeName": "kafka-output",
      "config": "{\"acks\": -1, \"topic\": \"METRICS_TOPIC_NAME\", \"clientId\": \"cidddd\", \"lingerMs\": 0, \"batchSize\": 16384, \"maxBlockMs\": 60000, \"keySerializer\": \"org.apache.kafka.common.serialization.StringSerializer\", \"sslClientAuth\": false, \"requestTimeout\": 30000, \"deliveryTimeout\": 120000, \"valueSerializer\": \"org.springframework.kafka.support.serializer.JsonSerializer\", \"bootstrapServers\": \"KAFKA_ADDRESS_AND_PORT\", \"securityProtocol\": \"SSL\", \"idempotenceEnabled\": true, \"sslEnabledProtocols\": \"TLSv1.2\", \"maxInFlightRequestsPerConnection\": 5, \"sslEndpointIdentificationAlgorithm\": \"https\"}"
    }
  ]
}

, где METRICS_TOPIC_NAME - это имя топика Apache Kafka для записи метрик (подробнее о создании в Руководстве оператора, инструкция поставляется в рамках компонента Abyss (LGDB) в составе продукта Platform V Monitor),

Подробнее о создании/получении/редактировании паролей смотрите в документации API /configuration/identifiable-entity/password/.

KAFKA_ADDRESS_AND_PORT - список bootstrap серверов Apache Kafka Abyss (эта информация должна быть известна Администраторам PVM).

Сбор логов: настройка FluentBit агента#

Логи приложений записываются в файл в формате JSON и в лог в обычном формате.

На файлы логов подписан FluentBit Sidecar, который отправляет логи дальше по pipeline.

Конфигурация FluentBit, носит информативный характер:

[SERVICE]
   Flush        1
   Daemon       Off
   Parsers_File /fluent-bit/etc/parsers.conf
   HTTP_Server  On
   HTTP_Listen  0.0.0.0
   HTTP_PORT    8085
[INPUT]
   Name tail
   Tag file.tail
   Path /fluent-bit/etc/logs/*.json
   Mem_Buf_Limit 10MB
   Skip_Long_Lines On
   Refresh_Interval 2
   Rotate_Wait 1
   Read_from_Head Off
   DB /fluent-bit/etc/logs/kube.db
   Parser custom
[OUTPUT]
   Name stdout
   Match *
[OUTPUT]
   Name             http
   Match            file.tail
   Host             telemetry-collector-push-service
   Port             8083
   URI              /push/project/{projectName}/pipeline/{pipelineName}
   Format           json

, где OUTPUT - это настройка вывода логов до Apache Kafka через единый коллектор, {projectName} - имя проекта, используемого для сбора данных, {pipelineName} - имя pipeline.

Конфигурация pipeline для импорта:

  1. Pipeline для обработки всех логов

{
  "quota": {
    "limitTrafficPerMin": 10000
  },
  "name": "PIPELINE_NAME",
  "input": {
    "typeName": "standard-http-api",
    "config": "{}"
  },
  "processors": [
    {
      "typeName": "http-jackson-converter",
      "config": "{\"required\": false, \"headersToEnrich\": []}",
      "order": 1
    },
    {
      "typeName": "pipeline-data-enrichment-processor",
      "config": "{}",
      "order": 2
    },
    {
      "typeName": "json-flattener-processor",
      "config": "{\"flattenMode\": \"KEEP_ARRAYS\", \"standardFlatteningForFieldsWithDots\": false}",
      "order": 3
    }
  ],
  "outputs": [
    {
      "typeName": "kafka-output",
      "config": "{\"acks\": -1, \"topic\": \"LOGS_TOPIC_NAME\", \"clientId\": \"cid-3\", \"lingerMs\": 0, \"batchSize\": 16384, \"maxBlockMs\": 60000, \"keySerializer\": \"org.apache.kafka.common.serialization.StringSerializer\", \"sslClientAuth\": false, \"requestTimeout\": 30000, \"deliveryTimeout\": 120000, \"valueSerializer\": \"org.springframework.kafka.support.serializer.JsonSerializer\", \"bootstrapServers\": \"KAFKA_ADDRESS_AND_PORT\", \"securityProtocol\": \"SSL\", \"idempotenceEnabled\": true, \"sslEnabledProtocols\": \"TLSv1.2\", \"maxInFlightRequestsPerConnection\": 5, \"sslEndpointIdentificationAlgorithm\": \"https\"}"
    }
  ]
}

, где LOGS_TOPIC_NAME - это имя топика Apache Kafka для записи логов (подробнее о создании топика в Руководстве оператора, инструкция поставляется в рамках компонента Abyss (LGDB) в составе продукта Platform V Monitor),

KAFKA_ADDRESS_AND_PORT - список bootstrap серверов Apache Kafka Abyss (эта информация должна быть известна Администраторам PVM).

Сбор трассировок#

Конфигурирование приложения (источника телеметрии)#

Сбор данных происходит с помощью Spring Zipkin. Трассировки пишутся для всех приложений сервиса: pull/push collector, management application.

Конфигурация:

spring.zipkin.enabled: true
spring.zipkin.base-url: http://{host}:{port}/push/project/{projectName}/pipeline/{pipelineName}
spring.zipkin.api-path: /
spring.zipkin.sender.type: WEB

, где {projectName} - имя проекта, используемого для сбора данных, {pipelineName} - имя pipeline.

Конфигурация pipeline для импорта:

{
  "quota": {
    "limitTrafficPerMin": 10000
  },
  "name": "PIPELINE_NAME",
  "input": {
    "typeName": "standard-http-api",
    "config": "{}"
  },
  "processors": [
    {
      "typeName": "http-jackson-converter",
      "config": "{\"required\": false, \"headersToEnrich\": []}",
      "order": 1
    },
    {
      "typeName": "pipeline-data-enrichment-processor",
      "config": "{}",
      "order": 2
    },
    {
      "typeName": "json-flattener-processor",
      "config": "{\"flattenMode\": \"KEEP_ARRAYS\", \"standardFlatteningForFieldsWithDots\": false}",
      "order": 3
    }
  ],
  "outputs": [
    {
      "typeName": "kafka-output",
      "config": "{\"acks\": -1, \"topic\": \"TRACE_TOPIC_NAME\", \"clientId\": \"cid-3\", \"lingerMs\": 0, \"batchSize\": 16384, \"maxBlockMs\": 60000, \"keySerializer\": \"org.apache.kafka.common.serialization.StringSerializer\", \"sslClientAuth\": false, \"requestTimeout\": 30000, \"deliveryTimeout\": 120000, \"valueSerializer\": \"org.springframework.kafka.support.serializer.JsonSerializer\", \"bootstrapServers\": \"KAFKA_ADDRESS_AND_PORT\", \"securityProtocol\": \"SSL\", \"idempotenceEnabled\": true, \"sslEnabledProtocols\": \"TLSv1.2\", \"maxInFlightRequestsPerConnection\": 5, \"sslEndpointIdentificationAlgorithm\": \"https\"}"
    }
  ]
}

, где TRACE_TOPIC_NAME - это имя топика Apache Kafka для записи трассировок(топик создается с помощью UI Abyss),

KAFKA_ADDRESS_AND_PORT - список bootstrap серверов Apache Kafka Abyss (эта информация должна быть известна Администраторам PVM).

Настройка FluentBit агента для сбора трассировок#

Пример конфигурации FluentBit для отправки trace из системы распределенной трассировки Zipkin в FluentBit:

apiVersion: v1
kind: ConfigMap
metadata:
  name: volume-conf-fluent-bit-sidecar
data:
  fluent-bit.conf: |-
    [SERVICE]
       Flush        1
       Daemon       Off
       Parsers_File /fluent-bit/etc/parsers.conf
       HTTP_Server  On
       HTTP_Listen  0.0.0.0
       HTTP_PORT    ${fluentbit_monitoring_port_number}
    [INPUT]
       Name http
       Tag api_v2_spans
       Port ${spans_port_number}
       Buffer_max_size ${buffer_max_size}
       Buffer_chunk_size ${buffer_chunk_size}
    [FILTER]
       Name nest
       Match *
       Operation lift
       Nested_under tags
       Add_prefix tag_
    [FILTER]
       Name nest
       Match *
       Operation lift
       Nested_under localEndpoint
       Add_prefix localEndpoint_
    [FILTER]
       Name nest
       Match *
       Operation lift
       Nested_under remoteEndpoint
       Add_prefix remoteEndpoint_
    [OUTPUT]
       Name stdout
       Match *
    [OUTPUT]
       Name             http
       Match            file.tail
       Host             telemetry-collector-push-service
       Port             8083
       URI              push/project/{projectName}/pipeline/{pipelineName}
       Format           json 
  parsers.conf: |-
    [PARSER]
       Name custom
       Format json

, где {projectName} - имя проекта, используемого для сбора данных, {pipelineName} - имя pipeline.

Здесь в секции [INPUT] для плагина HTTP, тег api_v2_spans такой же, какой динамически устанавливается путем добавления в конец URL-адреса запроса. Затем этот тег используется для маршрутизации события через систему. Если вы не установите этот тег, http.0 будет использоваться автоматически. Если у вас несколько [INPUT]'ов HTTP, они будут следовать шаблону http.N, где N - целое число, представляющее [INPUT].

Для приложений на базе spring-boot c использованием стартера spring-cloud-starter-zipkin в файле application.properties/yaml установить следующие настройки:

1. spring.zipkin.base-url=http://localhost:${spans_port_number}
2. spring.zipkin.encoder=json_v2
  • Первый параметр - базовый URL для отправки трассировок Zipkin. Возможна отправка через FluentBit, в этом случае необходимо убедиться, что откидываемые приложением метрики (трассировки) направляются в выставленный FluentBit endpoint без gzip-компрессии;

  • Второй параметр выставит кодировку span в соответствующий формат json_v2.

spring.zipkin.compression.enabled=false (дефолтное значение) 

Конфигурация pipeline для импорта:

{
  "quota": {
    "limitTrafficPerMin": 10000
  },
  "name": "self-tracing-pipe",
  "input": {
    "typeName": "standard-http-api",
    "config": "{}"
  },
  "processors": [
    {
      "typeName": "http-jackson-converter",
      "config": "{\"required\": false, \"headersToEnrich\": []}",
      "order": 1
    },
    {
      "typeName": "pipeline-data-enrichment-processor",
      "config": "{}",
      "order": 2
    },
    {
      "typeName": "json-flattener-processor",
      "config": "{\"flattenMode\": \"KEEP_ARRAYS\", \"standardFlatteningForFieldsWithDots\": false}",
      "order": 3
    }
  ],
  "outputs": [
    {
      "typeName": "kafka-output",
      "config": "{\"acks\": -1, \"topic\": \"TRACE_TOPIC_NAME\", \"clientId\": \"cid-3\", \"lingerMs\": 0, \"batchSize\": 16384, \"maxBlockMs\": 60000, \"keySerializer\": \"org.apache.kafka.common.serialization.StringSerializer\", \"sslClientAuth\": false, \"requestTimeout\": 30000, \"deliveryTimeout\": 120000, \"valueSerializer\": \"org.springframework.kafka.support.serializer.JsonSerializer\", \"bootstrapServers\": \"KAFKA_ADDRESS_AND_PORT\", \"securityProtocol\": \"SSL\", \"idempotenceEnabled\": true, \"sslEnabledProtocols\": \"TLSv1.2\", \"maxInFlightRequestsPerConnection\": 5, \"sslEndpointIdentificationAlgorithm\": \"https\"}"
    }
  ]
}