专栏首页云原生生态圈Cortex: 高可用和水平扩展Prometheus监控系统

Cortex: 高可用和水平扩展Prometheus监控系统

Prometheus已成为cloud-native世界中的默认监控应用程序和系统。对于真实使用案例,Prometheus应该是高可用的,这是有挑战的。一旦在高可用性模式下[1]运行?Prometheus,就会遇到很多问题,例如数据重复,为重复数据实现single pane等。为了解决此问题,Cortex诞生了。Cortex[2]是一个CNCF sandbox project[3],旨在为使用Prometheus [4]收集的指标提供长期存储和全局指标视图。首先让我们看一下Cortex的主要目标,然后看一下它为Prometheus解决的一些问题。

  • 水平可伸缩性– Cortex可以分成多个微服务,每个微服务都可以独立地水平伸缩。例如,如果许多Prometheus实例正在向Cortex发送数据,则可以扩展Ingester微服务。如果cortex有许多的查询,则可以扩展QuerierQuery Frontend微服务。
  • 高可用性– Cortex可以在实例之间复制数据replicate data。这样可以防止数据丢失,并避免度量标准数据出现间断,即使发生机器故障and/orpod被驱逐。
  • 多租户–多个不受信任的parties可以共享同一群集。Cortex在从ingesterquerying的整个生命周期中提供数据隔离。这对于为多个单元或应用程序存储数据的大型组织或运行SaaS服务的人员非常有用。
  • 长期存储– Cortex将数据分块存储并为其生成索引。可以将Cortex配置为将其存储在自托管或云提供商支持的数据库或对象存储中。

Cortex的需求

Prometheus高可用性和数据去重

Prometheus默认情况下不具有高可用性。使Prometheus高可用的一种方式是运行多个实例去scraping相同的作业。这些实例在抓取指标时会因微小的时间间隔差异而在数据中产生细微差异。此外,如果其中一个实例宕机了几个小时,那么当查询转发到该实例时,将会出现数据空白。如果我们使用grafana这样的工具将指标展示为图形,我们可能会得到不同的样本值或有数据缺失的图形。

可以将Cortex配置为从多个HA Prometheus实例读取数据。它从一个主实例main接受指标,并从其他实例放弃该度量。一旦这个副本掉线,Cortex会无缝切换到另一副本并将其标记为主副本main。为此,Cortex着眼于两个标签,一个共同的标签与一个集群(或一组Prometheus)相关联,另一个识别副本。

全局指标视图

可以将Prometheus实例配置为对cortex执行远程写入。使用此功能,指标可以从多个集群聚合到一个运行cortes的集群中。这为我们提供了一个中心位置,在这里我们可以观察整个基础设施的指标。Cortex提供了与Prometheus/PromQL兼容的端点endpoint。可以将此端点endpoint作为数据源提供给grafana,并与普通Prometheus实例相同的方式执行查询。

长期储存

普罗米修斯的本地存储不是持久的长期存储。发送到cortex的指标被存储在已配置的存储服务中。如果使用云存储,这将使您从运行自己的数据库的麻烦中解脱出来。你还可以享受云提供商提供的SLA。Cortex还支持用于存储块的对象存储:

  • GCS
  • S3

多租户

当向cortex写入指标时,通过设置http头(X-Scope-OrgID)来提供多租户。查询时必须提供相同的值。在下面的例子中,这个headers是使用nginx反向代理设置的。

架构图

Cortex架构

Cortex架构(源)[5]

  • Nginx/gateway–一个位于cortex前面的反向代理,将收到的所有请求转发给相应的服务。
  • 分发服务器Distributor–处理传入的指标,将其拆分为多个批次,然后将其传递给Ingesters。如果复制因子replication factor设置为> 1,则数据将发送到多个实例。
  • 接收器Ingester–此服务负责将数据写入已配置的存储后端。Ingester是半状态的,因为它们保留了最后12个小时的样本。这些样本将被批处理并压缩,然后再写入块存储。
  • 查询前端Query Frontend–一个可选组件,用于对查询请求进行排队,并在失败时重试它们。结果也被缓存以提高性能
  • 查询器Querier–查询器处理PromQL的求值。如果是最近的数据,则从大块存储和或内部获取样本

