(一)ACK prometheus-operator 之架构梳理

简介: 本文以troubleshooting的思维为切入点,深入梳理prometheus-operator架构原理,技术上跟阿里云arms_prometheus是相通的,便于在问题场景中快速定位。

前提条件

本文环境基于阿里云ACK专有集群1.22以及ACK应用市场的ack-prometheus-operator  chart 12.0.0。


概念区分

Prometheus-Operator vs Prometheus vs Kube-Prometheus

这是三个不同的开源项目,概念上不要混淆,简单看下三者关联:

Prometheus:用于监控k8s集群,收集容器集群的监控指标,可以作为三方展示平台比如grafana的数据源。

Prometheus Operator可用于管理Prometheus,operator本身并不做监控,可以看成是prometheus的自动化运维工具, 类似是一个翻译器,用于将便捷的配置翻译成标准prometheus配置文件。

Kube-Prometheus : 目前k8s集群监控的主流项目,主要使用Prometheus做集群监控,使用Prometheus Operator做监控的运维管理,也就是以上二者的结合。

ACK应用市场的ACK-Prometheus-Operator 新版本是集成了kube-prometheus的。本文基于ACK-Prometheus-Operator chart 12.0.0,也就是kube-prometheus展开解析。

ACK-Prometheus-Operator 架构

一句话总结,ACK-Prometheus-Operator Kube-Prometheus主要包含Prometheus-operator控制器、prometheus server监控系统、各种exporter做指标采集组件和prometheus alert报警系统。本系列不涉及alert组件。


本文重点章节:

最后一节,《Prometheus-Operator 配置更新流程》, 分别介绍了:

标准prometheus配置解读

Operator CRD配置之间的匹配关系

Prometheus如何reload新配置

配置更新生效流程

Prometheus-Operator 架构

分别梳理prometheus以及prometheus-operator两部分。

  • prometheus官网给出的架构图如下:


Prometheus  本身就是一个k8s 监控系统,负责实现对监控数据的获取,存储以及查询。Prometheus server 的基本原理是通过 HTTP/HTTPS 周期性抓取被监控目标的 metrics(指标)数据,任意组件只要提供对应的 HTTP/HTTPS 接口并且符合 Prometheus 定义的数据格式,就可以接入 Prometheus 监控。在监控领域,有PUSH/PULL两种概念,prom-operator 这种由prom server 调用被监控对象(targets)获取监控数据的方式被称为 Pull(拉) 。

ACK-prometheus便是采用pull方式 (此处对比的是pushgateway,ACK-prometheus-operator 组件没有单独部署pushgateway做指标的“push”)。其次,Prometheus Server 需要对采集到的监控数据进行存储,Prometheus Server 本身就是一个时序数据库,将采集到的监控数据按照时间序列的方式存储在本地磁盘当中。


Prometheus-Operator官网给出的架构图。

可以直观的看出Prometheus-Operator负责部署和管理prometheus server.


Operator 是 Kubernetes 的一种自定义资源的控制器,就像KCM组件内置资源控制器如deployment  controller 管理deployment一样,Prometheus-Operator会管理控制prometheus相关资源,可以参考CNCFOperator 白皮书

Prometheus-Operator根据相关CRD(servicemonitor等)配置及时更新prometheus server的监控对象(targets)使其可以按照实际配置预期运行,可以将Prometheus-Operator看成一个代码化的自动化的简化prometheus 部署维护操作的高级运维人员。


Prometheus-Operator既然是一种k8s controller,则具备 k8s controller的通用性架构。通用k8s控制器内部可以分informer -worker queue -control loop三部分,不在本文做赘述,只是了解下prometheus-operator 也是基于这种架构不断的watch apiserver中相关crd的变更去推动prometheus 的配置更新。

图来自 《https://kingjcy.github.io/post/cloud/paas/base/kubernetes/k8s-controller/


ACK-Prometheus-Operator 部署

ACK-Prometheus-Operator 集成 kube-prometheus架构中的组件详细介绍请各自参考超链接中的官网,不做赘述。ACK应用市场基于helm chart 部署后,主要部署了以下几个组件:


在ACK-prometheus-operator 架构中,各个组件对应形式如下:

部署组件

映射在ACK中的资源

类型

怎么部署到ack集群的

Prometheus Operator

ack-prometheus-operator-operator

Deployment

helm部署

Prometheus server

prometheus-ack-prometheus-operator-prometheus

statefulset

prometheus-operator 根据helm部署的CRD prometheus 部署 statefulset

Alertmanager

alertmanager-ack-prometheus-operator-alertmanager

statefulset

prometheus-operator 根据helm部署的CRD alertmanagers 部署statefulset

Prometheus node-exporter

ack-prometheus-operator-prometheus-node-exporter

DaemonSet

helm部署

Grafana

ack-prometheus-operator-grafana

Deployment

helm部署

kube-state-metrics

ack-prometheus-operator-kube-state-metrics

Deployment

helm部署


Prometheus-Operator CRD资源

Prometheus-Operator 是本文的重点,以deployment的形式存在,其中包含了所有CRD的schema定义、模型,以及各CRD的处理逻辑。它负责部署并管理相关CRD资源,定期循环watch apiserver, 将相关的CRD更新/配置更新及时应用到运行中的prometheus系统中。

这些CRD都是一些方便使用人员配置的项目,以k8s用户熟悉的方式(label、selectors)定义prometheus的scrap job, 支持多种label比较方式: In, NotIn, Exists, DoesNotExists 。

k8s用户更新CRD后,最终会被operator翻译成prometheus标准的配置文件,prometheus.yml完成自动更新和生效,无需重启prometheus实例。

每一个CRD的标准格式不赘述,在配置环节会有具体示例。以下CRD可以通过kubectl get xx 获取具体信息。

CRD 名称

作用

Prometheus

最核心的一个CRD, 控制prometheus server的statefulset状态。

该CRD用于部署、管理prometheus stateful实例,以及配置该prometheus实例与ServiceMonitor(通过serviceMonitorNamespaceSelector标签)、Altermanager(通过alertmanagers标签)、PromtheusRule(通过ruleSelector标签)之间的关联。   一个Prometheus crd 资源创建后,promtheus-operator会自动创建一个prometheus stateful实例。

ServiceMonitor

纯配置,Operator告诉prometheus server , 要监控的 targets是基于k8s service动态发现。 Operator基于servicemonitor的配置生成promtheus的标准配置文件promtheus.yml。

注意的是,ServiceMonitor中的endpoint被转换为prometheus.yml中的kubernetes_sd_configs标签,即服务发现仍然是通过prometheus的原生能力完成的,ServiceMonitor或prometheus-operator并不具备服务发现能力,仅仅是配置转换与应用能力。

PodMonitor

纯配置,类似于ServiceMonitor,只不过要监控的 targets是基于k8s pod label 动态发现,是针对pod级别的scrap job。

Alertmanager

用于部署和管理promtheus的Altermanager实例.一个Altermanager资源定义会对应于一个stateful实例,prometheus-opertaor会根据Alertmanager中指定replicas、image、RBAC等信息将promtheus的altermanager pod部署,prometheus实例会自动与该Alertmanager相关联,共同完成监控->告警的链路。

PrometheusRule

用于生成promtheus的告警规则文件.纯配置项。promtheus-operator会将该资源转换为prometheus的rule文件,挂在于prometheus实例的文件系统中:

alertmanagerconfigs

Alertmanager配置, 默认无配置。

probes

默认无配置。

thanosrulers

控制Thanos deployment, 默认无配置。


各个CRD以及operator之间的关系:



图来自《https://v1-0.choerodon.io/zh/blog/prometheus-operator-introduce/



Prometheus-Operator 配置更新流程


Prometheus Server 可以通过静态配置static_configs管理监控目标,也可以配合使用 Service/Pod Discovery 的方式(sd_config)动态管理监控目标,并从这些监控目标中获取数据。

Prometheus-operator 通过定期循环watch apiserver,获取到CRD资源(比如servicemonitor)的创建或者更新,将配置更新及时应用到运行中的prometheus pod中转换成标准promethesu配置文件供prom server使用。

标准prometheus配置解读

标准配置文件参考网上现成的分析就行,随手找了一个:https://developer.aliyun.com/article/830280


标准配置官方解析: https://prometheus.io/docs/prometheus/latest/configuration/configuration/示例


不过我们使用ack-prometheus-operator,其实是想尽量避免手写这种及其不易读容器出错的的配置,所以会利用operator CRD去做配置。


Operator CRD配置之间的匹配关系

使用CRD做prometheus配置,“匹配”是一个很重要的细节,详细匹配关系如图,任何地方匹配失败会导致转化成的标配prometheus文件无法识别到targets。




配置间的匹配总结就是:

