Блог Amazon Web Services

Начинаем работу с Amazon Managed service for Prometheus

Зарегистрируйтесь, чтобы получать приглашения на мероприятия AWS на русском языке.

Оригинал статьи: ссылка (Imaya Kumar Jagannathan, Senior Solutions Architect; Viji Sarathy, Senior Solutions Architect)

Amazon Managed Service для Prometheus (AMP) — это совместимый с Prometheus сервис мониторинга контейнерной инфраструктуры и метрик приложений для контейнеров, который упрощает клиентам настройку безопасного мониторинга масштабируемых контейнерных окружений. Prometheus поддерживает различные механизмы сбора метрик, которые включают в себя ряд библиотек и серверов, помогающих экспортировать специфические для приложений метрики из сторонних систем в формате метрик Prometheus. Вы также можете использовать AWS Distro для OpenTelemetry, чтобы получать метрики приложений из своего окружения. С помощью AMP вы можете использовать ту же открытую модель данных и язык запросов Prometheus для мониторинга производительности ваших контейнерных рабочих нагрузок, что и сегодня. Для использования сервиса не требуются предварительные вложения, и вы платите только за количество принимаемых метрик.

Клиенты, использующие Prometheus в своих контейнерных средах, сталкиваются с проблемами управления высокодоступной, масштабируемой и безопасной серверной средой Prometheus, инфраструктурой для долговременного хранения данных и контролем доступа. AMP решает эти проблемы, предоставляя полностью управляемую среду, тесно интегрированную с AWS Identity and Access Management (IAM) для контроля аутентификации и авторизации. Вы можете начать использовать AMP, выполнив эти два простых шага:

  • Создайте рабочую среду AMP
  • Настройте сервер Prometheus на отправку метрик в рабочую среду AMP

После настройки вы сможете использовать полностью управляемую среду AMP для получения, хранения и запроса метрик. В этой статье мы рассмотрим шаги, необходимые для настройки AMP для получения пользовательских метрик Prometheus, собранных из контейнеризованной рабочей нагрузки, развернутой на кластере Amazon EKS, а затем запросим и визуализируем их с помощью Grafana.

Архитектура

На диаграмме ниже показана общая архитектура Amazon Managed Service для Prometheus и его взаимодействие с другими компонентами.

Архитектура AMP

Архитектура AMP

Настройка рабочей среды для сбора метрик Prometheus

Чтобы начать, вы сначала должны создать рабочую среду AMP. Рабочая среда — это изолированое от других рабочих сред AMP окружение, где вы принимаете, храните и запрашиваете метрики Prometheus, которые были собраны из рабочих нагрузок. В каждом регионе в рамках одной учетной записи AWS можно создать одну или несколько рабочих сред, и каждую рабочую среду можно использовать для приема метрик, собранных с нескольких рабочих нагрузок, которые экспортируют метрики в формате, совместимом с Prometheus.

Управляемая клиентом политика IAM со следующими правами доступа должна быть добавлена пользователю IAM, который управляет рабочей средой.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "aps:CreateWorkspace",
                "aps:DeleteWorkspace",
                "aps:DescribeWorkspace",
                "aps:ListWorkspaces",
                "aps:UpdateWorkspaceAlias"
            ],
            "Resource": "*"
        }
    ]
}

Рабочая среда создается из консоли управления AWS, как показано ниже:

Создать рабочую среду

Создать рабочую среду

Список рабочих сред

Список рабочих сред

Кроме того, вы также можете создать рабочую среду с помощью AWS CLI, как это описано здесь.

Далее, в качестве дополнительного шага, вы создаете interface VPC endpoint для безопасного доступа к управляемому сервису из ресурсов, развернутых на вашем VPC. Это гарантирует, что данные, принимаемые управляемым сервисом, не покинут VPC в вашей учетной записи AWS. Это можно сделать с помощью AWS CLI следующим образом. Убедитесь, что такие строки, как VPC_ID, AWS_REGION и другие, будут заменены соответствующими значениями.