其他组件:

  • Ruler–处理alertmanager产生的警报
  • Alertmanager –评估警报规则
  • ConfigsAPI –在Postgres中存储RulerAlertmanager的配置
  • Table Manager–负责在选定的块chunk/索引index存储后端中创建表
  • Consul –存储分发服务器distributor生成的一致的哈希环(hash ring)。分发服务器在发送指标时使用散列值来选择ingester。

与其他选项的异同

Thanos

?Thanos和Cortex具有非常相似的目标:聚合指标,将其存储在块存储中,并为所有度量使用一块single pane。因此,两个项目重用大量Prometheus代码也就不足为奇了。但是,有一些关键差异可能会帮助您决定使用哪个。

Thanos

Cortex

最近的数据存储在Prometheus中

最近的数据存储在Ingesters中(Cortex组件)

使用可以将数据写入块存储的Sidecar

通过prometheus的远程写将数据发送到cortex

单租户

多租户

手动分片

根据标签自动分片数据

Prom TSDB块

索引块 index

下采样:历史数据可以汇总(例如,将5秒的样本平均为1分钟的样本)

查询分片(将30天转换为30天的一天查询)

需要Ingress到运行Prometheus的集群中进行查询

运行Prometheus的集群仅需要出口Egress

演练

让我们通过安装一个真实的示例并通过多个Prometheus和Grafana对其进行配置以可视化数据来试用Cortex。

git clone https://github.com/kanuahs/cortex-demo.git
cd cortex-demo

Prometheus and Cortex with Docker Compose

为了简单设置,我们将使用docker-compose启动以下服务:

  • 三个Prometheus容器
  • Consul
  • 三个Cortex容器
  • Grafana

为了简单起见,我们将使用多功能的cortex配置。这将cortex作为一个独立的应用程序运行。我们将运行它的三个实例来检查复制。有三个Prometheus配置文件。它们具有外部标签,在执行远程写入时将标签添加到所有指标。Prometheus1和Prometheus3容器写入Cortex1,而Prometheus2容器写入Cortex2。我们将在Cortex3上运行查询。以下代码片段显示了三个Prometheus实例的配置差异。

# Prometheus one
global:
  # ...
  external_labels:
    cluster: two
# ...
remote_write:
- url: http://cortex2:9009/api/prom/push

# Prometheus two
global:
  # ...
  external_labels:
    cluster: two
# ...
remote_write:
- url: http://cortex1:9009/api/prom/push

# Prometheus three
global:
  # ...
  external_labels:
    cluster: tree
# ...
remote_write:
- url: http://cortex1:9009/api/prom/push

使用docker-compose启动所有服务。

docker-compose -f docker-demo/docker-compose.yaml up

转到http://localhost:3000/explore,使用凭据admin/admin登录,然后选择cortex3作为数据源。运行示例查询(例如up)Cortex将返回所有3个Prometheus容器的指标:

完成后,运行以下命令进行清理

docker-compose -f docker-demo/docker-compose.yaml down

在Kubernetes中部署Cortex以及Prometheus的依赖

如架构所示,我们将Cortex部署为一组微服务。我们还需要Helm来部署依赖项(Cassandra)和其他服务(Grafana,Prometheus)。如果尚未安装Helm,则可以按照Helm文档中的快速入门指南进行操作[6]。让我们开始吧,首先我们将部署cortex组件。

kubectl apply -f k8s/

我们还将使用Helm安装Prometheus。下面的命令将为我们完成这两项工作:

  • 创建一个名为" cluster"的外部标签,并将该标签的值设置为"one"。这将有助于分离不同的Prometheus实例
  • 设置cortex的远程写入。
helm install stable/prometheus \
 --name prom-one \
 --set server.global.external_labels.cluster=one \
 --set serverFiles."prometheus\.yml".remote_write[0].url=http://nginx.default.svc.cluster.local:80/api/prom/push

现在,我们将部署Grafana。下面的命令使用Grafana的配置[7]功能在Pod启动时将Cortex添加为数据源。

helm install stable/grafana --name=grafana \
 --set datasources."datasources\.yaml".apiVersion=1 \
 --set datasources."datasources\.yaml".datasources[0].name=cortex \
 --set datasources."datasources\.yaml".datasources[0].type=prometheus \
 --set datasources."datasources\.yaml".datasources[0].url=http://nginx.default.svc.cluster.local/api/prom \
 --set datasources."datasources\.yaml".datasources[0].access=proxy \
 --set datasources."datasources\.yaml".datasources[0].isDefault=true 

kubectl port-forward svc/grafana 3000:80

