Prometheus: CloudWatch exporter – сбор метрик из AWS и графики в Grafana

Автор: | 21/06/2018

Используем prometheus/cloudwatch_exporter.

Клиент написан, внезапно, на Java, из минусов – не умеет экпортировать теги AWS в метки Prometheus (есть альтернативный клиент – technofy/cloudwatch_exporter, который вроде бы умеет).

IAM пользователь

Для IAM пользователя, доступы которого будет использовать експортёр требуются роли cloudwatch:ListMetrics и cloudwatch:GetMetricStatistics (надо проверить – сработает ли роль CloudWatchAgentServerPolicy, подключенная к EC2, что бы не использовать Access/Secret ключи).

Переходим в IAM, создаём новую политику – Create policy:

  • в Service выбираем CloudWatch
  • в Access level – выбираем List > ListMetrics и Read > GetMetricStatistics

Сохраняем её – Create policy:

Переходим в Users – Add user:

Создаём пользователя с Programmatic access:

Выбираем Attach existing policies directly, и находим созданную ранее политику:

Получаем его Access и Secret ключи:

Сохраняем их.

Проверка prometheus/cloudwatch_exporter

Сначала запустим експортер из Docker образа с тестовым конфигом.

Создаём файл его настроек, назовём к примеру prometheus-exporter.yml:

region: us-east-2
metrics:

 - aws_namespace: AWS/EC2
   aws_metric_name: CPUUtilization
   aws_dimensions: [InstanceId]

Важный момент: хотя в документации к екпортёру сказано, что aws_dimensions и aws_statistics являются optional параметрами – на самом деле без как минимум aws_dimensions метрики не собираются. На этот счёт даже есть открытая issue тут>>>, но на неё как-то не реагируют вообще.

Список dimensions для типа EC2 можно найти в документации AWS тут>>>., а для всех остальных типов – тут>>>.

Что бы определить какой тип dimensions использовать – переходим в CloudWatch, выбираем тип метрик, в данном случае EC2, и открываем список метрик:

Тут InstanceId как раз является искомым фильтром.

Запускаем контейнер, передавая в переменных ключи, и через docker volumes – файл настроек:

[simterm]

$ sudo docker run -d -p 9106:9106 -e AWS_ACCESS_KEY_ID=AKI***ZZA -e AWS_SECRET_ACCESS_KEY=7vb***lDqi -v /home/setevoy/Temp/prometheus-exporter.yml:/config/config.yml prom/cloudwatch-exporter

[/simterm]

Проверяем:

[simterm]

$ curl -s localhost:9106/metrics | grep -v \# | grep -v cloud
aws_ec2_cpuutilization_sum{job="aws_ec2",instance="",instance_id="i-0ad3a71827218abcd",} 7.66666666666652 1529488320000
aws_ec2_cpuutilization_sum{job="aws_ec2",instance="",instance_id="i-01dc5f648589e273f",} 8.63661202185913 1529488500000
aws_ec2_cpuutilization_sample_count{job="aws_ec2",instance="",instance_id="i-0ad3a71827218abcd",} 5.0 1529488320000
aws_ec2_cpuutilization_sample_count{job="aws_ec2",instance="",instance_id="i-01dc5f648589e273f",} 5.0 1529488500000
aws_ec2_cpuutilization_minimum{job="aws_ec2",instance="",instance_id="i-0ad3a71827218abcd",} 1.33333333333288 1529488320000
aws_ec2_cpuutilization_minimum{job="aws_ec2",instance="",instance_id="i-01dc5f648589e273f",} 1.66666666666667 1529488500000
aws_ec2_cpuutilization_maximum{job="aws_ec2",instance="",instance_id="i-0ad3a71827218abcd",} 1.66666666666667 1529488320000
aws_ec2_cpuutilization_maximum{job="aws_ec2",instance="",instance_id="i-01dc5f648589e273f",} 1.83333333333394 1529488500000
aws_ec2_cpuutilization_average{job="aws_ec2",instance="",instance_id="i-0ad3a71827218abcd",} 1.5333333333333041 1529488320000
aws_ec2_cpuutilization_average{job="aws_ec2",instance="",instance_id="i-01dc5f648589e273f",} 1.7273224043718258 1529488500000

[/simterm]

cloudwatch-exporter в Prometheus

Теперь добавим експортёр в Prometheus.

