Если вы используете в облачных провайдерах managed-инсталляции серверных служб вроде RDS или ElastiCache от AWS, то скорее всего уже задавались темой мониторинга инфраструктуры, а главное оповещений по произошедшим инцидентам. При реализации возникают понятные вопросы:
-
Как можно настроить сбор данных с endpointов в систему мониторинга?
-
Если использовать Prometheus, то какие экспортеры использовать и где их можно запускать?
-
Какие есть варианты готовых алертов для покрытия основных причин аварий/частичной недоступности?
Эта статья в большей степени рассчитана на начинающих инженеров: на примере Prometheus и CloudWatch мы рассмотрим одно из самых простых и понятных решений с помощью cloudwatch_exporter и prometheus_aws_cost_exporter в AWS, напишем для них Helm-чарт и задеплоим его в Kubernetes. (K8s будет выступать удобной площадкой для разворачивания экспортеров.) А также посмотрим, как можно мониторить текущие и ежедневные затраты всей вашей инфраструктуры.
CloudWatch сервис для мониторинга инфраструктуры. С его помощью можно настраивать уведомления о произошедших инцидентах по почте, что довольно популярно в проектах, где еще нет централизованной системы мониторинга. Однако мы пойдем по другому пути и будем выводить метрики в формате Prometheus, на основе которых строить графики и настраивать алерты.
У AWS есть отдельные типы инстансов с бюджетами кредитов по CPU и дисков с кредитами по IO. Они позволяют накапливать бюджет кредитов во время сниженной нагрузки и тратить его в том случае, если она резко выросла. Но прогнозировать, когда нагрузка может уйти, проблематично. Поэтому есть риск выработать весь бюджет и перейти на режим ограниченного потребления ресурсов. Данный вариант развития событий сложно диагностировать, так как в мониторинге сервера это напрямую не будет отражено. Поэтому очень полезно мониторить кредиты CPU/IO, чтобы понимать, какое количество кредитов доступно в данный момент, какова динамика их потребления и предвидеть их исчерпание.
Итак, возвращаясь к выбранным инструментам: prometheus_aws_cost_exporter будет использоваться для мониторинга потребления финансов, так как cloudwatch_exporter возвращает информацию только за предыдущий день. Зато cloudwatch_exporter позволяет снимать гораздо больше метрик.
Приступим к непосредственной реализации!
1. Настраиваем IAM
Поскольку рассматривать мы будем два экспортера с немного различным функционалом, потребуются два разных аккаунта в IAM (AWS Identity and Access Management). Ниже представлен список ролей, которые нужны обоим аккаунтам:
-
cloudwatch:ListMetrics
-
cloudwatch:GetMetricStatistics
-
tag:GetResources
Для работы prometheus_aws_cost_exporter требуется больший набор прав: необходимо создать отдельную роль и назначить её пользователю. Для удобства роль можно создать из JSON:
{ "Effect": "Allow", "Action": [ "cloudwatch:PutMetricData", "ec2:DescribeVolumes", "ec2:DescribeTags", "logs:PutLogEvents", "logs:DescribeLogStreams", "logs:DescribeLogGroups", "logs:CreateLogStream", "logs:CreateLogGroup", "ce:GetCostAndUsage" ], "Resource": "*"},{ "Effect": "Allow", "Action": [ "ssm:GetParameter" ], "Resource": [ "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*", "arn:aws:ce:*:*:/GetCostAndUsage" ]}
Для учётных записей экспортеров также требуется создать access
key ID и secret access key, которые будут передаваться в виде
переменных (AWS_ACCESS_KEY_ID
и
AWS_SECRET_ACCESS_KEY
).
2. Создаем IAM-роли через веб-интерфейс
Авторизуемся в консоли управления AWS и перейдем в раздел IAM,
где для примера создадим пользователя под названием
cloudwatch_users
.
В поле Access Type включим опцию Programmatic
access, которая позволит сгенерировать упомянутые access
key ID и secret access key (они потребуются для
работы с API, сохраните их куда-нибудь в надёжное хранилище).
Следующая вкладка Attach existing policies directly, где
мы создадим новую политику. Для данной IAM-роли требуются права
ListMetrics
и
GetMetricStatistics
.
Если удобнее создавать роль через API, можно воспользоваться JSON-сниппетом:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "cloudwatch:GetMetricStatistics", "cloudwatch:ListMetrics" ], "Resource": "*" } ]}
После нажатия на Review policy указываем название для
Policy и создаем её (Create
policy). Дальнейшие пункты не влияют на
функции созданной роли. Однако потребуется вернуться на этап
создания IAM-роли, чтобы добавить созданный нами Policy. На самом
последнем этапе станут доступны для просмотра значения для
переменных AWS_ACCESS_KEY_ID
и
AWS_SECRET_ACCESS_KEY
, которые надо записать в
values.yaml нашего будущего Helm-чарта.
Если вы используете Terraform, то по
данной ссылке есть готовый Terraform receipt для
создания IAM-роли и пользователей. Ключи API из
terraform.tfstate
можно получить с помощью
jq
:
jq '.resources[].instances[].attributes | {(.id):
.secret}'
Примечание: запросы к CloudWatch тарифицируются; актуальные цены можно изучить здесь. Исходя из этой информации можете выбрать, как часто выполнять запросы к API например, раз в час или в сутки в зависимости от задачи.
3. Helm-чарт для экспортеров
Перейдем к деплою cloudwatch-exporter и cost-exporter в Kubernetes. Потребуется написать очень простой Helm-чарт, который будет состоять из нескольких простых объектов.
В самом начале объявим необходимые переменные в
values.yaml
:
---aws_access_key_id: <AWS_ACCESS_KEY_ID>aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>region: eu-central-1replicas: 1resources: requests: cpu: 1m memory: 512Mienv: metric_today_daily_costs: "yes" metric_yesterday_daily_costs: "yes" query_period: "1800" metric_today_daily_usage: "yes" metric_today_daily_usage_norm: "yes"
Подробнее о содержимом этого файла:
-
В переменных
aws_access_key_id
иaws_secret_access_key
объявляются значения, полученные при создании IAM-роли; -
region
регион, в котором требуется выполнять мониторинг ресурсов; -
query_period
периодичность запроса метрик из AWS (в секундах); -
metric_today_daily_costs
,metric_yesterday_daily_costs
,metric_today_daily_usage
,metric_today_daily_usage_norm
включение/выключение запрашивания метрик затрат (costs) и потребления (usage) за вчера и за сегодня (по умолчанию имеет значениеno
); -
Параметры из блока
env
используются cost-exporterом (на работу cloudwatch-exporter не влияют).
Ниже пример листинга с Deployment для cloudwatch-exporter, который носит иллюстративный характер (содержит только основную структуру для удобства чтения). Полная версия доступна здесь.
apiVersion: apps/v1kind: Deploymentmetadata: name: cloudwatch-exporterspec: selector: matchLabels: app: cloudwatch-exporter template: metadata: labels: app: cloudwatch-exporter spec: containers: - name: cloudwatch-exporter image: prom/cloudwatch-exporter:cloudwatch_exporter-0.9.0 env: - name: AWS_ACCESS_KEY_ID value: "{{ .Values.aws_access_key_id }}" - name: AWS_SECRET_ACCESS_KEY value: "{{ .Values.aws_secret_access_key }}" volumeMounts: - name: config subPath: config.yml mountPath: /config/config.yml volumes: - name: config configMap: name: config
Следующий Deployment (точнее, снова его фрагмент) для cost-exporter:
apiVersion: apps/v1kind: Deploymentmetadata: name: cost-exporterspec: selector: matchLabels: app: cost-exporter template: metadata: labels: app: cost-exporter spec: containers: - name: cost-exporter image: nachomillangarcia/prometheus_aws_cost_exporter:latest args: - --host - 0.0.0.0 env: - name: AWS_ACCESS_KEY_ID value: "{{ .Values.aws_access_key_id }}" - name: AWS_SECRET_ACCESS_KEY value: "{{ .Values.aws_secret_access_key }}" - name: METRIC_TODAY_DAILY_COSTS value: "{{ .Values.env.metric_today_daily_costs }}" - name: METRIC_YESTERDAY_DAILY_COSTS value: "{{ .Values.env.metric_yesterday_daily_costs }}" - name: QUERY_PERIOD value: "{{ .Values.env.query_period }}" - name: METRIC_TODAY_DAILY_USAGE value: "{{ .Values.env.metric_today_daily_usage }}" - name: METRIC_TODAY_DAILY_USAGE_NORM value: "{{ .Values.env.metric_today_daily_usage_norm }}"
4. Настраиваем метрики для мониторинга
Остается настроить самое главное те метрики, которые будут собираться в Prometheus и на основании значений которых мы хотим делать алерты.
Здесь есть пример конфигурационного файла для cloudwatch_exporter с перечислением необходимых для мониторинга метрик.Посмотреть все доступные для мониторинга метрики например, для EC2 можно с помощью консольной утилиты aws:
aws cloudwatch list-metrics --namespace EC2
Все параметры конфига берутся из вывода консольной утилиты
aws
. Типичный фрагмент конфига:
- aws_namespace: AWS/NetworkELB aws_metric_name: HealthyHostCount aws_dimensions: - LoadBalancer - TargetGroup aws_statistics: - Sum period_seconds: 60
Этот фрагмент указывает экспортеру брать из AWS/NetworkELB
метрику HealthyHostCount
с периодичностью 60 секунд,
агрегировать её по LoadBalancer
и
TargetGroup
, выдавать значение Sum
.
Бонус! Несколько примеров алертов
Вот так выглядит алерт на использование CPU в Redis у ElastiCache:
- alert: RedisCPUUsage annotations: description: | Redis CPU utilization on {{`{{$labels.cache_cluster_id}}`}} in cluster is over than 60% summary: Redis CPU utilization on {{`{{$labels.cache_cluster_id}}`}} in cluster is over than 60% expr: | aws_elasticache_cpuutilization_average >= 60 for: 5m
Алерт на количество target у LoadBalancer:
- alert: LBTargetGroupIsUnhealthy annotations: description: Some hosts are target group {{`{{$labels.target_group}}`}} in cluster is unhealthy! summary: Some hosts are target group {{`{{$labels.target_group}}`}} in cluster is unhealthy! expr: | aws_networkelb_healthy_host_count_sum{load_balancer=~".*someservice.*",target_group=~".*someservice.*"} < 3 for: 1m
Алерт на исчерпание EBS Burst balance:
- alert: EBSBurst_balance annotations: description: EBS Burst balance in cluster is less than 60% summary: EBS Burst balance in cluster is less than 60% expr: | aws_ebs_burst_balance_average <= 60 for: 5m
В репозитории представлен более обширный список примеров для конфигурации метрик и алертов.
Примеры, как могут выглядеть графики в Prometheus:
AWS EC2 EBS IO balance (average)AWS ElastiCache CPU utilization (average)Заключение
В статье рассмотрен мониторинг сервисов AWS с помощью известных Prometheus exporterов. Настроив его описанным образом, можно получить удобный инструмент для анализа состояния managed-инфраструктуры и ее стоимости, что поможет скорректировать расходы и вовремя получать информацию о потребляемых финансовых ресурсах.
За рамками материала остались некоторые вопросы взаимодействия с Prometheus (как ему сообщать, откуда и куда scrapeить метрики), а также создание панелей в Grafana. (Кстати, для prometheus_aws_cost_exporter есть dashboard от создателя.) Разобравшись и с ними для своего конкретного случая, можно получить более полное, законченное решение.
P.S.
Читайте также в нашем блоге: