type
status
date
slug
summary
tags
category
icon
password
Prometheus Operator 简介
在传统的 Prometheus 监控方案中,所有的
抓取目标(scrape targets)
和 报警规则(alert rules)
都需要手动写入配置文件。如果监控目标数量庞大,比如成百上千个实例,每次新增、修改或删除目标时,都需要直接编辑配置文件并重启 Prometheus,维护成本高,灵活性差。为了解决这个问题,Prometheus Operator
应运而生。Prometheus Operator
为 Kubernetes 集群中的 Prometheus 实例 提供了声明式管理方式,使 Prometheus 的部署、管理和运行更加自动化和高效。通过自定义资源(CRD)
,Prometheus Operator 允许用户在 Kubernetes 中以YAML 形式直接定义 Prometheus 实例、抓取目标(ServiceMonitor)、报警规则(PrometheusRule)等,无需手动修改繁琐的配置文件,大幅提升运维效率。
上图是 Prometheus-Operator 官方提供的架构图。各组件以不同的方式运行在 Kubernetes 集群中,其中 Operator 是最核心的部分。作为一个控制器,它负责创建 Prometheus、ServiceMonitor、AlertManager 以及 PrometheusRule 等 CRD 资源对象,并持续监控(Watch)和维护这些资源对象的状态。
Prometheus Operator 为 Kubernetes 提供了对 Prometheus 及其相关监控组件的本地部署和管理方案。该项目旨在简化和自动化基于 Prometheus 的监控栈配置,主要包括以下功能:
Kubernetes 自定义资源
:使用 Kubernetes CRD 来部署和管理 Prometheus、Alertmanager 和相关组件。
简化的部署配置
:直接通过 Kubernetes 资源清单配置 Prometheus,包括版本、持久化、副本、保留策略等配置。
Prometheus 监控目标配置
:基于常用的 Kubernetes 标签查询自动生成监控目标配置,无需专门学习 Prometheus 的配置语法。部署
我们可以直接使用 kube-prometheus 的 Helm Charts 来进行快速安装,也可以直接手动安装。这里我们直接使用 kube-prometheus 这个项目来进行安装,该项目和 Prometheus-Operator 的区别就类似于 Linux 内核和 CentOS/Ubuntu 这些发行版的关系,真正起作用的是 Operator 去实现的,而 kube-prometheus 只是利用 Operator 编写了一系列常用的监控资源清单。不过需要注意 Kubernetes 版本和 kube-prometheus 的兼容,github地址:https://github.com/prometheus-operator/prometheus-operator

这里我的k8s集群是1.28.2,所以我们使用0.13、0.14、main版本都是可以的。我这里直接下载的zip包,然后上传到服务器上

将上传至服务器的包进行解压
首先创建需要的命名空间和CRD资源,等待它们创建好后再创建其他资源
执行完后,发现自动创建了一个名为 monitoring 的命名空间,以及相关的 CRD 资源对象声明
有了这些CRD资源,我们才可以去创建对应的 Operator 控制器,在 manifests 目录下面就包含了 Operator 的资源清单以及各种监控对象声明,比如 Prometheus、Alertmanager 等,直接应用即可
执行完后,会自动安装 prometheus-operator、node-exporter、kube-state-metrics、grafana、prometheus-adapter 以及 prometheus 和 alertmanager 等大量组件
针对 grafana、alertmanager 和 prometheus 都创建了一个类型为 ClusterIP 的 Service,当然如果我们想要在外网访问这两个服务的话可以通过创建对应的 Ingress 对象或者使用 NodePort 类型的 Service,我们这里为了简单,直接使用 NodePort 类型的服务即可
更改完成后,我们就可以通过上面的 NodePort 去访问对应的服务了
比如查看 prometheus 的服务发现页面,可以看到已经监控上了很多指标数据了

