乐趣区

关于java:最牛逼的集群监控系统它始终位列第一

在本文中,咱们将看到 Prometheus 监控技术栈的局限性,以及为什么挪动到基于 Thanos 的技术栈能够进步指标留存率并升高总体基础设施老本。

用于此演示的内容能够在上面链接中获取,并提交到他们各自的许可证。

  • https://github.com/particulei…
  • https://github.com/particulei…

Kubernetes 普罗米修斯技术栈

在为咱们的客户部署 Kubernetes 基础设施时,在每个集群上部署监控技术栈是规范做法。这个堆栈通常由几个组件组成:

  • Prometheus:收集度量规范
  • 告警管理器:依据指标查问向各种提供者发送警报
  • Grafana:可视化奢华仪表板

简化架构如下:

注意事项

这种架构有一些注意事项,当你想从其中获取指标的集群数量减少时,它的伸缩性以及可扩展性不太好。

多个 Grafana

在这种设置中,每个集群都有本人的 Grafana 和本人的一组仪表板,保护起来很麻烦。

存储指标数据是低廉的

Prometheus 将指标数据存储在磁盘上,你必须在存储空间和指标保留工夫之间做出抉择。如果你想长时间存储数据并在云提供商上运行,那么如果存储 TB 的数据,块存储的老本可能会很高。同样,在生产环境中,Prometheus 常常应用复制或分片或两者同时运行,这可能会使存储需要减少两倍甚至四倍。

解决方案

多个 Grafana 数据源

能够在内部网络上公开 Prometheus 的端点,并将它们作为数据源增加到单个 Grafana 中。你只须要在 Prometheus 内部端点上应用 TLS 或 TLS 和根本认证来实现安全性。此解决方案的毛病是不能基于不同的数据源进行计算。

Prometheus 联邦

Prometheus 联邦容许从 Prometheus 中抓取 Prometheus,当你不抓取很多指标数据时,这个解决方案能够很好地工作。在规模上,如果你所有的 Prometheus 指标的抓取持续时间都比抓取距离长,可能会遇到一些重大的问题。

Prometheus 近程写

尽管近程写入是一种解决方案(也由 Thanos receiver 实现),但咱们将不在本文中探讨“推送指标”局部。你能够在这里 [1] 浏览对于推送指标的利弊。倡议在不信赖多个集群或租户的状况下(例如在将 Prometheus 构建为服务提供时),将指标作为最初的伎俩。无论如何,这可能是当前文章的主题,但咱们将在这里集中探讨抓取。

Thanos,它来了

Thanos 是一个“开源的,高可用的 Prometheus 零碎,具备长期存储能力”。很多出名公司都在应用 Thanos,也是 CNCF 孵化我的项目的一部分。

Thanos 的一个次要特点就是容许“有限”存储空间。通过应用对象存储(比方 S3),简直每个云提供商都提供对象存储。如果在前提环境下运行,对象存储能够通过 rook 或 minio 这样的解决方案提供。

它是如何工作的?

Thanos 和 Prometheus 并肩作战,从 Prometheus 开始降级到 Thanos 是很常见的。

Thanos 被分成几个组件,每个组件都有一个指标(每个服务都应该这样:)),组件之间通过 gRPC 进行通信。

Thanos Sidecar

Thanos 和 Prometheus 一起运行(有一个边车),每 2 小时向一个对象存储库输入 Prometheus 指标。这使得 Prometheus 简直是无状态的。Prometheus 依然在内存中保留着 2 个小时的度量值,所以在产生宕机的状况下,你可能依然会失落 2 个小时的度量值(这个问题应该由你的 Prometheus 设置来解决,应用 HA/ 分片,而不是 Thanos)。

Thanos sidecar 与 Prometheus 运营者和 Kube Prometheus 栈一起,能够轻松部署。这个组件充当 Thanos 查问的存储。

Thanos 存储

Thanos 存储充当一个网关,将查问转换为近程对象存储。它还能够在本地存储器上缓存一些信息。基本上,这个组件容许你查问对象存储以获取指标。这个组件充当 Thanos 查问的存储。

Thanos Compactor

Thanos Compactor 是一个单例(它是不可扩大的),它负责压缩和升高存储在对象存储中的指标。下采样是随着工夫的推移对指标力度的宽松。例如,你可能想将你的指标放弃 2 年或 3 年,但你不须要像昨天的指标那么少数据点。这就是压缩器的作用,它能够在对象存储上节俭资节,从而节省成本。

Thanos Query