На хосте мониторинга создаём файл настроек для екпортёра, в данном случае это будет /etc/prometheus/prometheus-cloudwatch-exporter.yml.

region: us-east-2
metrics:

 - aws_namespace: AWS/EC2
   aws_metric_name: CPUUtilization
   aws_dimensions: [InstanceId]
   aws_statistics: [Average]

 - aws_namespace: AWS/EC2
   aws_metric_name: DiskReadOps
   aws_dimensions: [InstanceId]
   aws_statistics: [Sum]

 - aws_namespace: AWS/EC2
   aws_metric_name: DiskWriteOps
   aws_dimensions: [InstanceId]
   aws_statistics: [Sum]

Обновляем Compose файл с Prometheus и Grafana – добавляем запуск контейнера с cloudwatch-exporter, тут это /opt/prometheus/prometheus-compose.yml:

version: '3.3'

networks:
  prometheus:

services:

  prometheus-server:
    image: prom/prometheus:v1.8.2
    networks:
      - prometheus
    ports:
      - 9090:9090
    volumes:
      - /etc/prometheus/prometheus-server-conf.yml:/etc/prometheus.yml
      - /data/prometheus/prometheus:/prometheus
    command:
      - '-config.file=/etc/prometheus.yml'
      - '-storage.local.path=/prometheus'
      - '-web.external-url=http://dev.monitor.domain.world/prometheus'
    restart: always

  grafana-ui:
    image: grafana/grafana
    networks:
      - prometheus
    ports:
      - 3000:3000
    volumes:
      - /etc/grafana:/etc/grafana/
      - /data/grafana:/var/lib/grafana
    depends_on:
      - prometheus-server

  cloudwatch-exporter:
    image: prom/cloudwatch-exporter
    networks:
      - prometheus
    ports:
      - 9106:9106
    volumes:
      - /etc/prometheus/prometheus-cloudwatch-exporter.yml:/config/config.yml
    environment:
      - AWS_ACCESS_KEY_ID=AKI***ZZA
      - AWS_SECRET_ACCESS_KEY=7vb***Dqi

Обновляем файл настроек самого Prometheus, тут это /etc/prometheus/prometheus-server-conf.yml – указываем ему сбор метрик с этого експортёра:

global:

  scrape_interval:     15s
  external_labels:
    monitor: 'btrm-monitor'

scrape_configs:

  - job_name: 'prometheus'
    metrics_path: '/prometheus/metrics'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: backend-dev
    honor_labels: true
    params:
      match[]:
        - '{job!=""}'
    metrics_path: '/federate'
    ec2_sd_configs:
      - region: us-east-2
        access_key: AKI***A4A
        secret_key: Onh***0X+
        port: 9090

    relabel_configs:
      - source_labels: [__meta_ec2_tag_Name]
        regex: mobile.*
        action: keep
      - source_labels: [__meta_ec2_tag_Name]
        target_label: instance

  - job_name: cloudwatch-exporter
    honor_labels: true
    metrics_path: '/metrics'
    static_configs:
      - targets: ['cloudwatch-exporter:9106']

В имени хоста в targets – указываем имя контейнера в Compose файле.

Запускаем Prometheus, Grafana и cloudwatch-exporter:

[simterm]

# docker-compose -f prometheus-compose.yml up
Creating network "prometheus_prometheus" with the default driver
Creating prometheus_cloudwatch-exporter_1 ... done
Creating prometheus_prometheus-server_1   ... done
Creating prometheus_grafana-ui_1          ... done
Attaching to prometheus_prometheus-server_1, prometheus_cloudwatch-exporter_1, prometheus_grafana-ui_1
...

[/simterm]

Проверяем targets:

Проверяем метрики:

И они же в панели самого CloudWatch:

Осталось создать дашборд в Grafana.

Grafana dashboard

Создаём новый башборд, тип Graph:

Переходим в Settings > General, задаём имя борды и теги:

Добавляем переменную с именем instance, тип Query:

  • в Datasource выбираем Prometehus
  • в самом запросе вызываем aws_ec2_cpuutilization_average{job="aws_ec2"}, который вернёт нам все инстансы с меткой job=”aws_ec2″
  • в регулярке – получаем только ID инстанса – /.*instance_id="(.*)",/

Жмём Add.

Переходим к редактированию панели, задаём имя:

В Metrics задаём datasource и запрос aws_ec2_cpuutilization_average{instance_id=~"$instance"}:

Проверяем:

Готово.