现在环境当中 Prometheus 是两个副本,我们这里通过 Service 去访问,按正常来说请求是会去轮询访问后端的两个 Prometheus 实例的,但实际上我们这里访问的时候始终是路由到后端的一个实例上去,因为这里的 Service 在创建的时候添加了
sessionAffinity: ClientIP
这样的属性,会根据 ClientIP 来做 session 亲和性,所以我们不用担心请求会到不同的副本上去为什么会担心请求会到不同的副本上去呢?正常多副本应该是看成高可用的常用方案,理论上来说不同副本本地的数据是一致的,但是需要注意的是 Prometheus 的主动 Pull 拉取监控指标的方式,由于抓取时间不能完全一致,即使一致也不一定就能保证网络没什么问题,所以最终不同副本下存储的数据很大可能是不一样的,所以这里我们配置了 session 亲和性,可以保证我们在访问数据的时候始终是一致的。

在多实例 Prometheus 部署中,每个 Prometheus 实例都维护着自己的 TSDB(时序数据库),并采用
Pull 模式
定期拉取监控目标的 metrics
数据。然而,由于不同实例的抓取时间并不完全同步,导致每个 Prometheus 实例的存储数据可能存在时间差异,无法保证数据一致性。例如:Prometheus-0 在 10:00:00 开始抓取数据,每 10 秒 抓取一次,存储的值依次为 1, 2, 3。Prometheus-1 在 10:05:00 才开始抓取,同样每 10 秒 采集一次,但由于时间不同,数据值可能变成了 2, 3, 3。当客户端通过 Service 访问 Prometheus 时,如果 Service 采用轮询(Round Robin)方式分配请求,那么:第一次请求可能访问 Prometheus-0,获取的数据是 1。第二次请求可能访问 Prometheus-1,获取的数据变成了 2。第三次请求又回到 Prometheus-0,数据又变成了 1。这样会导致查询数据波动,给用户造成困惑,让用户感到十分懵逼。为了确保同一个客户端的请求始终命中同一个 Prometheus 实例,可以在 Kubernetes Service 配置
会话亲和性(Session Affinity)
:基于客户端 IP 绑定(ClientIP)
:同一 IP 的请求始终访问同一个实例。这样,同一客户端的查询请求始终落在同一个 Prometheus 实例上,避免数据查询出现跳变。这种方式可以改善用户体验,但仍然不能彻底解决 Prometheus 实例数据不一致的问题。如果需要 全局一致性,可以考虑 Thanos 或 VictoriaMetrics Cluster,它们提供了 跨实例数据合并
和 统一查询层
,确保查询结果始终一致。CRD
Prometheus Operator是最核心的部分,作为一个控制器,他会去创建Prometheus、Alertmanager、ServiceMonitor、PodMonitor、Probe、ThanosRuler、PrometheusRule、AlertmanagerConfig这些CRD资源对象,然后会一直Watch并维持这些资源对象的状态。官方文档:https://prometheus-operator.dev/docs/api-reference/api
Prometheus
Prometheus 是由 Prometheus Operator 引入的一个自定义资源定义(CRD),用于声明希望在 Kubernetes 集群中如何部署和运行 Prometheus 实例。通过该 CRD,用户可以定义 Prometheus 的副本数、副本之间是否启用持久化存储(Persistent Volume)、与之关联的告警规则(Alertmanager)配置等内容。
对于每一个 Prometheus 类型的 CRD 资源,Operator 会以 StatefulSet 的形式在相同的命名空间下自动部署对应的 Prometheus 实例。部署时,Operator 会为每个 Prometheus Pod 生成一个名为 <prometheus-name> 的 Secret,该 Secret 中包含了 Prometheus 的完整配置文件,本质上是自动生成的 prometheus.yml 配置。而 Prometheus 的配置内容,并不是由用户手动撰写,而是由 Operator 根据集群中已存在的 CRD 资源(如 ServiceMonitor、PodMonitor、Probe 等)动态生成的。只要这些 CRD 资源匹配了当前 Prometheus CRD 的选择器配置,Operator 就会将其纳入监控范围,并将它们转换为对应的 scrape job,写入配置中。更重要的是:这个配置是实时同步的。每当有新的 ServiceMonitor 或 PodMonitor 被创建、修改或删除,Operator 都会自动更新生成的配置,并将其同步进 Secret 中。Prometheus 会在容器重载配置时生效,因此整个过程对用户来说是透明的。
Prometheus CRD 还支持通过 serviceMonitorSelector 和 podMonitorSelector 等字段来选择性地纳入哪些监控目标。也就是说,可以通过设置标签选择器,控制某个 Prometheus 实例具体采集哪些 ServiceMonitor 或 PodMonitor 对象。如果未设置这些选择器,默认情况下会包含全部资源。如果显式设置为空,即
matchLabels: {}
,则不会包含任何对象。Prometheus CRD默认是2个副本,现在我们来查看一下
在一些高级用例中,如果用户不希望由 Operator 自动生成配置,也可以不提供这些选择器,此时 Operator 将不再维护对应的配置 Secret,而是交由用户手动写入配置内容。这样可以手动控制 Prometheus 的所有配置细节,同时仍然享受 Operator 提供的版本管理、自动部署等能力。执行以下命令,将prometheus实例的配置文件解码并写入到本地
prometheus.yaml
文件中您可以使用任何文本编辑器打开并修改 prometheus.yaml 文件的配置内容。您可以进行多种修改,包括添加或删除监控目标、设置告警规则,或调整数据采集的时间间隔。我们这里只是为了进行测试,下面我们将global下面的scrape_interval和evaluation_interval的时间改为60s。完成修改后,您需要使用以下命令将更新后的配置文件重新导入到 Prometheus 实例中
我们也可以通过如下方式修改,然后执行
kubectl edit
命令进行修改最后,重启prometheus实例,以便它可以加载新的配置文件
注:自己测试没通过,不知道是哪里的问题,还在思考中,如果各位大佬知道怎么修改,可以留言,感谢
服务发现 ServiceMonitor
ServiceMonitor 是 Prometheus Operator 所引入的自定义资源(CRD),用于声明 Prometheus 如何在动态环境中发现和监控服务。它的核心作用是通过 标签选择器(Label Selector) 精确地匹配目标 Service,并定义采集这些服务的指标的方式,从而实现自动发现和自动配置,无需手动修改 Prometheus 配置文件。
传统 Prometheus 是通过静态配置文件 prometheus.yml 来定义抓取目标的,一旦服务 IP 或端口变化,就需要人工更新。而在 Kubernetes 中,服务和 Pod 是动态变化的,这种静态配置方式显然不适用。而 Prometheus Operator + ServiceMonitor 的组合,则实现了 监控目标的动态管理。只要服务打上了符合规则的标签,Prometheus Operator 就可以自动发现对应的 Service,并生成抓取任务。可以将 ServiceMonitor 理解为 Prometheus 的 scrape target 的抽象声明。比如我们想要监控 Kubernetes 的调度组件 Scheduler,可以先为 kube-scheduler 创建一个 Service 对象,然后再创建一个 ServiceMonitor 对象,通过标签匹配这个 Service,Operator 就会自动将 kube-scheduler 的抓取目标添加到 Prometheus 的监控列表中,无需手动改配置或重启服务。
要让 ServiceMonitor 正常工作,有一个关键点是:被匹配的 Service 必须对应有 Endpoints。在 Kubernetes 中,Endpoints 是一个记录 IP 地址和端口的资源对象,通常由 Service 自动创建,它表示当前这个 Service 后端实际关联的 Pod 列表。Prometheus 最终是去抓取这些 Endpoints 中的 Pod 地址和端口的数据。换句话说,ServiceMonitor 实际上是通过匹配 Service,再由 Service 自动生成的 Endpoints 间接找到 Pod,然后通过定义的端口、路径进行指标采集。因此,要确保被监控的 Pod 打有正确的标签、Service 使用标签选择器将这些 Pod 关联起来、ServiceMonitor 匹配这个 Service、Prometheus Operator 能发现 ServiceMonitor 并动态注册到 Prometheus。
这样,当有新的 Pod 创建时,只要打了相同的标签,Prometheus 就能自动开始采集它们的指标,真正实现了监控的自动化和动态化,非常适合云原生环境。ServiceMonitor 允许监控跨命名空间的目标,这对多租户 Kubernetes 监控非常重要
监控kube-scheduler
我这里先来进行一个简单的案例进行演示,首先我们打开Grafana,发现并没有scheduler的监控数据,由于 kubeadm 部署的 Kubernetes 集群不会默认启用 kube-scheduler 的 metrics 端口

