Сейчас в Prometehus мы собираем метрики из AWS CLoudWatch с помощью CloudWatch exporter от самого AWS, см. Prometheus: CloudWatch exporter — сбор метрик из AWS и графики в Grafana, однако, у него есть несколько недостатков:
- написан на Java, тяжёлый — грузит хост мониторнига
- не подтягивает теги
- использует
GetMetricStatisticsдля получения метрик - умеет собирать метрики только из одного региона — для нескольких регионов потребутеся запускать несколько експортёров
Что бы избавиться от этих проблем — используем вместо него yet-another-cloudwatch-exporter.
Содержание
AWS CloudWatch — недостатки
Tags
Первое, что крайне неудобно — это отсутствие тегов в метриках, собираемых дефолтным експортёром.
Например, Application Load Balancer возвращается в таком виде:
Тогда как у самого ALB тегов намного больше:
И сейчас в Grafana нет никакой возможности эти теги использовать для выборки.
GetMetricStatistics vs GetMetricData
Второй нюанс — это то, как експортер собирает метрики, т.к. он использует AWS API GetMetricStatistics.
Два года тому была открыта issue Reduce cost of api operations by using GetMetricData API instead of GetMetricStatistics API — но воз и ныне там.
Проблема заключается в том, что при GetMetricStatistics на каждую метрику выполняется отдельный API-запрос.
Т.е., если у вас 100 ЕС2-инстансов, и у каждого 10 метрик — то cloudwatch-exporter будет выполнять 1000 запросов каждые 60 секунд, что в результате выливается в приличные деньги:
В отличии от AWS cloudwatch-exporter, в yet-another-cloudwatch-exporter используется запрос GetMetricData, который позволяет получить до 500 метрик при выполнении единого запроса.
Запуск yet-another-cloudwatch-exporter
Попробуем получить данные.
Создаём файл с данными доступа к AWS, назовём его alb-cred:
[default] aws_region = us-east-2 aws_access_key_id = AKI***D4Q aws_secret_access_key = QUC***BTI
Либо можно использовать AWS EC2 Instance Profile, но в его политику надо добавить разрешения на выполенние таких вызовов:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchExporterPolicy",
"Effect": "Allow",
"Action": [
"tag:GetResources",
"cloudwatch:ListTagsForResource",
"cloudwatch:GetMetricData",
"cloudwatch:ListMetrics"
],
"Resource": "*"
}
]
}
Создаём файл настроек самого експортёра:
discovery:
jobs:
- regions:
- us-east-2
type: elb
enableMetricData: true
metrics:
- name: ActiveConnectionCount
statistics:
- Sum
period: 300
length: 600
Запускаем его:
[simterm]
$ docker run -ti -p 5000:5000 -v /home/setevoy/Temp/alb-cred:/exporter/.aws/credentials -v /home/setevoy/Temp/config.yaml:/tmp/config.yml quay.io/invisionag/yet-another-cloudwatch-exporter:v0.19.1-alpha
{"level":"info","msg":"Parse config..","time":"2020-07-21T10:59:49Z"}
{"level":"info","msg":"Startup completed","time":"2020-07-21T10:59:49Z"}
[/simterm]
И пробуем метрики:
[simterm]
$ curl localhost:5000/metrics
# HELP aws_elb_info Help is not implemented yet.
# TYPE aws_elb_info gauge
aws_elb_info{name="arn:aws:elasticloadbalancing:us-east-2:534***385:loadbalancer/app/fea06ba9-eksstage1mealplan-a584/***",tag_Env="",tag_Name="",tag_Stack="",tag_ingress_k8s_aws_cluster="bttrm-eks-stage-1",tag_ingress_k8s_
aws_resource="LoadBalancer",tag_ingress_k8s_aws_stack="eks-stage-1-mealplan-api-ns/mealplan-api-ingress",tag_kubernetes_io_cluster_bttrm_eks_dev_0="",tag_kubernetes_io_cluster_bttrm_eks_dev_1="",tag_kubernetes_io_cluster_bttrm_eks_prod_0=
"",tag_kubernetes_io_cluster_bttrm_eks_prod_1="",tag_kubernetes_io_cluster_bttrm_eks_stage_1="owned",tag_kubernetes_io_cluster_eksctl_bttrm_eks_production_1="",tag_kubernetes_io_ingress_name="mealplan-api-ingress",tag_kubernetes_io_namesp
ace="eks-stage-1-mealplan-api-ns",tag_kubernetes_io_service_name=""} 0
...
[/simterm]
Теперь видим все теги.
Настройка yet-another-cloudwatch-exporter
exportedTagsOnMetrics
Список тегов, которые експортер будет получать вместе с метриками может быть ограничен exportedTagsOnMetrics.
Например — оставим только теги:
discovery:
exportedTagsOnMetrics:
alb:
- Name
- kubernetes.io/service-name
- ingress.k8s.aws/cluster
- kubernetes.io/namespace
...
SeacrhTags
Также, можно граничить список ресурсов, с которых будем собирать метрики (аналог tag_selections в експортёре от AWS).
Например, ограничим выбор кластером «bttrm-eks-prod-1» — приводим файл к виду:
discovery:
exportedTagsOnMetrics:
alb:
- Name
- kubernetes.io/service-name
- ingress.k8s.aws/cluster
- kubernetes.io/namespace
jobs:
- type: alb
regions:
- us-east-2
searchTags:
- Key: ingress.k8s.aws/cluster
Value: bttrm-eks-prod-1
metrics:
- name: UnHealthyHostCount
statistics: [Maximum]
period: 60
length: 600
- name: ActiveConnectionCount
statistics: [Sum]
period: 300
length: 600
Проверяем:
[simterm]
$ curl localhost:5000/metrics
# HELP aws_alb_active_connection_count_sum Help is not implemented yet.
# TYPE aws_alb_active_connection_count_sum gauge
aws_alb_active_connection_count_sum{dimension_LoadBalancer="app/bcf678a9-eksprod1bttrmapps-447a/***",name="arn:aws:elasticloadbalancing:us-east-2:534***385:loadbalancer/app/bcf678a9-eksprod1bttrmapps-***",region="us-east-2",tag_Name="",tag_ingress_k8s_aws_cluster="bttrm-eks-prod-1",tag_kubernetes_io_namespace="eks-prod-1-bttrm-apps-ns",tag_kubernetes_io_service_name=""} 112
...
aws_alb_tg_un_healthy_host_count_maximum{dimension_LoadBalancer="app/bcf678a9-eksprod1bttrmapps-447a/***",dimension_TargetGroup="targetgroup/bcf678a9-9b32ce4accea2525b4d/e0f341421a33a453",name="arn:aws:elasticloadbalancing:us-east-2:534***385:targetgroup/bcf678a9-9b32ce4accea2525b4d/e0f341421a33a453",region="us-east-2",tag_Name="",tag_ingress_k8s_aws_cluster="bttrm-eks-prod-1",tag_kubernetes_io_namespace="eks-prod-1-bttrm-apps-ns",tag_kubernetes_io_service_name="bttrm-apps-backend-svc"} 0
...
[/simterm]
Теперь получаем метрики только с одного кластера, и только нужными нам тегами.
Запуск в Prometheus
У нас весь стек мониторинга запускается из Docker Compose — добавляем туда новый ексопртёр:
...
yace-clouwatch-exporter:
image: quay.io/invisionag/yet-another-cloudwatch-exporter:v0.19.1-alpha
networks:
- prometheus
ports:
- 5000:5000
volumes:
- /etc/prometheus/prometheus-yace-cloudwatch-exporter.yaml:/tmp/config.yml:ro
restart: unless-stopped
Обновляем конфиг самого Prometheus — добавляем новый таргет:
...
scrape_configs:
- job_name: 'yace-clouwatch-exporter'
metrics_path: '/metrics'
static_configs:
- targets: ['yace-clouwatch-exporter:5000']
...
Проверяем таргет:
И метрики:
Графики в Grafana
И теперь можем использовать эти метрики в Grafana с выборкой по, например, окружению — dev, stage, prod (см. Grafana: создание dashboard):
А $env формируется из нашей лейблы ekscluster, которая добавляется ко всем ресурсам во время создания кластера из CloudFormation (см. AWS Elastic Kubernetes Service: автоматизация создания кластера, часть 1 — CloudFormation):
Готово.
Ссылки по теме
- Improving the Prometheus exporter for Amazon CloudWatch
- Monitoring AWS Lambda with Prometheus and Sysdig