aws ec2 create-vpc-endpoint \
--vpc-id <VPC_ID> \
--service-name com.amazonaws.<AWS_REGION>.aps-workspaces \
--security-group-ids <SECURITY_GROUP_IDS> \
--vpc-endpoint-type Interface \
--subnet-ids <SUBNET_IDS>

В вышеприведенной команде SECURITY_GROUP_IDS представляет собой список групп безопасности, связанных с VPC interface endpoint для обеспечения связи между сетевым интерфейсом конечной точки и ресурсами в VPC, такими как рабочие узлы кластера Amazon EKS. SUBNET_IDS представляет собой список подсетей, в которых находятся эти ресурсы.

Настройка прав доступа

Сборщики метрик (например, сервер Prometheus, развернутый на кластере Amazon EKS) извлекают оперативные метрики из контейнерных рабочих нагрузок, запущенных в кластере, и отправляют их в AMP для долговременного хранения, а также для последующего запроса инструментами мониторинга. Данные отправляются с помощью HTTP-запросов, которые должны быть подписаны валидными учетными данными AWS с использованием алгоритма AWS Signature Version 4 для аутентификации и авторизации каждого клиентского запроса на управляемый сервис. Для этого запросы отправляются на экземпляр AWS прокси для подписи, который будет перенаправлять их в управляемый сервис.

Прокси для подписи AWS может быть развернут в кластере Amazon EKS для работы под учетной записью службы Kubernetes. С помощью ролей IAM для учетных записей служб (IRSA) можно связать роль IAM с учетной записью служб Kubernetes и, таким образом, предоставить права доступа этой роли IAM любому поду, который использует эту учетную запись. Это следует принципу наименьших привилегий, поскольку с помощью IRSA можно безопасно настроить прокси для подписи AWS, чтобы отправлять метрики Prometheus в AMP.

Shell скрипт, предоставленный ниже, выполняет следующие действия после замены переменной YOUR_EKS_CLUSTER_NAME на имя вашего Amazon EKS кластера.

  1. Создает роль IAM с политикой IAM, имеющей права доступа на удаленную запись в рабочую среду AMP.
  2. Создает учетную запись службы Kubernetes, сопровождаемую ролью IAM.
  3. Создает доверительные отношения между ролью IAM и провайдером OIDC, расположенным в вашем кластере Amazon EKS.

Для выполнения скрипта необходимо, чтобы вы установили инструменты CLI kubectl и eksctl и настроили их для доступа к вашему кластеру Amazon EKS.

##!/bin/bash
CLUSTER_NAME=YOUR_EKS_CLUSTER_NAME
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")

PROM_SERVICE_ACCOUNT_NAMESPACE=prometheus
GRAFANA_SERVICE_ACCOUNT_NAMESPACE=grafana
SERVICE_ACCOUNT_NAME=iamproxy-service-account
SERVICE_ACCOUNT_IAM_ROLE=EKS-AMP-ServiceAccount-Role
SERVICE_ACCOUNT_IAM_ROLE_DESCRIPTION="IAM role to be used by a K8s service account with write access to AMP"
SERVICE_ACCOUNT_IAM_POLICY=AWSManagedPrometheusWriteAccessPolicy
SERVICE_ACCOUNT_IAM_POLICY_ARN=arn:aws:iam::$AWS_ACCOUNT_ID:policy/$SERVICE_ACCOUNT_IAM_POLICY
#
# Setup a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
# If the IAM role already exists, then add this new trust policy to the existing trust policy
#
echo "Creating a new trust policy"
read -r -d '' NEW_TRUST_RELATIONSHIP <<EOF
 [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:${GRAFANA_SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "${OIDC_PROVIDER}:sub": "system:serviceaccount:${PROM_SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
        }
      }
    }
  ]