然后就我们打开Prometheus页面,没有发现的目标

我们先来查看下 kube-scheduler 组件对应的 ServiceMonitor 资源的定义
上面是一个典型的 ServiceMonitor 资源对象的声明方式,通过
selector.matchLabels
在 kube-system
这个命名空间下面匹配具有 app.kubernetes.io/name=kube-scheduler
这样的 ServiceServiceMonitor 是去匹配的service资源对象,由于我们这里是静态pod,需要手动创建service才能与 ServiceMonitor 进行关联
labels 区域的配置必须和我们上面的 ServiceMonitor 对象中的 selector 保持一致,selector 下面配置的是
component=kube-scheduler
匹配的是kube-scheduler 这个 Pod查看我们刚刚创建的Service
创建完成后,隔一小会儿后去 Prometheus 页面上查看 targets 下面 kube-scheduler 已经有采集的目标了,但是提示
connect: connection refused
这样的错误
这是因为 kube-scheduler 启动的时候默认绑定的是
127.0.0.1
地址,所以要通过 IP 地址去访问就被拒绝了。所以我们要修改 master 节点上的静态 Pod 资源清单更改后 kube-scheduler 会自动重启
重启完成后,我们再去查看 Prometheus 上面的采集目标,发现正常了

然后我们再来查看下Grafan面板,发现已经有了数据

