一文掌握 Prometheus 多集群监控神器 Thanos

介绍

在本文中,我们将看到 Prometheus 仅监控堆栈的局限性,以及为什么迁移到基于 Thanos 的堆栈可以提高指标保留率并降低整体基础架构成本。

用于此演示的内容可 在此处和 此处获得, 并提交给各自的许可证。

Kubernetes 普罗米修斯堆栈

在为我们的客户部署 Kubernetes 基础架构时,在每个集群上部署一个监控堆栈是标准的。这个堆栈通常由几个组件组成:

简化架构如下:

注意事项

此架构有一些注意事项,并且在增加要从中获取指标的集群数量时不能很好地扩展。

多个 Grafana

在这个设置中,每个集群都有自己的 Grafana 和自己的一组仪表板,维护起来很麻烦。

存储指标很昂贵

Prometheus 将指标存储在磁盘上,您必须在存储空间和指标保留时间之间做出选择。如果您想长时间存储数据并在云提供商上运行,如果您在其上存储 TB 级数据,块存储可能会很昂贵。同样在生产环境中,Prometheus 通常运行在复制或分片或两者兼有的情况下,这可以使您的存储需求增加一倍甚至四倍。

解决方案

多个 Grafana 数据源

可以在外部网络上公开 Prometheus 端点并将它们作为数据源添加到单个 Grafana 中。例如,您只需要使用双向 TLS 或 TLS 和基本身份验证在 Prometheus 外部端点上实现安全性。这种方案的缺点是不能根据不同的数据源进行计算。

Prometheus federation

Prometheus federation允许从 Prometheus 抓取 Prometheuses,当您不抓取大量指标时,此解决方案效果很好。在规模上,如果所有 Prometheus 目标的抓取持续时间比抓取间隔长,您可能会遇到一些严重的问题。

Prometheus 远程写入

虽然远程写入是一种解决方案(也由 Thanos 接收器实现),但我们不会在本文中讨论“推送指标”部分。您可以在此处了解推送指标的优缺点 。建议将指标作为最后的手段或在不信任多个集群或租户时(例如在构建 Prometheus 作为服务产品时)。无论如何,这可能是另一篇文章的主题,但我们将重点关注这里的报废。

进入Thanos

Thanos是一个“开源、高可用、具有长期存储能力的 Prometheus 设置”。Thanos 被许多知名公司使用。它也是CNCF 孵化项目的一部分。

Thanos 的主要功能之一是允许“无限”存储。怎么会这样 ?通过使用几乎每个云提供商都提供的对象存储(例如 S3)。如果在本地运行,可以使用rookminio等解决方案提供对象存储。

它是如何工作的 ?

Thanos 与 Prometheus 并肩作战。从仅 Prometheus 的设置开始并升级到 Thanos 是很常见的。

Thanos 分为几个组件,每个组件都有一个目标(每个服务都应该是:))。组件之间通过 gRPC 进行通信。

Thanos Sidecar

Thanos 与 Prometheus(带有 sidecar)一起运行,并且每 2 小时将 Prometheus 指标导出到对象存储。这使得 Prometheus几乎是 无状态的。Prometheus 仍在内存中保留 2 小时的指标,因此您可能仍会在中断时丢失 2 小时的指标(这个问题应该由您的 Prometheus 设置处理,使用 HA/Sharding,而不是 Thanos)。

Thanos sidecar与Prometheus OperatorKube Prometheus Stack一起开箱即用, 并且可以轻松部署。该组件充当 Thanos Query 的存储。

Thanos Store

Thanos Store充当将查询转换为远程对象存储的网关。它还可以在本地存储上缓存一些信息。基本上,这是允许您查询对象存储以获取指标的组件。该组件充当 Thanos Query 的存储

Thanos Compactor

Thanos compactor是一个单例(不可扩展),负责压缩和下采样存储在对象存储中的指标。下采样是随着时间的推移失去指标粒度的行为。例如,您可能希望将指标保留 2 或 3 年,但您不需要像昨天的指标那样多的数据点。这就是压缩器的用途,为您节省对象存储的字节数,从而为您节省费用。

Thanos Query

Thanos Query是 Thanos 的主要组件,它是您发送 promQL 查询的中心点。Thanos Query 公开了与 Prometheus 兼容的端点。然后它将查询分派到所有“stores”。请记住,stores可能是提供指标的任何其他 Thanos 组件。Thanos Query可以将查询发送到:

  • 另一个 Thanos query (它们可以堆叠)
  • Thanos store
  • Thanos sidecar