EOF
#
# Get the old trust policy, if one exists, and append it to the new trust policy
#
OLD_TRUST_RELATIONSHIP=$(aws iam get-role --role-name $SERVICE_ACCOUNT_IAM_ROLE --query 'Role.AssumeRolePolicyDocument.Statement[]' --output json)
COMBINED_TRUST_RELATIONSHIP=$(echo $OLD_TRUST_RELATIONSHIP $NEW_TRUST_RELATIONSHIP | jq -s add)
echo "Appending to the existing trust policy"
read -r -d '' TRUST_POLICY <<EOF
{
  "Version": "2012-10-17",
  "Statement": ${COMBINED_TRUST_RELATIONSHIP}
}
EOF
echo "${TRUST_POLICY}" > TrustPolicy.json
#
# Setup the permission policy grants write permissions for all AWS StealFire workspaces
#
read -r -d '' PERMISSION_POLICY <<EOF
{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "aps:RemoteWrite",
            "aps:QueryMetrics",
            "aps:GetSeries",
            "aps:GetLabels",
            "aps:GetMetricMetadata"
         ],
         "Resource":"*"
      }
   ]
}
EOF
echo "${PERMISSION_POLICY}" > PermissionPolicy.json

#
# Create an IAM permission policy to be associated with the role, if the policy does not already exist
#
SERVICE_ACCOUNT_IAM_POLICY_ID=$(aws iam get-policy --policy-arn $SERVICE_ACCOUNT_IAM_POLICY_ARN --query 'Policy.PolicyId' --output text)
if [ "$SERVICE_ACCOUNT_IAM_POLICY_ID" = "" ]; 
then
  echo "Creating a new permission policy $SERVICE_ACCOUNT_IAM_POLICY"
  aws iam create-policy --policy-name $SERVICE_ACCOUNT_IAM_POLICY --policy-document file://PermissionPolicy.json 
else
  echo "Permission policy $SERVICE_ACCOUNT_IAM_POLICY already exists"
fi

#
# If the IAM role already exists, then just update the trust policy.
# Otherwise create one using the trust policy and permission policy
#
SERVICE_ACCOUNT_IAM_ROLE_ARN=$(aws iam get-role --role-name $SERVICE_ACCOUNT_IAM_ROLE --query 'Role.Arn' --output text)
if [ "$SERVICE_ACCOUNT_IAM_ROLE_ARN" = "" ]; 
then
  echo "$SERVICE_ACCOUNT_IAM_ROLE role does not exist. Creating a new role with a trust and permission policy"
  #
  # Create an IAM role for Kubernetes service account 
  #
  SERVICE_ACCOUNT_IAM_ROLE_ARN=$(aws iam create-role \
  --role-name $SERVICE_ACCOUNT_IAM_ROLE \
  --assume-role-policy-document file://TrustPolicy.json \
  --description "$SERVICE_ACCOUNT_IAM_ROLE_DESCRIPTION" \
  --query "Role.Arn" --output text)
  #
  # Attach the trust and permission policies to the role
  #
  aws iam attach-role-policy --role-name $SERVICE_ACCOUNT_IAM_ROLE --policy-arn $SERVICE_ACCOUNT_IAM_POLICY_ARN  
else
  echo "$SERVICE_ACCOUNT_IAM_ROLE_ARN role already exists. Updating the trust policy"
  #
  # Update the IAM role for Kubernetes service account with a with the new trust policy
  #
  aws iam update-assume-role-policy --role-name $SERVICE_ACCOUNT_IAM_ROLE --policy-document file://TrustPolicy.json
fi
echo $SERVICE_ACCOUNT_IAM_ROLE_ARN

# EKS cluster hosts an OIDC provider with a public discovery endpoint.
# Associate this Idp with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
# Doing this with eksctl is the easier and best approach.
#
eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve

Данный скрипт создаёт роль IAM со следующими правами доступа, называющуюся EKS-AMP-ServiceAccount-Role и связывает эту роль с учетной записью Kubernetes, называющейся iamproxy-service-account в пространствах имен prometheus и grafana.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "aps:RemoteWrite",
                "aps:QueryMetrics",
                "aps:GetSeries",
                "aps:GetLabels",
                "aps:GetMetricMetadata"
            ],
            "Resource": "*"
        }
    ]
}