运行以下命令以获取Grafana管理员密码。之后,打开localhost:3000/explore并使用用户名"admin"和打印的密码登录。

kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

以下是一些示例查询,您可以运行这些查询来测试Prometheus是否向Cortex发送指标:

up{cluster="one"}
prometheus_tsdb_head_samples_appended_total{cluster="one"}

Cleanup

kubectl delete -f k8s/
helm delete --purge prom-one
helm delete --purge grafana

ingester pods将卡在终止阶段。这是设计使然的,因为ingester是半状态的,并且将在终止之前尝试将其数据刷新到其他ingester。这使得升级和回滚成为可能,同时避免了数据丢失。在这种情况下,我们只是尝试一下,而不关心数据,因此我们可以使用以下命令强制将其删除:

kubectl delete pod -l name=ingester --grace-period=0 --force

具有数据去重功能的HA Prometheus设置

此设置与上一个非常相似。主要区别在于我们正在部署两个Prometheus实例。两者都具有被设置为相同值"one"的集群标签和唯一的副本标签。分发器组件已配置为基于这两个标签执行重复数据删除。如果Cortex在当前规定的时间(超过30秒)内没有从当前副本接收指标,它将故障转移到下一个发送样本的副本。

kubectl apply -f k8s-ha/

helm install stable/prometheus \
--name prom-one \
--set server.global.external_labels.cluster=one \
--set server.global.external_labels.replica=one \
--set serverFiles."prometheus\.yml".remote_write[0].url=http://nginx.default.svc.cluster.local:80/api/prom/push

helm install stable/prometheus \
--name prom-two \
--set server.global.external_labels.cluster=one \
--set server.global.external_labels.replica=two \
--set serverFiles."prometheus\.yml".remote_write[0].url=http://nginx.default.svc.cluster.local:80/api/prom/push

helm install stable/grafana --name=grafana \
--set datasources."datasources\.yaml".apiVersion=1 \
--set datasources."datasources\.yaml".datasources[0].name=cortex \
--set datasources."datasources\.yaml".datasources[0].type=prometheus \
--set datasources."datasources\.yaml".datasources[0].url=http://nginx.default.svc.cluster.local/api/prom \
--set datasources."datasources\.yaml".datasources[0].access=proxy \
--set datasources."datasources\.yaml".datasources[0].isDefault=true

kubectl port-forward svc/grafana 3000:80

运行以下命令以获取grafana管理员密码。之后,打开localhost:3000/explore并使用用户名"admin"和打印的密码登录。

kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

以下是一些示例查询,您可以运行这些查询来测试Prometheus是否向Cortex发送指标:

up{cluster="one"}
prometheus_tsdb_head_samples_appended_total{cluster="one"}

要测试HA,我们可以尝试删除Prometheus窗格之一。

kubectl delete pod -l app=prometheus,component=server,release=prom-one

Grafana图中应该没有数据缺失,因为Cortex将故障转移到另一个实例。

清理

kubectl delete -f k8s/
helm delete --purge prom-one
helm delete --purge prom-two
helm delete --purge grafana

使用Cassandra作为索引和块存储

在前两个示例中,我们使用dynamodb-local作为索引存储,并使用fakes3作为块存储。在此示例中,我们将使用Apache Cassandra进行索引存储和块存储。

以下命令将启用helm incubator repo,使用helm安装Cassandra,并等待3个副本准备就绪。

helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/
helm install --wait --name=cassie incubator/cassandra

准备好Cassandra后,继续安装所有其他服务。

kubectl apply -f k8s-cassandra/

helm install stable/prometheus \
--name prom-one \
--set server.global.external_labels.cluster=one \
--set serverFiles."prometheus\.yml".remote_write[0].url=http://nginx.default.svc.cluster.local:80/api/prom/push

helm install stable/grafana --name=grafana \
--set datasources."datasources\.yaml".apiVersion=1 \
--set datasources."datasources\.yaml".datasources[0].name=cortex \
--set datasources."datasources\.yaml".datasources[0].type=prometheus \
--set datasources."datasources\.yaml".datasources[0].url=http://nginx.default.svc.cluster.local/api/prom \
--set datasources."datasources\.yaml".datasources[0].access=proxy \
--set datasources."datasources\.yaml".datasources[0].isDefault=true 
kubectl port-forward svc/grafana 3000:80

运行以下命令以获取Grafana管理员密码。之后,打开localhost:3000/explore并使用用户名admin和打印的密码登录。