监控etcd
了解了上述案例,下面我们来手动创建一个servicemonitor来监控etcd集群。由于我们这里演示环境使用的是 kubeadm 搭建的集群,etcd pod配置文件位于
/etc/kubernetes/manifest/
目录下面。查看etcd的启动参数,里面有一个 --listen-metrics-urls=http://127.0.0.1:2381
的配置,该参数就是来指定 metrics 接口运行在 2381 端口下面的,而且是 http 的协议,所以也不需要什么证书配置。但是 etcd 的 metrics 接口是监听在 127.0.0.1
这个 IP 上面的,所以访问会被拒绝,我们这里改为0.0.0.0
修改完后,会自动重启etcd
接下来我们创建对应的 ServiceMonitor 对象,匹配
kube-system
这个命名空间下面的具有 k8s-app=etcd
这个标签的 Service。jobLabel 表示用于检索 job 任务名称的标签,由于 etcd 的 metrics 接口在 2381 端口下面,不需要 https 安全认证,所以用默认的配置即可但实际上现在并不能监控到 etcd 集群,因为并没有一个满足 ServiceMonitor 条件的 Service 对象与之关联。所以接下来我们需要创建一个满足上面条件的 Service 对象,由于我们把 etcd 当成是集群外部的服务,所以要引入到集群中来我们就需要自定义 Endpoints 对象来创建 Service 对象了
查看创建好的service、ep和servicemonitor
打开 Prometheus 的 Dashboard 中查看 target,发现有 etcd 的监控项了

打开Grafana,导入etcd监控模板,我这里导入的模版id为3070

服务自动发现
Prometheus Operator
提供了额外的抓取配置,使我们能够通过添加配置来实现自动服务发现和监控。在 Prometheus Operator
中,可以自动发现并监控带有 prometheus.io/scrape=true
注解的 Service。此外,我们也可以通过手动添加 Prometheus 额外的抓取配置,实现对特定目标的监控。例如,以下 prometheus-additional.yaml
文件配置了对 etcd 组件的监控:然后通过这个文件创建一个对应的 Secret 对象
然后我们需要在声明 prometheus 的资源对象文件中通过 additionalScrapeConfigs 属性添加上这个额外的配置
打开 Prometheus 的 Dashboard 中查看配置已经生效了

如果后续需要修改或添加配置,可执行以下命令。先删除原有的 additional-configs Secret,然后重新创建一个包含 prometheus-additional.yaml 配置文件的 Secret。这样可以确保 Prometheus 读取到最新的配置
报警通知 Alertmanager
在使用 Prometheus Operator 部署的监控系统中,Prometheus 会通过 Kubernetes 的服务发现机制(Service Discovery)自动发现 Alertmanager 的实例,而无需用户手动配置 IP 地址或主机名。Prometheus 的配置文件(由 Operator 自动生成)中会包含一段 alerting 配置,用于指定 Alertmanager 的地址列表。
具体来说,Prometheus 会使用 kubernetes_sd_configs 配置项,并将 role 设置为 endpoints,表示 Prometheus 会从 Kubernetes API 中查询集群内所有的 Endpoints 资源,并从中获取 Alertmanager 服务的访问地址。它通常还会通过 relabel_configs 进一步过滤,只保留服务名为 alertmanager-main、端口名为 web 的目标。这个服务正是由 Operator 创建的,暴露了 Alertmanager 的 Web 接口用于接收告警。
查看Prometheus配置文件,可以看出 Prometheus 使用 Kubernetes 的自动发现机制(role 为 endpoints)来获取 AlertManager 的实例信息。配置中匹配的是服务名为 alertmanager-main 且端口名为 web 的 Service