Развертывание сервера Prometheus

Amazon Managed Service для Prometheus не собирает эксплуатационные метрики непосредственно из контейнеризированных рабочих нагрузок в кластере Kubernetes. Для выполнения этой задачи пользователям необходимо развернуть и настроить стандартный сервер Prometheus или агента OpenTelemetry, как, например, OpenTelemetry сборщик для AWS Distro, в своем кластере. В данной статье используется сервер Prometheus, который разворачивается на кластере Amazon EKS с помощью чартов Helm следующим образом:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
kubectl create ns prometheus
helm install prometheus-for-amp prometheus-community/prometheus -n prometheus

Теперь, прокси для подписи AWS может быть развернут в кластере Amazon EKS с использованием предоставленного манифеста YAML. Замените переменную {AWS_REGION} на соответствующее имя региона AWS, замените ${IAM_PROXY_PROMETHEUS_ROLE_ARN} на ARN созданного вами EKS-AMP-ServiceAccount-Role и замените {WORKSPACE_ID} на AMP ID рабочей среды, созданной вами ранее. Подписывающий прокси ссылается на образ Docker из публичного репозитория в ECR.

Создайте файл под названием amp_ingest_override_values.yaml со следующим содержимым.

serviceAccounts:
    server:
        name: "iamproxy-service-account"
        annotations:
            eks.amazonaws.com/role-arn: "${IAM_PROXY_PROMETHEUS_ROLE_ARN}"
server:
  sidecarContainers:
    aws-sigv4-proxy-sidecar:
        image: public.ecr.aws/aws-observability/aws-sigv4-proxy:1.0
        args:
        - --name
        - aps
        - --region
        - ${AWS_REGION}
        - --host
        - aps-workspaces.${AWS_REGION}.amazonaws.com
        - --port
        - :8005
        ports:
        - name: aws-sigv4-proxy
          containerPort: 8005
  statefulSet:
      enabled: "true"
  remoteWrite:
      - url: http://localhost:8005/workspaces/${WORKSPACE_ID}/api/v1/remote_write

Выполните следующую команду для изменения конфигурации сервера Prometheus, чтобы развернуть прокси для подписи и настроить конечную точку remoteWrite.

helm upgrade --install prometheus-for-amp prometheus-community/prometheus -n prometheus -f ./amp_ingest_override_values.yaml

После применения вышеуказанных конфигураций сервер Prometheus готов к сбору метрик с сервисов, развернутых в кластере, и отправке их в указанную рабочую среду Amazon Managed Service для Prometheus с помощью прокси для подписи AWS.

Приложение, оснащенное клиентской библиотекой Prometheus, теперь развернуто в виде набора реплик для кластера Amazon EKS. Оно отслеживает количество входящих HTTP-запросов с помощью счетчика Prometheus с именем http_requests_total и предоставляет эти данные по HTTP на конечной точке /metrics. При обращении к этой конечной точке выдается следующий результат, который периодически собирается сервером Prometheus.

# HELP http_requests_total Total number of HTTP requests.
# TYPE http_requests_total counter
http_requests_total{job="recommender",path="/user/product",} 86.0
http_requests_total{job="recommender",path="/popular/product",} 128.0
http_requests_total{job="recommender",path="/popular/category",} 345.0

Визуализация метрик с помощью Grafana

Метрики, собранные в рабочей среде Amazon Managed Service для Prometheus, могут быть визуализированы с помощью Grafana. В Grafana v7.3.x добавлена новая функция для поддержки аутентификации AWS Signature Version 4 (SigV4), и мы будем ее здесь использовать. Разверните самостоятельно управляемую Grafana в кластере Amazon EKS с помощью Helm-чартов, как показано ниже:

helm repo add grafana https://grafana.github.io/helm-charts
kubectl create ns grafana
helm install grafana-for-amp grafana/grafana -n grafana