ServiceMonitor注意事项:

  • ServiceMonitor的label  需要跟prometheus中定义的serviceMonitorSelector一致
  • ServiceMonitor的endpoints中port时对应k8s service资源中的portname, 不是port number.
  • ServiceMonitor的selector.matchLabels需要匹配k8s service中的label
  • ServiceMonitor资源创建在prometheus的namespace下,使用namespaceSelector匹配要监控的k8s svc的ns.
  • servicemonitor若匹配多个svc,会发生数据重复


PodMonitor注意事项:

  • PodMonitor的label  需要跟prometheus中定义的podMonitorSelector一致
  • PodMonitor的spec.podMetricsEndpoints.port 需要写pod中定义的port name,不能写port number。
  • PodMonitor的selector.matchLabels需要匹配k8s pod 中的label
  • PodMonitor资源创建在prometheus的namespace下,使用namespaceSelector匹配要监控的k8s pod的ns.



Prometheus如何reload新配置

简单讲就是重启进程或者调用HTTP /-/reload 接口:

A configuration reload is triggered by sending a SIGHUP to the Prometheus process or sending a HTTP POST request to the /-/reload endpoint (when the --web.enable-lifecycle flag is enabled). This will also reload any configured rule files.


Prometheus stateful pod 包含config-reloader  和 prometheus两个container。其中,config-reloader 用于定期调用reload接口去刷新配置。有几个时间间隔值需要了解下,新配置部署后需要等待的生效时间,参考官网。 可以看到,默认每3分钟reload一次新配置。