查看alertmanager-main service,可以看到服务名正是 alertmanager-main,Port 定义的名称也是 web,符合上面的规则。所以 Prometheus 和 AlertManager 组件就正确关联上了
Alertmanager 自定义资源(CRD)是由 Prometheus Operator 引入的,用于声明在 Kubernetes 集群中运行的 Alertmanager 实例的期望配置。通过该 CRD,用户可以定义 Alertmanager 的副本数量、是否启用持久化存储、资源请求限制等参数,从而以声明式方式管理告警服务的生命周期。
对于每个 Alertmanager 类型的资源,Prometheus Operator 会在同一命名空间下,基于用户的配置生成一个 StatefulSet,并启动对应数量的 Alertmanager 实例。这些实例具备稳定的网络标识(DNS 名称),可以用于集群内部的服务发现与负载均衡。
当有两个或更多配置的副本时,Operator 会在高可用模式下运行 Alertmanager 实例,示例配置如下:
我们可以查看我们环境中的alertmanager pod数量
通过 Operator 提供的 alertmanager 资源对象创建的组件,应该怎样去配置报警呢?Alertmanager 的配置文件,即传统中的 alertmanager.yml 由一个挂载到 Pod 中的 Kubernetes Secret 提供。Prometheus-Operator 自动创建的名为
alertmanager-main-generated
的 Secret 对象,由 Operator 自动生成并维护,内容包括路由规则、接收器配置、抑制规则、告警分组策略等注意:alertmanager-main-generated secret 是基于 alertmanager-main secret 和 CRD AlertmanagerConfig 自动生成的
如果我们想要添加自己的接收器,我们就可以直接更改
alertmanager-main
这个 secret 文件比如我们把修改好的secret文件进行base64加密处理
然后复制base64加密的内容,执行如下命令,找到 data 部分,替换
alertmanager.yaml
的值AlertmanagerConfig
如果我们想要添加自己的接收器,我们就可以直接更改
alertmanager-main
这个 secret 文件,但是这里的内容是 base64 编码过后的,如果手动添加内容就非常不方便,为此 Prometheus-Operator 新增了一个 AlertmanagerConfig 的 CRD,比如我们现在需要使用邮箱进行报警。首先在 monitoring 命名空间下面创建一个secret用于存储邮箱授权码然后新建一个 AlertmanagerConfig 类型的资源对象,可以通过
kubectl explain alertmanagerconfig
或者在线 API 文档来查看字段的含义查看创建好的alertmanagerconfig
如果使用钉钉进行告警接收,可以参考如下配置
注意:直接创建上面的配置是不会生效的,我们需要添加一个 Label 标签,并在 Alertmanager 的资源对象中通过标签来关联上面的这个对象,比如我们这里新增了一个 Label 标签:
alertmanagerConfig: example
,然后需要重新更新 Alertmanager 对象,添加 alertmanagerConfigSelector
属性去匹配 AlertmanagerConfig 资源对象更新完成后默认的配置会和我们创建的配置进行合并,我们可以重新查看生成的 Secret 资源对象内容,也可以直接查看 Alertmanager 的 WEB UI 界面的配置内容。可以看到我们在 AlertmanagerConfig 里面定义的名为 email 的 Receiver,在最终生成的配置中名称了
monitoring/email/email
,格式为 <namespace>/<name>/<receiver name>

打开邮件,查看告警信息

综上,修改 Alertmanager 配置可以修改 secret Alertmanager-main 或者 CRD Alertmanagerconfig
报警规则 prometheusrule
在 Prometheus Dashboard 的 Alert 页面可以看到已经配置了许多报警规则,这些规则是由 Prometheus Operator 在安装时,默认创建的一些告警规则