kubectl get secret --namespace default grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

以下是一些示例查询,您可以运行这些查询来测试Prometheus是否向Cortex发送指标:

up{cluster="one"}
prometheus_tsdb_head_samples_appended_total{cluster="one"}

清理

kubectl delete -f k8s/
helm delete --purge cassie
helm delete --purge prom-one
helm delete --purge grafana

结论

Cortex是一个强大的工具,可无缝地运行多个Prometheus服务器,同时简化了用户的操作和使用。虽然Thanos确实提供了非常相似的功能,但它们的实现方式却大不相同。通过尝试实现的用例将推动选择Cortex与Thanos。但是,Cortex确实使运行高度可扩展且具有弹性的基于Prometheus的监视系统变得容易。

  • 翻译: 云原生生态圈 · Marionxue
  • 作者: By Shaunak Deshmukh
  • 原文: https://www.infracloud.io/blogs/cortex-prometheus-ha/

参考资料

[1]

高可用模式: https://prometheus.io/docs/introduction/faq/#can-prometheus-be-made-highly-available

[2]

Cortex: https://github.com/cortexproject/cortex

[3]

CNCF-sandbox: https://github.com/cortexproject/cortex

[4]

Prometheus: https://prometheus.io

[5]

Cortex Architechure With Nginx: https://github.com/cortexproject/cortex/blob/master/docs/architecture.md

[6]

Helm Quickstart: https://helm.sh/docs/using_helm/#quickstart

[7]

Grafana Provision: https://grafana.com/docs/administration/provisioning/

本文分享自微信公众号 - 云原生生态圈(CloudNativeEcoSystem),作者:Marionxue

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微软出品·kubernetes最新学习指南 v3.0

    Kubernetes正在席卷应用开发世界。到2022年,全球超过75%的组织将在生产环境中运行容器化应用程序。Kubernetes正在塑造应用程序开发和管理的未...

    公众号: 云原生生态圈
  • 轻松爬取拉勾网招聘岗位信息

    最近发现一些朋友想要跳槽,正值疫情,也不知道现在市场的如何,同时目前的IT行业更是越来越难,技术革新越来越快,对新的岗位的需求也是不断的变化,因此就会想知道现在...

    公众号: 云原生生态圈
  • Logoly-P站&YouTobe风格Logo在线生成器

    最近发现很多的微信文章上出现了一种logo设计,跟P站的logo设计风格一样让人印象深刻,黑底白字,配上一小撮橙色,给人极强的冲击力。后来查了一下在Github...

    公众号: 云原生生态圈
  • 监控神器Prometheus用不对,也就是把新手村的剑

    监控系统的历史悠久,是一个很成熟的方向,而 Prometheus 作为新生代的开源监控系统,慢慢成为了云原生体系的事实标准,也证明了其设计很受欢迎。

    lyb-geek
  • 如何使用Prometheus监视您的Ubuntu 14.04服务器

    Prometheus是由SoundCloud开发的开源监控系统。与其他监控系统(如InfluxDB和Graphite)一样,Prometheus将其所有数据存储...

    尘埃
  • 雷军的互联网思维OUT了,李彦宏号召全行业切换到AI思维

    今天,一年一度的百度联盟峰会在重庆举办。这个大会已有十五年历史,是百度面向联盟生态伙伴的大会,李彦宏每年都会在这个大会上展望未来,比如去年就提出“人工智能是互联...

    罗超频道
  • AI“军备竞赛”决战中美,美正在丧失垄断优势?|纽约时报长文

    大数据文摘
  • 机器认知、人机交互、边缘计算……在这里,他们谈论了关于AI的关键议题

    这些在AI领域时刻被探讨的话题,在今天的2019中国(深圳)IT领袖峰会上,有了一些不一样的答案。

    镁客网
  • 让吉他爬格子生动活泼起来

    爬格子是任何一个学吉他的人都无法避免的经历,而且爬格子会上瘾,因为爬格子不需要太多的思考,当我拿起吉他时,大脑还没想好要练习什么的时候,手指已经不自觉的开始爬了...

    有福
  • 还没通关“猜画小歌”?击败谷歌AI的秘籍在此

    不是因为这家公司要被欧盟罚款50亿美元,而是因为Google首款微信小程序“猜画小歌”:跟AI玩我画你猜的小游戏。

    量子位

扫码关注云+社区

领取腾讯云代金券