最近因为工作需要,评估了一下 AWS托管Prometheus 服务(简称 AMP)。本文记录了一下在评估过程中产生的体会。

AMP是什么,以及AMP不是什么

AWS自己官方的说法是:Amazon Managed Service for Prometheus is a serverless, Prometheus-compatible monitoring service 。但就我自己评估下来的体验来看,他不像是一个托管版本的 Promethues,而更像是一个 远程存储查询 服务。特点就是支持Prometheus Remote Write协议的写入,以及PromQL语法的查询。

在使用上,AMP也是需要搭配用于采集的客户端代理来使用。通常,这个客户端代理是Promethues,或者Open Telemetry。这个客户端代理,完成了采集目标的自动发现和采集的核心功能,只是写入数据的时候,使用Remote Write协议写入AMP而已。

通常情况下,如果你的Prometheus部署在有持久化数据存储的环境中,比如单独的虚拟机、Kubernetes的Stateful,那么你没必要使用AMP。

反过来,如果你的Prometheus部署在不具备持久化数据存储的环境中,比如Kubernetes的Deployment,那么可以搭配AMP实现稳定的、不依赖运行环境磁盘的数据存储。

AMP数据采集的权限控制

AMP的其实本身并不采集数据,而是由真正的采集客户端代理采集后,通过Remote Write进行投递。因此,这里的权限控制,说的就是采集代理如何获取AMP的Remote Write写数据授权。

AWS文档中提到了两类采集客户端代理:Prometheus、Open Telemetry。后者又分为开源版本和AWS维护版本(AWS Distro)。我的评估场景中没有使用Open Telemetry,因此这里跳过不说,只说说我使用的Prometheus这种采集代理。

AMP的Remote Write接口,使用的是名为Sigv4的授权机制。Prometheus自带对这种授权机制的支持。我们需要做的,其实只是配置一下而已。主要包括几个步骤:

  • 创建一个AWS的IAM角色,给该角色授予 AmazonPrometheusRemoteWriteAccess 权限,故名思义,就是让该角色可以写入AMP数据。
  • 将创建的角色附加到Prometheus的运行环境中。比如AWS的EC2、EKS集群,或者Kubernetes集群内POD绑定的一个ServiceAccount。
  • 配置Prometheus启用RemoteWrite。主要包括两个配置项, remote_write.urlremote_write.sigv4.region ,前者配置为AMP的写入端点即可,后者配置为AMP所在的可用区。其他 remote_write.queue_config 按照实际需求配置即可。

这几个步骤,其实和几乎所有基于IAM授权的机制都是一样的。背后的原理,就是几乎所有AWS的服务,都是通过其官方SDK接入的。官方SDK的授权机制,大概包括几种:

  • 从环境变量中获取。
  • ~/.aws/credential 或者 ~/aws/config 获取。
  • 从运行环境中获取。

前面两种,都需要使用者明确设置Access Key和Secret Key,因此可以用于任何环境中。

最后一种只能用于AWS环境中,比如AWS的EC2、EKS集群、Fargate集群等。大致的原理,大家可以理解成,在AWS云内部,提供了一些特殊、只能在aws内部访问的API。这些API可以自动根据访问来源(比如内网IP),动态通过IAM获取其权限。

AMP数据查询的权限控制

完成数据采集后,最重要的就是通过查询,来验证数据采集是否正确。可惜的是AMP本身并不提供这个功能。哪怕是像Prometheus那样,提供一个最简单的PromQL查询界面,都没有。因此,我们还需要额外找一个Grafana之类的工具,用于查询并可视化AMP中的数据。

查询的授权机制,原理上和采集是一致的。用于查询和可视化的Grafan,本身也提供了对AWS的Sigv4授权机制的支持。但是配置上稍显复杂一些。

首先,Grafana对Sigv4的支持,默认是关闭的,至于为啥代码都支持了却默认关闭,我也不知道。这就导致默认情况下,你添加Prometheus数据源的时候,根本就看不到Sigv4这个授权选项。很多人搞不好还以为是版本问题,或者有什么BUG。

要打开这个功能,直接在Grafana中,配置 auth.sigv4_auth_enabledtrue 。你可以直接在配置文件中修改,或者通过环境变量 GF_AUTH_SIGV4_AUTH_ENABLED=true 来配置。

在打开了Grafana对Sigv4的支持后,我们还需要将AMP添加为一个Grafana数据源。具体如下:

  • 打开Grafana的数据源管理页面,数据源类型选择 Prometheus
  • 数据源配置中,HTTP 区的URL项填AMP的查询URL。注意要把查询URL尾巴上的 /api/v1/query去掉。
  • Auth 区中打开 SigV4 Auth 认证方式。
  • SigV4 Auth Detail中配置授权(下文详说)。
  • Save & Test保存并验证。