这些报警规则来源于 Prometheus 配置文件中指定的 AlertManager 实例和报警规则文件(rules 文件)。我们可以在 Prometheus Dashboard 的 Config 页面中查看与 AlertManager 配置相关的详细信息

对于 prometheusrule 的更新操作 (create, delete, update) 都会被 watch 到,然后更新到统一的一个 configmap 中, 然后 prometheus 自动重载配置。每个 prometheusrule 会作为
configmap prometheus-k8s-rulefiles-0
中的一个 data,data 的命名规则为 <namespace>-<rulename>-ruleuid
prometheus 实例的挂载信息
而对应的报警规则文件位于
/etc/prometheus/rules/prometheus-k8s-rulefiles-0/
目录下面所有的 YAML 文件。我们可以进入 Prometheus 的 Pod 中验证下该目录下面是否有 YAML 文件
这个目录下的 YAML 文件,实际上就是创建的一个 PrometheusRule 文件包含的内容。所以如果以后我们需要自定义一个报警选项的话,只需要定义一个 PrometheusRule 资源对象即可。我们创建的 PrometheusRule 资源对象后,会自动在上面的
prometheus-k8s-rulefiles-0
目录下面生成一个对应的 <namespace>-<name>-<xxx-id>.yaml
文件。那么 Prometheus 为什么能够识别这个 PrometheusRule 资源对象呢?因为 prometheus CRD 这个资源对象里面有非常重要的一个属性 ruleSelector,用来匹配 rule 规则的过滤器,我们这里没有过滤,所以可以匹配所有的,假设要求匹配具有 prometheus=k8s
和 role=alert-rules
标签的 PrometheusRule 资源对象,则可以添加下面的配置所以我们要想自定义一个报警规则,只需要创建一个能够被 prometheus 对象匹配的 PrometheusRule 对象即可。比如现在我们添加一个 etcd 是否可用的报警,我们知道 etcd 整个集群有一半以上的节点可用的话集群就是可用的,所以我们判断如果不可用的 etcd 数量超过了一半那么就触发报警
创建完成后,查看创建的PrometheusRule
隔一会儿再去容器中查看下 rules 目录

然后再去 Prometheus Dashboard 的 Alert 页面下面就可以查看到上面我们新建的报警规则了

告警模板
Alertmanager CRD 支持 ConfigMaps 参数, 会自动挂载到
/etc/alertmanager/configmaps
目录,我们可以将模板文件配置成 Configmap,创建模板文件查看创建的ConfigMap
更新 Alertmanager 添加 configmap
查看alertmanager pod,发现模板文件已经自动挂载到
/etc/alertmanager/configmaps
目录更改
alertmanager-main
这个 secret 文件,比如我们把修改好的secret文件进行base64加密处理然后复制base64加密的内容,执行如下命令,找到 data 部分,替换
alertmanager.yaml
的值然后我们来模拟一条告警,查看告警信息