如果相同的指标来自不同的store或 Prometheuse,Thanos Query还负责对指标进行重复数据删除。例如,如果您有一个位于 Prometheus 和对象存储中的指标,Thanos Query 可以对指标进行重复数据删除。在 Prometheus HA 设置的情况下,重复数据删除也基于 Prometheus 副本和分片工作。

Thanos Query Frontend

正如其名称所暗示的那样,Thanos Query Frontend充当 Thanos Query 的前端,其目标是将大型查询拆分为多个较小的查询并缓存查询结果(在内存中或在 memcached 中)

在远程写入的情况下还有其他组件,例如 Thanos Receive,但这仍然不是本文的主题。

多集群架构

有多种方法可以将这些组件部署到多个 Kubernetes 集群中,根据用例,有些方法比另一种更好,我们不能在这里面面俱到。

我们的示例在 AWS 上运行,使用 tEKS部署了 2 个集群,这是我们在 AWS 上部署生产就绪 EKS 集群的多合一解决方案:

我们的部署使用官方 kube-prometheus-stack 和bitnami thanos chart.

一切都在我们的terraform-kubernetes-addons存储库中进行了策划

thanosdemo文件夹中的目录结构如下:

 .
├──  env_tags.yaml
├──  eu-west-1
│  ├──  clusters
│  │  └──  observer
│  │     ├──  eks
│  │     │  ├──  kubeconfig
│  │     │  └──  terragrunt.hcl
│  │     ├──  eks-addons
│  │     │  └──  terragrunt.hcl
│  │     └──  vpc
│  │        └──  terragrunt.hcl
│  └──  region_values.yaml
└──  eu-west-3
   ├──  clusters
   │  └──  observee
   │     ├──  cluster_values.yaml
   │     ├──  eks
   │     │  ├──  kubeconfig
   │     │  └──  terragrunt.hcl
   │     ├──  eks-addons
   │     │  └──  terragrunt.hcl
   │     └──  vpc
   │        └──  terragrunt.hcl
   └──  region_values.yaml

这允许 DRY(不要重复自己)基础设施并轻松扩展 AWS 账户、区域和集群的数量。

Observer Cluster

Observer Cluster是我们的主集群,我们将从中查询其他集群:

Prometheus-operator 正在运行:

  • 启用 Grafana
  • 上传到特定observee bucket 的 Thanos sidecar