关于 SigV4 Auth Detail的配置,门道比较多。AMP的文档里,只是笼统的让配置GF_AUTH_SIGV4_AUTH_ENABLED、AWS_SDK_LOAD_CONFIG两个环境变量为true。但实际上,只有GF_AUTH_SIGV4_AUTH_ENABLED是必须配置的,而AWS_SDK_LOAD_CONFIG根据具体使用场景不同而不同。具体来说,包括两种场景:

  • 明确指定Access Key和Secret Key
  • 不明确指定,而是通过所在的环境自动认证

第一种场景,需要先在IAM上创建一个用户,直接或者通过角色授予他 AmazonPrometheusQueryAccess 的权限。然后参照下面的方式配置SigV4 Auth Detail

  • Authentication Provider:选Access & secret key
  • Access Key IDSecret Access Key:分别配置IAM用户的密钥;
  • Assume Role ARNExternal ID留空
  • Default Region:设置为AMP所在的可用区
  • !!重点!!:到这里就结束了。 不需要设置AWS_SDK_LOAD_CONFIG环境变量 也不需要给Prometheus所在的环境(比如EC2)附加任何的角色

第二种场景,不明确指定Access Key和Secret Key,而是通过所在的环境认证

  • **!!重点!!**必须在运行Grafana的时候,设置AWS_SDK_LOAD_CONFIG环境变量为true。这个环境变量并不是Grafana直接使用的,而是AWS自己使用的,因此在Grafana的文档里找不到。

  • Authentication Provider:选AWS SDK Default

  • Access Key IDSecret Access Key:你应该看不到这两个配置项,所以不用填;

  • Assume Role ARNExternal ID留空

  • Default Region:设置为AMP所在的可用区

参照上面说的两种场景配置之后,Grafana应该就可以拉到AMP里的数据了。

怎么评估AMP的成本

亚马逊的成本计算,向来都是巨仔细,同时也巨复杂的。AMP也不例外,具体的计费大家可以参考一下AMP Pricing。这里只是说一下我的个人理解。

首先,AMP计费包括几个计费点:

  • 指标存储:$0.03/GB-Mo
  • 指标抓取:起步$0.9/10M samples,越多越便宜
  • 指标查询:$0.1/B samples processed

指标存储

这个比较简单,就是按照你存储的数据量直接计算的。由于指标数据是会过期的,每天有数据新增、也有数据过期删除。因此长时间使用后,指标的数据量相对是稳定的。一个简单的估算方式,就是自己先用Prometheus存储在磁盘,看看每天的磁盘可用空间的变化,假如是1个GiB。那么按照保存120天来看。那么120天以后,数据量就是稳定的120GiB了。按照0.03的单价计算,一个月就3.6美元,也算是白菜价了,可以忽略。

指标抓取

指标抓取的费用,是按照sample,也就是采样点数量来计算的。一个指标采集一次,算一个sample。假如我们配置的采样周期是15s,那就意味着:

  • 一分钟采60/15=4次;
  • 一个小时4*60=240次;
  • 一天240*24=5760次;
  • 一个月5760*30=172800次。

也就是会所,对于一个指标,我们每次采集到的话,我们总共采集的采样点(samples)有172800个。那么问题来了,什么叫做一个指标呢?

比如,我们有一个用来统计HTTP请求数量的指标 http_request_total。假定他只包括method、path两个label。我们需要用类似 http_request_total{method=“POST”,path="/login"} 这样的、即包括指标名、也包括所有label及其确定值来标识 一个 指标。而不仅仅是用指标名 http_request_total 代表 一个指标。

因此,假如 method 有五个值(比如,GET/POST/PUT/PATCH/DELTE),path有四个值(比如login/logout/index/show),那么实际上名为 http_request_total 的指标,总共有5✖️4=20个,而不是一个。

要评估指标的数量,理论上有一个简单的方法,就是手动去Prometheus的抓取目标中,通过 /metrics 接口返回的数据统计。不过这种方法返回的不一定准确,因为指标是随时动态变化的,每一次抓取到的指标都不一定一样。有的指标可能这一次有、下一次就没有了。

还有一个比较粗暴的方式,就是先把指标投递到AMP,然后通过Cloudwatch中 AWS/Usage 命名空间中 ActiveSeries 指标的最大值,来评估到底有多少指标。

还是举个例子来说:

假如我们有100个指标名,每个指标名平均的label组合有100个。那么我们就大概有10000个指标,一天采集下来采样点就有10000*172800=1728Million个。按照0.09/10Million的单价,一个月的成本大概就是15美元。

指标查询

指标查询的成本计算逻辑,和指标抓取是一致的,但是更不好估算,原因有二:

  • 首先,指标查询既包括像告警这种周期性的查询,也包括查看监控这种临时性的查询,不好预估;
  • 其次,每次查询表达式写得不一样(比如时间范围不同、查询条件不同),导致最后查出来的数据量会有很大的差距。

因此这里就不再赘述了。