PodMonitor
PodMonitor 是 Prometheus Operator 提供的自定义资源(CRD),用于定义 Prometheus 如何监控一组动态变化的 Pod。它通过 标签选择器(Label Selector) 来筛选集群中符合条件的 Pod,从而实现自动发现和抓取指标。这样一来,用户无需为每一个 Pod 单独编写配置,只需确保应用统一暴露 Prometheus 指标端点,便可以统一纳入监控。一旦创建了 PodMonitor,Prometheus Operator 会将符合规则的 Pod 自动转换为 Prometheus 的 scrape job(抓取任务),并动态添加到 Prometheus 的配置中。整个过程不需要重启 Prometheus,也无需用户手动更新配置,特别适合容器环境下 Pod 动态扩缩容的场景。
在 PodMonitorSpec 中,podMetricsEndpoints字段用于定义需要抓取哪些端口(如 metrics),路径(如 /metrics),抓取间隔(interval)、超时时间(scrapeTimeout)等参数。该字段允许用户精确控制 Prometheus 如何与 Pod 进行交互,获取所需指标。
PodMonitor 的另一个重要特性是支持跨命名空间监控。通过配置 namespaceSelector,可以指定 PodMonitor 能发现哪些命名空间中的 Pod。若 namespaceSelector 为 {}(即为空),则允许发现所有命名空间的目标;若 namespaceSelector.matchNames 指定了具体命名空间名,则只发现这些命名空间中的目标;若不设置 namespaceSelector,则默认只发现与 PodMonitor 同一命名空间的目标。
PodMonitor 适用于应用直接在 Pod 内部暴露监控指标的场景,无需依赖 Kubernetes Service,适合对接 Sidecar 模式或无需通过服务访问的内部指标采集。而如果应用的监控指标通过 Kubernetes Service 对外暴露,则更推荐使用 ServiceMonitor,因为它更适合以服务为单位的监控场景。
ThanosRuler
ThanosRuler 是由 Thanos Operator 引入的一种自定义资源(CRD),用于在 Kubernetes 集群中声明式部署和配置 Thanos 的 Ruler 组件。它的核心作用是集中执行 Prometheus 的
告警规则(Alerting Rules)
和 记录规则(Recording Rules)
,并支持跨多个 Prometheus 实例进行统一评估,增强整个监控系统的高可用性和规则管理一致性。在传统 Prometheus 中,规则(如告警表达式或聚合表达式)是分散存放在各个 Prometheus 实例中的,这会导致管理难度大、重复配置多、难以保证统一性。而 Thanos Ruler 则通过从一个或多个数据源统一读取指标数据,集中执行规则,从而避免了这些问题。
在配置 ThanosRuler CRD 时,用户需要通过 queryEndpoints 字段指定数据源,也就是 Thanos Ruler 将连接哪些 Prometheus 或 Thanos Querier 实例来获取时间序列数据。这些数据源会传递给 Ruler 实际运行时的
--query
参数。一般建议连接至 Thanos Querier,因为它可以聚合多个 Prometheus 实例的数据,实现更完整的视图。例如,在集群中配置如下字段:表示该 Ruler 实例将从 thanos-query 服务获取数据,这样它就可以评估规则文件中定义的表达式,触发告警或写入新指标。ThanosRuler 还支持定义规则文件的来源,通常以 ConfigMap 或 Secret 的形式挂载到 Pod 中。此外,它还可以将告警直接推送给 Alertmanager,从而实现 Prometheus 与 Alertmanager 解耦后的统一告警处理。
数据持久化
如果我们重启了 Prometheus 的 Pod,会发现我们之前采集的数据已经没有了,下面我们重启一下prometheus
我们打开Grafana查看监控数据,发现之前的数据丢失了

这是因为我们通过 prometheus 这个 CRD 创建的 Prometheus 并没有做数据的持久化,我们可以直接查看生成的 Prometheus Pod 的挂载情况就清楚了
我们可以看到 Prometheus 的数据目录
/prometheus
实际上是通过 emptyDir
进行挂载的,我们知道 emptyDir 挂载的数据的生命周期和 Pod 生命周期一致的,所以如果 Pod 挂掉了,数据也就丢失了,这也就是为什么我们重建 Pod 后之前的数据就没有了的原因。对应线上的监控数据肯定需要做数据的持久化的,同样的 prometheus 这个 CRD 资源也为我们提供了数据持久化的配置方法,由于我们的 Prometheus 最终是通过 Statefulset 控制器进行部署的,所以我们这里通过 StorageClass 来做数据持久化,此外由于 Prometheus 本身对 NFS 存储没有做相关的支持,所以线上一定不要用 NFS 来做数据持久化,对于如何去为 prometheus 这个 CRD 对象配置存储数据,我们可以去查看官方文档 API,也可以用 kubectl explain
命令去了解我们这里在 prometheus 的 CRD 对象中通过 storage 属性配置
volumeClaimTemplate
对象,更新完成后会自动生成两个 PVC 和 PV 资源对象,如果你的环境没有配置动态存储,那么我们可以手动创建,先创建一个StorageClass
手动创建 PersistentVolume,并关联 StorageClass
查看PVC
现在我们再去看 Prometheus Pod 的数据目录就可以看到是关联到一个 PVC 对象上了
现在即使我们的 Pod 挂掉了,数据也不会丢失了
- 链接:www.qianshuai.cn/article/prometheusoperator
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。