kube-prometheus-stack = {
  enabled                     = true
  allowed_cidrs               = dependency.vpc.outputs.private_subnets_cidr_blocks
  thanos_sidecar_enabled      = true
  thanos_bucket_force_destroy = true
  extra_values                = <<-EXTRA_VALUES
    grafana:
      deploymentStrategy:
        type: Recreate
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: nginx
          cert-manager.io/cluster-issuer: "letsencrypt"
        hosts:
          - grafana.${local.default_domain_suffix}
        tls:
          - secretName: grafana.${local.default_domain_suffix}
            hosts:
              - grafana.${local.default_domain_suffix}
      persistence:
        enabled: true
        storageClassName: ebs-sc
        accessModes:
          - ReadWriteOnce
        size: 1Gi
    prometheus:
      prometheusSpec:
        replicas: 1
        retention: 2d
        retentionSize: "10GB"
        ruleSelectorNilUsesHelmValues: false
        serviceMonitorSelectorNilUsesHelmValues: false
        podMonitorSelectorNilUsesHelmValues: false
        storageSpec:
          volumeClaimTemplate:
            spec:
              storageClassName: ebs-sc
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 10Gi
    EXTRA_VALUES

为Observer Cluster生成一个 CA:

  • 此 CA 将被observee clusters ingress sidecar信任
  • TLS证书是为Thanos querier组件生成的,该组件将查询observee clusters

部署 Thanos 组件:

  • 所有 Thanos 组件都已部署
  • 作为 Grafana 的数据源端点的Query Frontend(查询前端)
  • 部署 Storegateway 以查询observer bucket
  • Query 将对存储网关和其他查询器执行查询

部署的其他 Thanos 组件:

  • 部署了配置了 TLS 的 Thanos Query 来查询每个 observee cluster
thanos-tls-querier = {
  "observee" = {
    enabled                 = true
    default_global_requests = true
    default_global_limits   = false
    stores = [
      "thanos-sidecar.${local.default_domain_suffix}:443"
    ]
  }
}

thanos-storegateway = {
  "observee" = {
    enabled                 = true
    default_global_requests = true
    default_global_limits   = false
    bucket                  = "thanos-store-pio-thanos-observee"
    region                  = "eu-west-3"
  }

Observee cluster

Observee cluster 是具有最少 Prometheus/Thanos 安装的 Kubernetes 集群,将由 Observer cluster查询

Prometheus 操作员正在运行:

  • 上传到observee特定bucket的Thanos side
  • Thanos sidecar 与Ingress具有 TLS 客户端身份验证的对象一起发布并信任 observer cluster CA。
 kube-prometheus-stack = {
  enabled                     = true
  allowed_cidrs               = dependency.vpc.outputs.private_subnets_cidr_blocks
  thanos_sidecar_enabled      = true
  thanos_bucket_force_destroy = true
  extra_values                = <<-EXTRA_VALUES
    grafana:
      enabled: false
    prometheus:
      thanosIngress:
        enabled: true
        ingressClassName: nginx
        annotations:
          cert-manager.io/cluster-issuer: "letsencrypt"
          nginx.ingress.kubernetes.io/ssl-redirect: "true"
          nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
          nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
          nginx.ingress.kubernetes.io/auth-tls-secret: "monitoring/thanos-ca"
        hosts:
        - thanos-sidecar.${local.default_domain_suffix}
        paths:
        - /
        tls:
        - secretName: thanos-sidecar.${local.default_domain_suffix}
          hosts:
          - thanos-sidecar.${local.default_domain_suffix}
      prometheusSpec:
        replicas: 1
        retention: 2d
        retentionSize: "6GB"
        ruleSelectorNilUsesHelmValues: false
        serviceMonitorSelectorNilUsesHelmValues: false
        podMonitorSelectorNilUsesHelmValues: false
        storageSpec:
          volumeClaimTemplate:
            spec:
              storageClassName: ebs-sc
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 10Gi
    EXTRA_VALUES

部署Thanos components:

  • 用于管理此特定集群的下采样的 Thanos compactor
thanos = {
  enabled = true
  bucket_force_destroy = true
  trusted_ca_content      = dependency.thanos-ca.outputs.thanos_ca
  extra_values = <<-EXTRA_VALUES
    compactor:
      retentionResolution5m: 90d
    query:
      enabled: false
    queryFrontend:
      enabled: false
    storegateway:
      enabled: false
    EXTRA_VALUES
}

再深入一点

让我们检查一下我们的集群上正在运行什么。在observer我们有:

kubectl -n monitoring get pods
NAME                                                        READY   STATUS    RESTARTS   AGE
alertmanager-kube-prometheus-stack-alertmanager-0           2/2     Running   0          120m
kube-prometheus-stack-grafana-c8768466b-rd8wm               2/2     Running   0          120m
kube-prometheus-stack-kube-state-metrics-5cf575d8f8-x59rd   1/1     Running   0          120m
kube-prometheus-stack-operator-6856b9bb58-hdrb2             1/1     Running   0          119m
kube-prometheus-stack-prometheus-node-exporter-8hvmv        1/1     Running   0          117m
kube-prometheus-stack-prometheus-node-exporter-cwlfd        1/1     Running   0          120m
kube-prometheus-stack-prometheus-node-exporter-rsss5        1/1     Running   0          120m
kube-prometheus-stack-prometheus-node-exporter-rzgr9        1/1     Running   0          120m
prometheus-kube-prometheus-stack-prometheus-0               3/3     Running   1          120m
thanos-compactor-74784bd59d-vmvps                           1/1     Running   0          119m
thanos-query-7c74db546c-d7bp8                               1/1     Running   0          12m
thanos-query-7c74db546c-ndnx2                               1/1     Running   0          12m
thanos-query-frontend-5cbcb65b57-5sx8z                      1/1     Running   0          119m
thanos-query-frontend-5cbcb65b57-qjhxg                      1/1     Running   0          119m
thanos-storegateway-0                                       1/1     Running   0          119m
thanos-storegateway-1                                       1/1     Running   0          118m
thanos-storegateway-observee-storegateway-0                 1/1     Running   0          12m
thanos-storegateway-observee-storegateway-1                 1/1     Running   0          11m
thanos-tls-querier-observee-query-dfb9f79f9-4str8           1/1     Running   0          29m
thanos-tls-querier-observee-query-dfb9f79f9-xsq24           1/1     Running   0          29m

kubectl -n monitoring get ingress
NAME                            CLASS    HOSTS                                            ADDRESS                                                                         PORTS     AGE
kube-prometheus-stack-grafana   <none>   grafana.thanos.teks-tg.clusterfrak-dynamics.io   k8s-ingressn-ingressn-afa0a48374-f507283b6cd101c5.elb.eu-west-1.amazonaws.com   80, 443   123m

并且在observee

kubectl -n monitoring get pods
NAME                                                        READY   STATUS    RESTARTS   AGE
alertmanager-kube-prometheus-stack-alertmanager-0           2/2     Running   0          39m
kube-prometheus-stack-kube-state-metrics-5cf575d8f8-ct292   1/1     Running   0          39m
kube-prometheus-stack-operator-6856b9bb58-4cngc             1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-bs4wp        1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-c57ss        1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-cp5ch        1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-tnqvq        1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-z2p49        1/1     Running   0          39m
kube-prometheus-stack-prometheus-node-exporter-zzqp7        1/1     Running   0          39m
prometheus-kube-prometheus-stack-prometheus-0               3/3     Running   1          39m
thanos-compactor-7576dcbcfc-6pd4v                           1/1     Running   0          38m

kubectl -n monitoring get ingress
NAME                                   CLASS   HOSTS                                                   ADDRESS                                                                         PORTS     AGE
kube-prometheus-stack-thanos-gateway   nginx   thanos-sidecar.thanos.teks-tg.clusterfrak-dynamics.io   k8s-ingressn-ingressn-95903f6102-d2ce9013ac068b9e.elb.eu-west-3.amazonaws.com   80, 443   40m

我们的 TLS 查询器应该能够查询observee cluster的指标。让我们检查一下他们的行为:


k -n monitoring logs -f thanos-tls-querier-observee-query-687dd88ff5-nzpdh

level=info ts=2021-02-23T15:37:35.692346206Z caller=storeset.go:387 component=storeset msg="adding new storeAPI to query storeset" address=thanos-sidecar.thanos.teks-tg.clusterfrak-dynamics.io:443 extLset="{cluster=/"pio-thanos-observee/", prometheus=/"monitoring/kube-prometheus-stack-prometheus/", prometheus_replica=/"prometheus-kube-prometheus-stack-prometheus-0/"}"

所以这个查询器 pod 可以查询我的另一个集群,如果我们检查 webUI,我们可以看到stores:

kubectl -n monitoring port-forward thanos-tls-querier-observee-query-687dd88ff5-nzpdh 10902

太好了,但我只有一家stores!记得我们说过查询器可以堆叠在一起。在我们的观察者集群(observer cluster)中,我们有标准的 http 查询器,可以像在架构图中查询其他组件一样。

kubectl -n monitoring port-forward thanos-query-7c74db546c-d7bp8 10902

在这里,我们可以看到所有已添加到中央查询器的商店:

  • observer cluster 本地 thanos sidecar
  • 我们的存储网关(一个用于远程观察者集群( observee cluster),一个用于本地观察者集群(observer cluster))
  • 可以查询observee sidecar的本地TLS查询器

Grafana 中的可视化

最后,我们可以前往 Grafana,看看默认的 Kubernetes 仪表板是如何与多集群兼容的。

结论

Thanos 是一个非常复杂的系统,有很多活动部件,我们没有深入研究这里涉及的特定自定义配置,因为这会花费太多时间。

我们在我们的 tEKS存储库中为 AWS 提供了一个非常完整的实现,它抽象了很多复杂性(主要是 mTLS 部分)并允许进行大量自定义。您也可以将我们的 terraform-kubernetes-addons 模块用作独立组件。我们计划在未来支持其他云提供商。请随时通过 Github 问题与我们联系,了解其中任何一个项目。

根据您的基础架构和要求,有许多可能的 Thanos 实现可能适合您。

如果您想深入了解 Thanos,可以查看他们的官方 kube-thanos存储库以及他们关于跨集群通信的建议

当然,我们很乐意帮助您设置云原生监控堆栈,请通过[email protected]联系我们:)

您也可以每天通过 CNCF/Kubernetes Slack 频道联系我们。

Kevin Lefevre,首席技术官兼联合创始人

The post 一文掌握 Prometheus 多集群监控神器 Thanos first appeared on Linux迷.

版权声明:
作者:cc
链接:https://www.techfm.club/p/15951.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>