Обновление сервера Grafana для использования прокси для подписи AWS.

Создайте новый файл и назовите его amp_query_override_values.yaml. Этот файл будет использован для обновления вашей установленной Grafana, чтобы включить протокол Sigv4, который прокси для подписи AWS использует для аутентификации.

serviceAccount:
    name: "iamproxy-service-account"
    annotations:
        eks.amazonaws.com/role-arn: "${IAM_PROXY_PROMETHEUS_ROLE_ARN}"
grafana.ini:
  auth:
    sigv4_auth_enabled: true

Теперь выполните следующую команду, чтобы обновить ваше окружение Grafana.

helm upgrade --install grafana-for-amp grafana/grafana -n grafana -f ./amp_query_override_values.yaml

Теперь вы можете получить доступ к Grafana, переадресовав порт на http://localhost:5001, используя следующую команду. Замените строку GRAFANA_POD_NAME на актуальное имя пода Grafana, который вы только что создали.

kubectl port-forward -n grafana pods/GRAFANA_POD_NAME 5001:3000

Затем откройте Grafana из интернет-браузера, используя вышеуказанный URL, и войдите в систему, указав имя admin. Пароль можно получить из секрета Kubernetes следующим образом:

kubectl get secrets grafana-for-amp -n grafana -o jsonpath='{.data.admin-password}'|base64 --decode

Прежде чем мы сможем визуализировать метрики в Grafana, необходимо настроить один или несколько источников данных. Здесь мы укажем рабочую среду внутри Amazon Managed Service для Prometheus в качестве источника данных, как показано ниже. В поле URL укажите адрес для запросов, отображаемый на странице детальной информации о рабочей среде AMP, без /api/v1/query в конце адреса.

Настройка источника данных AMP

Настройка источника данных AMP

Теперь вы готовы запросить метрики для счетчика Prometheus http_requests_total, хранящиеся в управляемой рабочей среде сервиса, и визуализировать частоту HTTP-запросов за 5-минутный период, используя запрос Prometheus, следующим образом: sum(rate(http_requests_total{exported_job=”recommender”}[5m])) by (path)

На рисунке ниже показано, как визуализировать эту метрику в Grafana для различных сегментов адреса URL, полученных в счетчике Prometheus.

PromQL и визуализация метрик

PromQL и визуализация метрик

В дополнение к служебным метрикам, собранным с рабочих нагрузок приложений, мы можем запросить системные метрики, собранные Prometheus для всех контейнеров и узлов в кластере Kubernetes. Например, счетчик Prometheus node_network_transmit_bytes_total фиксирует объем данных, переданных с каждого узла кластера. На рисунке ниже скорость передачи данных с каждого узла с помощью запроса Prometheus представлена следующим образом: sum(rate(node_network_transmit_bytes_total[5m])) by (instance)

PromQL визуализация данных метрик

PromQL визуализация данных метрик

Пользователи могут также визуализировать эти метрики, используя Amazon Managed Service для Grafana (AMG), как описано в этой статье.

Заключение

Prometheus — чрезвычайно популярный инструмент мониторинга с открытым исходным кодом, предоставляющий мощные возможности запросов и обладающий широкой поддержкой для различных рабочих нагрузок. В этой статье были описаны шаги, связанные с использованием Amazon Managed Service для Prometheus для безопасного получения, хранения и запроса метрик Prometheus, которые были собраны с рабочих нагрузок приложений, развернутых на Amazon EKS-кластере. Amazon Managed Service для Prometheus может также использоваться совместно с любой совместимой с Prometheus службой мониторинга и оповещения для сбора метрик из других контейнерных сред, таких как Amazon ECS, самостоятельно развернутого Kubernetes на AWS или локальной инфраструктуры. Рабочая среда Amazon Managed Service для Prometheus служит надежным источником данных для Grafana. Таким образом, пользователи могут визуализировать эти показатели с помощью самостоятельно развернутой Grafana или использовать Amazon Managed Service для Grafana.