Thanos 查问是 Thanos 的次要组件,它是向其发送 PromQL 查问的中心点。Thanos 查问裸露了一个与 Prometheus 兼容的端点。而后它将查问后果分派给所有的“stores”。记住,Store 可能是任何其余提供指标的 Thanos 组件。Thanos 查问能够发送查问到另一个 Thanos 查问(他们能够重叠)。

  • Thanos Store
  • Thanos Sidecar
  • Thanos Query

还负责对来自不同 Store 或 Prometheus 的雷同指标进行反复数据删除。例如,如果你有一个度量值在 Prometheus 中,同时也在对象存储中,Thanos Query 能够对该指标值进行反复数据删除。在 Prometheus HA 设置的状况下,反复数据删除也基于 Prometheus 正本和分片。

Thanos Query Frontend

正如它的名字所暗示的,Thanos 查问前端是 Thanos 查问的前端,它的指标是将大型查问拆分为多个较小的查问,并缓存查问后果(在内存或 memcached 中)。

还有其余组件,比方在近程写的状况下接管 Thanos,但这依然不是本文的主题。

多集群架构

有多种办法能够将这些组件部署到多个 Kubernetes 集群中,依据用例的不同,有些办法比其余办法更好,在这里咱们不能给出具体的介绍。

咱们的例子是在 AWS 上运行,应用 tEKS[2]部署了 2 个集群,咱们的 all in one 解决方案将生产就绪的 EKS 集群部署在 AWS 上:

  • 一个观察者集群[3]
  • 一个察看集群[4]

咱们的部署应用了官网的 kube-prometheus-stack 和 bitnami thanos 图表。

一切都是在咱们的 terraform-kubernetes-addons 存储库中策动的。

Thanos demo 文件夹中的目录构造如下:

.
├──  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(Don ‘t Repeat Yourself)基础设施,并能够轻松地扩大 AWS 帐户、区域和集群的数量。

观察者集群

观察者集群是咱们的主集群,咱们将从它查问其余集群:

Prometheus 正在运行:

  • Grafana 启用
  • Thanos 边车上传到特定的桶
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

为观察者集群生成一个 CA 证书:

  • 这个 CA 将被进入 sidecar 的被察看集群所信赖
  • 为 Thanos querier 组件生成 TLS 证书,这些组件将查问被察看集群

Thanos 组件部署:

  • Thanos 组件全副部署实现
  • 查问前端,作为 Grafana 的数据源端点
  • 存储网关用于查问察看零碎
  • Query 将对存储网关和其余查询器执行查问

部署的额定 Thanos 组件:

  • 配置了 TLS 的 Thanos 查询器对每个被察看集群进行查问
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"
  }

被观测集群

被观测集群是 Kubernetes 集群,具备最小的 Prometheus/Thanos 装置,将被观测集群查问。

Prometheus operator 正在运行:

  • Thanos 这边就是上传给观察者特定的桶
  • Thanos 边车与 TLS 客户端认证的入口对象一起公布,并信赖观察者集群 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 组件部署:

  • Thanos 压缩器来治理这个特定集群的下采样
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
}

再深刻一点

让咱们检查一下集群上正在运行什么。

对于观察员,咱们有:

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

被观察者:

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 查询器应该可能查问被观测集群的度量规范。

让咱们来看看它们的行为:

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\"}"

所以这个查询器 pods 能够查问我的其余集群,如果咱们查看 Web,咱们能够看到存储:

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

太棒了,然而我只有一个存储,还记得咱们说过查询器能够重叠在一起吗?在咱们的观察者集群中,咱们有规范的 http 查询器,它能够查问架构图中的其余组件。

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

这里咱们能够看到所有的存储曾经被增加到咱们的核心查询器:

  • 观察者把本地 Thanos 汇集
  • 咱们的存储网关(一个用于近程观测者集群,一个用于本地观测者集群)
  • 本地 TLS 查询器,它能够查问被察看的 sidecar

在 Grafana 可视化

最初,咱们能够返回 Grafana,看看默认的 Kubernetes 仪表板是如何与多集群兼容的。

总结

Thanos 是一个非常复杂的零碎,有很多挪动部件,咱们没有深入研究具体的自定义配置,因为它会破费太多的工夫。

咱们在 tEKS 存储库中提供了一个相当残缺的 AWS 实现,它形象了很多复杂性(次要是 mTLS 局部),并容许进行很多定制。你也能够应用 terraform-kubernetes-addons 模块作为独立的组件。咱们打算在将来反对其余云提供商。不要犹豫,通过 Github 上的任何一个我的项目的问题分割咱们。

依据你的基础设施和需要,有许多可能适宜你的 Thanos 实现。

如果你想深入研究 Thanos,能够查看他们的官网 kube-thanos 存储库,以及他们对于跨集群通信的倡议。

退出移动版