前面介绍了 Prometheus AlertManager、Alertmanager 配置实现钉钉告警、Pushgateway、基于K8S服务发现、监控常见服务、配置 Grafana 展示与报警、高可用集群方案相关的知识点,今天我将详细的为大家介绍Prometheus 高可用架构 Thanos相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发朋友圈支持一波!!!
前面文章中有简单提到 Prometheus 的高可用方案,尝试了联邦、Remote Write 之后,我们最终选择了 Thanos 作为监控配套组件,利用其全局视图来管理我们的多地域、300+集群的监控数据。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
Prometheus 官方的高可用有几种方案:
使用官方建议的多副本 + 联邦仍然会遇到一些问题,本质原因是 Prometheus 的本地存储没有数据同步能力,要在保证可用性的前提下再保持数据一致性是比较困难的,基本的多副本 Proxy 满足不了要求,比如:
目前大多数的 Prometheus 的集群方案是在存储、查询两个角度上保证数据的一致:
随着我们的集群规模越来越大,监控数据的种类和数量也越来越多:如Master/Node 机器监控、进程监控、4 大核心组件的性能监控,POD 资源监控、kube-stats-metrics、K8S events监控、插件监控等等。除了解决上面的高可用问题,我们还希望基于 Prometheus 构建全局视图,主要需求有:
在调研了大量的开源方案(Cortex/Thanos/Victoria/StackDriver..)和商业产品之后,我们选择了 Thanos,准确的说 Thanos 只是监控套件,与原生 Prometheus 结合,满足了长期存储 + 无限拓展 + 全局视图 + 无侵入性的需求。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
Thanos 的默认模式:sidecar 方式。
绑定部署在Prometheus 实例上,当进行查询时,由thanos sidecar返回监控数据给Thanos QueryT对数据进行聚合与去重。最新的监控数据存放于Prometheus 本机(适用于Sidecar数量少,单个prometheus集群,查询响应快的场景)。
Prometheus 实例实时将数据 push 到 Thanos Receiver,最新数据也得以集中起来,然后 Thanos Query 也不用去所有 Sidecar 查最新数据了,直接查 Thanos Receiver 即可(适用于集群规模大,多个prometheus节点,跨集群查询响应慢的场景)。
下面会介绍如何组合 Thanos 组件,来快速实现你的 Prometheus 高可用,因为是快速介绍,和官方的 quick start有一部分雷同,不过会给出推荐配置。
thanos 是无侵入的,只是上层套件,因此你还是需要部署你的 Prometheus,这里不再赘述,默认你已经有一个单机的 Prometheus 在运行,可以是 pod 也可以是主机部署,取决于你的运行环境,我们是在 k8s 集群外,因此是主机部署。Prometheus 采集的是地域A的监控数据。你的 Prometheus 配置可以是。
启动配置:
./prometheus
--config.file=prometheus.yml \
--log.level=info \
--storage.tsdb.path=data/prometheus \
--web.listen-address='0.0.0.0:9090' \
--storage.tsdb.max-block-duration=2h \
--storage.tsdb.min-block-duration=2h \
--storage.tsdb.wal-compression \
--storage.tsdb.retention.time=2h \
--web.enable-lifecycle
web.enable-lifecycle一定要开,用于热加载时 reload 你的配置,retention 保留 2 小时,Prometheus 默认 2 小时会生成一个 block,Thanos 会把这个 block 上传到对象存储。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
采集配置:prometheus.yml
global:
scrape_interval: 60s
evaluation_interval: 60s
external_labels:
region: 'A'
replica: 0
rule_files:
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['0.0.0.0:9090']
- job_name: 'demo-scrape'
metrics_path: '/metrics'
params:
...
这里需要声明 external_labels,标注你的地域。如果你是多副本运行,需要声明你的副本标识,如 0号,1,2 三个副本采集一模一样的数据,另外2个 Prometheus 就可以同时运行,只是 replica 值不同而已。这里的配置和官方的 Federation方案差不多。
对 Prometheus 的要求:
–-web.enable-admin-api
-–web.enable-lifecycle
关键的步骤来了,最核心莫过于 sidecar 组件。sidecar是 k8s 中的一种模式。Sidecar 组件与 Prometheus server 部署于同一个 pod 中。他有两个作用:
当然,这不意味着 Prometheus 可以是完全无状态的,因为如果它崩溃并重新启动,您将丢失2个小时的指标,不过如果你的 Prometheus 也是多副本,可以减少这 2h 数据的风险。
sidecar配置:
./thanos sidecar \
--Prometheus.url="http://localhost:8090" \
--objstore.config-file=./conf/bos.yaml \
--tsdb.path=/home/work/opdir/monitor/Prometheus/data/Prometheus/
配置很简单,只需要声明 Prometheus.url 和数据地址即可。objstore.config-file 是可选项。如果你要把数据存放在对象存储(这也是推荐做法),就配置下对象存储的账号信息。
Thanos 默认支持谷歌云/AWS 等,以 谷歌云为例,配置如下:
type: GCS
config:
bucket: ""
service_account: ""
因为 Thanos 默认还不支持我们的云存储,因此我们在 Thanos 代码中加入了相应的实现,并向官方提交了 PR。
需要注意的是:别忘了为你的另外两个副本 1号 和 2号 Prometheus 都搭配一个 sidecar。如果是 pod运行可以加一个 container,127 访问,如果是主机部署,指定 Prometheus 端口就行。
另外 sidecar 是无状态的,也可以多副本,多个 sidecar 可以访问一份 Prometheus 数据,保证 sidecar 本身的拓展性,不过如果是 pod 运行也就没有这个必要了,sidecar 和 Prometheus 同生共死就行了。
sidecar 会读取 Prometheus 每个 block 中的 meta.json 信息,然后扩展这个 json 文件,加入了 Thanos 所特有的 metadata 信息。而后上传到块存储上。上传后写入 thanos.shipper.json 中。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
sidecar 部署完成了,也有了3个一样的数据副本,这个时候如果想直接展示数据,可以安装 query 组件。
Query 组件(也称为“查询”)实现了 Prometheus 的 HTTP v1 API,可以像 Prometheus 的 graph一样,通过 PromQL 查询 Thanos 集群中的数据。 简而言之,sidecar 暴露了 StoreAPI,Query 从多个 StoreAPI 中收集数据,查询并返回结果。Query 是完全无状态的,可以水平扩展。
配置:
./thanos query \
--http-address="0.0.0.0:8090" \
--store=relica0:10901 \
--store=relica1:10901 \
--store=relica2:10901 \
--store=127.0.0.1:19914 \
store 参数代表的就是刚刚启动的 sidecar 组件,启动了 3 份,就可以配置三个relica0、relica1、relica2,10901 是 sidecar 的默认端口。 http-address 代表 query 组件本身的端口,因为他是个 web 服务,启动后,页面是这样的:
和 Prometheus 几乎一样对吧,有了这个页面你就不需要关心最初的 Prometheus 了,可以放在这里查询。
点击 store,可以看到对接了哪些 sidecar。
query 页面有两个勾选框,含义是:
你可能注意到了,在第 3 步里,./thanos query
有一条–store是 xxx:19914,并不是一直提到的 3 副本,这个 19914 就是接下来要说的 store gateway组件。
在第 2 步的 sidecar 配置中,如果你配置了对象存储 objstore.config-file,你的数据就会定时上传到 bucket 中,本地只留 2 小时,那么要想查询 2 小时前的数据怎么办呢?数据不被 Prometheus 控制了,应该如何从 bucket 中拿回来,并提供一模一样的查询呢?
Store gateway 组件:store gateway 主要与对象存储交互,从对象存储获取已经持久化的数据。与sidecar一样,store gateway也实现了 store api,query 组可以从 store gateway 查询历史数据。
配置如下:
./thanos store \
--data-dir=./thanos-store-gateway/tmp/store \
--objstore.config-file=./thanos-store-gateway/conf/bos.yaml \
--http-address=0.0.0.0:19904 \
--grpc-address=0.0.0.0:19914 \
--index-cache-size=250MB \
--sync-block-duration=5m \
--min-time=-2w \
--max-time=-1h \
grpc-address 就是 store api 暴露的端口,也就是 query 中–store 是 xxx:19914的配置。
因为Store gateway需要从网络上拉取大量历史数据加载到内存,因此会大量消耗 cpu 和内存,这个组件也是 thanos 面世时被质疑过的组件,不过当前的性能还算可以,遇到的一些问题后面会提到。
Store gateway也可以无限拓展,拉取同一份 bucket 数据。 放个示意图,一个 Thanos 副本,挂了多个地域的 store 组件。
其中一个地域的数据统计:查询一个月历史数据速度还可以,主要是数据持久化没有运维压力,随意扩展,成本低。
到这里,Thanos 的基本使用就结束了,至于 compact 压缩和 bucket 校验,不是核心功能,compact的资源消耗也特别大,rule组件我们没有使用,就不做介绍了。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
有了多地域多副本的数据,就可以结合 Grafana 做全局视图了,比如:
按地域和集群查看 ETCD 的性能指标:
按地域、集群、机器查看核心组件监控,如多副本 Master 机器上的各种性能。
数据聚合在一起之后,可以将所有视图都集中展示,比如还有这些面板:
压缩:官方文档有提到,使用 sidecar 时,需要将 Prometheus 的 --storage.tsdb.min-block-duration
和 --storage.tsdb.max-block-duration
这两个值设置为2h,两个参数相等才能保证Prometheus 关闭了本地压缩,其实这两个参数在 Prometheus -help
中并没有体现,Prometheus 作者也说明这只是为了开发测试才用的参数,不建议用户修改。而 Thanos 要求关闭压缩是因为 Prometheus 默认会以2,25,25*5的周期进行压缩,如果不关闭,可能会导致 thanos 刚要上传一个 block,这个 block 却被压缩中,导致上传失败。
不过你也不必担心,因为在 sidecar 启动时,会检查这两个参数,如果不合适,sidecar会启动失败。
store-gateway: store 组件资源消耗是最大的,毕竟他要拉取远程数据,并加载到本地供查询,如果你想控制历史数据和缓存周期,可以修改相应的配置,如:
--index-cache-size=250MB \
--sync-block-duration=5m \
--min-time=-2w \ 最大查询 1 周
--max-time=-1h \
store-gateway 默认支持索引缓存,来加快 TSDB 块的查找速度,但有时候启动会占用了大量的内存,在 0.11.0之后的版本做了修复。
Prometheus 2.0 已经对存储层进行了优化。例如按照时间和指标名字,连续的尽量放在一起。而 store gateway可以获取存储文件的结构,因此可以很好的将指标存储的请求翻译为最少的 object storage 请求。对于那种大查询,一次可以拿成百上千个 Chunks 数据。
而在 store 的本地,只有 Index 数据是放入 Cache 的,Chunk 数据虽然也可以,但是就要大几个数量级了。目前,从对象存储获取 Chunk 数据只有很小的延时,因此也没什么动力去将 Chunk 数据给 Cache起来,毕竟这个对资源的需求很大。
store-gateway中的数据:
每个文件夹中其实是一个个的索引文件 index.cache.json。更多关于企业级监控平台系列的学习文章,请参阅:构建企业级监控平台,本系列持续更新中。
Prometheus 数据越来越多,查询一定会越来越慢,Thanos 提供了一个 compactor 组件来处理,他有两个功能。
注意的是 Compactor 并不会减少磁盘占用,反而会增加磁盘占用(做了更高维度的聚合)。
thanos 组件的优化并不是万能的,因为业务数据总在增长,这时候可能要考虑业务拆分了。我们需要对业务有一定的划分,不同的业务监控放在不同bucket里(需要改造或者多部署几个 sidecar)。例如有5个 bucket ,再准备5个 store gateway 进行代理查询。减少单个 store 数据过大的问题。
第二个方案是时间切片,也就是上面提到的 store gateway,可以选择查询多长时间的数据。store gateway配置支持两种表达式,一种是基于相对时间的,例如–max-time 是3d前到5d前的。一种是基于绝对时间的,如19年3月1号到19年5月1号。例如想查询3个月的数据,一个 store 可以代理一个月的数据,那么就需要部署3个store来合作。
query 组件启动时,默认会根据 query.replica-label 字段做重复数据的去重,你也可以在页面上勾选deduplication 来决定。query 的结果会根据你的 query.replica-label的 label 选择副本中的一个进行展示。可如果 0,1,2 三个副本都返回了数据,且值不同,query 会选择哪一个展示呢?
Thanos 会基于打分机制,选择更为稳定的 replica 数据, 具体逻辑在:https://github.com/thanos-io/thanos/blob/55cb8ca38b3539381dc6a781e637df15c694e50a/pkg/query/iter.go。
使用thanos querier调试PromQL和prometheus上调试别无二致,最主要的一点是记得选择“Use Deldupication“ 删除重复数据。
grafana创建数据源时,由于thanos-query和grafana同属一个namespace,所以url地址填写thanos-query:9090即可。如果位于不同namespace,url地址填写为:http://(servicename).(namespace).svc.cluster.local:9090。
然后从grafana官网dashboard导入对应的dashboard即可。
以上就是今天要讲解目前比较流行的方案:Thanos,它完全兼容 Prometheus API,提供统一查询聚合分布式部署 Prometheus 数据的能力,同时也支持数据长期存储到各种对象存储(比如 S3、阿里云 OSS 等)以及降低采样率来加速大时间范围的数据查询。
参考来源:http://www.xuyasong.com/?p=1925 https://www.cuiliangblog.cn/detail/article/30