const (
 defaultWatchInterval = 3 * time.Minute // 3 minutes was the value previously hardcoded in github.com/thanos-io/thanos/pkg/reloader.
 defaultDelayInterval = 1 * time.Second // 1 second seems a reasonable amount of time for the kubelet to update the secrets/configmaps.
 defaultRetryInterval = 5 * time.Second // 5 seconds was the value previously hardcoded in github.com/thanos-io/thanos/pkg/reloader.
#
 watchInterval := app.Flag("watch-interval", "how often the reloader re-reads the configuration file and directories; when set to 0, the program runs only once and exits").Default(defaultWatchInterval.String()).Duration()
 delayInterval := app.Flag("delay-interval", "how long the reloader waits before reloading after it has detected a change").Default(defaultDelayInterval.String()).Duration()
 retryInterval := app.Flag("retry-interval", "how long the reloader waits before retrying in case the endpoint returned an error").Default(defaultRetryInterval.String()).Duration()
 watchedDir := app.Flag("watched-dir", "directory to watch non-recursively").Strings()


那如果测试期间不想等3分钟呢?除了重启,可以手动触发reload 么?(其实没必要)

先说结论:手动模拟方式:curl -X POST http://localhost:9090/-/reload   (localhost可以换成prom pod ip)


扩展:

pod中的多容器,为何netstat可以看到全部容器进程监听,ps 看不到?思考一下, 不在此处赘述。

config-reloader container: 自己的监听是8080,9090不是自己container的监听。

prometheus container,自己的监听是9090.


看下yaml定义进一步理解两个容器如何合作:


config-reloader容器启动参数可以看出,他会定期发出这个reload接口调用,由于9090是prometheus server container中的进程监听,其实是prometheus server响应的这个接口。 config-reload 进程负责的是定期call 9090端口的reload接口.



默认 prom server命令行开启了  --web.enable-lifecycle ,因此可以使用reload/quit 接口 (不开启这个参数则无法使用这俩接口)。prometheus container收到reload 接口调用后,便会reload  启动参数里定义的--config.file。



但是prometheus server container relaod的是固定文件--config.file,这个文件是如何获取/发现最新的配置内容呢?看下文。


配置更新生效流程

  • 1. helm或者kubectl更新servicemonitor、podmonitor或者prometheus CRD 中的配置(包含addtionalscrapeconfig)
  • 2. Prometheus-operator watch apiserver获取到以上CRD 中的更新
  • 3. Prometheus-operator 将捕捉到的更新都翻译成prometheus标准配置格式prometheus.yaml
  • 4. Prometheus-operator 打包prometheus.yaml 到secret “prometheus-ack-prometheus-operator-prometheus ” 中,存储为secret.data字段: prometheus.yaml.gz,
  • 5. 以上secret的data是被mount 给prometheus pod 的config-reloader  container中的。
  • 6. 由config-reloader 解压gz文件后读取出标准 prometheus.yml文件,通过empty-dir共享给prometheus container 。
  • 7. Prometheus 进程读取参数 --config.file 指定的文件路径,就是通过emptydir的共享文件,即config-reloader输出的config yaml文件。
  • 8. Prometheus server 根据配置中的relabel等信息,动态/静态发现要监控的targets, 对targets发起http/https请求抓取metrics数据。
  • 9. 抓取metrics数据存储后提供给UI做query查询,或者提供给grafana等做展示。

看下第六步config-reloader中的处理:


从secret中查看标准prom config配置:

kubectl get secret prometheus-ack-prometheus-operator-prometheus   -n monitoring -ojson|jq -r '.data["prometheus.yaml.gz"]' |base64 -d| gunzip

看下prometheus pod yaml中关于secret mount的定义:

containers:
#prometheus 启动参数读取emptydir实现的共享文件,即config-reloader输出的config yaml文件
          name: prometheus
        - args:
            - '--config.file=/etc/prometheus/config_out/prometheus.env.yaml'
          volumeMounts:
            - mountPath: /etc/prometheus/config_out
              name: config-out
#config-reloader 读取secret中的配置内容并gunzip为标准prom config yaml格式输出到config_out,config_out通过emptydir实现共享。
    name: config-reloader
        - args:
            - '--config-file=/etc/prometheus/config/prometheus.yaml.gz'
            - >-
              --config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml
          volumeMounts:
            - mountPath: /etc/prometheus/config
              name: config
            - mountPath: /etc/prometheus/config_out
              name: config-out
#volumes
  volumes:
        - name: config
          secret:
            defaultMode: 420
            secretName: prometheus-ack-prometheus-operator-prometheus
        - emptyDir: {}
          name: config-out
        - name: config
          secret:
            defaultMode: 420
            secretName: prometheus-ack-prometheus-operator-prometheus



参考:

https://yuque.antfin.com/xingyu.cxy/gz5g1e/uzs2k8

https://zhuanlan.zhihu.com/p/342823695

https://yunlzheng.gitbook.io/prometheus-book/part-iii-prometheus-shi-zhan/operator/what-is-prometheus-operator

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
8月前
|
运维 Kubernetes Cloud Native
智联招聘 × 阿里云 ACK One:云端弹性算力颠覆传统 IDC 架构,打造春招技术新范式
在 2025 年春季招聘季的激战中,智联招聘凭借阿里云 ACK One 注册集群与弹性 ACS 算力的深度融合,成功突破传统 IDC 机房的算力瓶颈,以云上弹性架构支撑千万级用户的高并发访问,实现招聘服务效率与稳定性的双重跃升。
|
运维 Kubernetes Docker
利用Docker和Kubernetes构建微服务架构
利用Docker和Kubernetes构建微服务架构
|
11月前
|
Prometheus Kubernetes 监控
Kubernetes监控:Prometheus与AlertManager结合,配置邮件告警。
完成这些步骤之后,您就拥有了一个可以用邮件通知你的Kubernetes监控解决方案了。当然,所有的这些配置都需要相互照应,还要对你的Kubernetes集群状况有深入的了解。希望这份指南能帮助你创建出适合自己场景的监控系统,让你在首次发现问题时就能做出响应。
647 22
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
557 82
|
12月前
|
Kubernetes 监控 Serverless
基于阿里云Serverless Kubernetes(ASK)的无服务器架构设计与实践
无服务器架构(Serverless Architecture)在云原生技术中备受关注,开发者只需专注于业务逻辑,无需管理服务器。阿里云Serverless Kubernetes(ASK)是基于Kubernetes的托管服务,提供极致弹性和按需付费能力。本文深入探讨如何使用ASK设计和实现无服务器架构,涵盖事件驱动、自动扩展、无状态设计、监控与日志及成本优化等方面,并通过图片处理服务案例展示具体实践,帮助构建高效可靠的无服务器应用。
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
642 60
|
12月前
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
12月前
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
Kubernetes API 调度
【赵渝强老师】Kubernetes的体系架构
本文介绍了Kubernetes的体系架构及其核心组件。Kubernetes采用主从分布式架构,由master主节点和多个node工作节点组成。master节点负责集群管理和调度,运行API Server、scheduler、controller-manager等服务组件;node节点运行kubelet、kube-proxy和Docker容器守护进程,负责实际业务应用的运行。文章还简要介绍了Kubernetes的附加组件及其作用。
247 5
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?

热门文章

最新文章

推荐镜像

更多