• 解析 Prometheus PushGateway 推送监控指标全流程


    目录

    解析 Prometheus PushGateway 推送监控指标全流程

    安装

    基本使用

    Client SDK 推送

    API 推送

    抓取指标


    解析 Prometheus PushGateway 推送监控指标全流程

    我们知道 Prometheus 采用的 pull 模式,但是某些网络场景下面(比如不在一个子网或者防火墙),Prometheus 无法直接拉取监控指标数据,这个时候我们可能就需要一种能够主动 push 的模式了。而 Pushgateway 就是 Prometheus 生态中来解决这个问题的一个工具。

    但是 Pushgateway 也不是万能的,其本身也存在一些弊端:

    • 将多个节点数据汇总到 pushgateway, 如果 pushgateway 挂了,受影响范围更大

    • Prometheus 拉取状态 up 只针对 pushgateway, 无法做到对每个目标有效

    由于 Pushgateway 可以持久化推送给它的所有监控数据,所以即使你的监控已经下线,Prometheus 还会拉取到旧的监控数据,需要手动清理 Pushgateway 不要的数据。

    Pushgateway 的存在是为了允许临时和批处理作业向 Prometheus 暴露其指标。由于这些类型的任务可能存在的时间不够长而无法被抓取,因此他们可以将指标推送到 Pushgateway,然后 Pushgateway 将这些指标暴露给 Prometheus。有一点我们需要明白的是 Pushgateway 不是将指标主动 push 给 Prometheus,而是通过脚本将指标数据主动 push 给 Pushgateway 后,Prometheus 仍然通过 pull 模式去抓取指标

    前面我们也介绍过 node-exporter 中的 textfile 收集器也可以用来采集指标,似乎和 Pushgateway 比较相似,这二者有什么区别吗?textfile 通常是用于节点级别的指标,而 Pushgateway 是用于服务级别的指标。

    安装

    同样要安装 Pushgateway 也非常简单,直接从 Release 页面 下载适用于你平台的二进制版本并解压即可使用。如果你想从源码自行编译,可以在代码根目录下面直接执行 make 命令即可编译。

    直接执行 Pushgateway 二进制文件即可启动了,要更改监听的地址,可以通过 --web.listen-address 标志(例如0.0.0.0:9091:9091)指定。默认情况下 Pushgateway 不保留指标。但是 --persistence.file 标志允许我们指定一个文件,将推送的指标保存在其中,这样当 Pushgateway 重新启动后指标仍然存在。

    此外当然我们也可以直接使用 Docker 镜像来进行启动:

    docker run -d -p 9091:9091 prom/pushgateway
    

    同样我们这里还是将 Pushgateway 部署在 Kubernetes 集群中,对应的资源清单文件如下所示:

    1. # pushgateway.yaml
    2. apiVersion: v1
    3. kind: PersistentVolumeClaim
    4. metadata:
    5.   name: pushgateway-data
    6.   namespace: kube-mon
    7. spec:
    8.   accessModes:
    9.     - ReadWriteOnce
    10.   resources:
    11.     requests:
    12.       storage: 2Gi
    13.   storageClassName: local-path
    14. ---
    15. apiVersion: apps/v1
    16. kind: Deployment
    17. metadata:
    18.   name: pushgateway
    19.   namespace: kube-mon
    20.   labels:
    21.     app: pushgateway
    22. spec:
    23.   selector:
    24.     matchLabels:
    25.       app: pushgateway
    26.   template:
    27.     metadata:
    28.       labels:
    29.         app: pushgateway
    30.     spec:
    31.       volumes:
    32.         - name: data
    33.           persistentVolumeClaim:
    34.             claimName: pushgateway-data
    35.       containers:
    36.         - name: pushgateway
    37.           image: prom/pushgateway:v1.4.3
    38.           imagePullPolicy: IfNotPresent
    39.           args:
    40.             - "--persistence.file=/data"
    41.           ports:
    42.             - containerPort: 9091
    43.               name: http
    44.           volumeMounts:
    45.             - mountPath: "/data"
    46.               name: data
    47.           resources:
    48.             requests:
    49.               cpu: 100m
    50.               memory: 500Mi
    51.             limits:
    52.               cpu: 100m
    53.               memory: 500Mi
    54. ---
    55. apiVersion: v1
    56. kind: Service
    57. metadata:
    58.   name: pushgateway
    59.   namespace: kube-mon
    60.   labels:
    61.     app: pushgateway
    62. spec:
    63.   selector:
    64.     app: pushgateway
    65.   type: NodePort
    66.   ports:
    67.     - name: http
    68.       port: 9091
    69.       targetPort: http

    这里我们 --persistence.file 指定了持久化的文件,然后通过一个 Service 来暴露了服务,直接应用上面的资源清单文件即可:

    1. ☸ ➜ kubectl apply -f https://p8s.io/docs/pushgateway/manifests/pushgateway.yaml
    2. ☸ ➜ kubectl get pods -n kube-mon -l app=pushgateway
    3. NAME                           READY   STATUS    RESTARTS   AGE
    4. pushgateway-7684cbb67d-6mbjn   1/1     Running   0          99s
    5. ☸ ➜ kubectl get svc -n kube-mon -l app=pushgateway
    6. NAME          TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
    7. pushgateway   NodePort   10.106.136.207   <none>        9091:30893/TCP   107s

    默认情况下 Pushgateway 会提供一个简单的 Web 页面,可以查看当前具有哪些指标。

    基本使用

    Pushgateway 的数据推送支持两种方式,Prometheus Client SDK 推送和 API 推送。

    Client SDK 推送

    Prometheus 本身提供了支持多种语言的 SDK,可通过 SDK 的方式,生成相关的数据,并推送到 Pushgateway,当然这种方式需要客户端代码支持,这也是官方推荐的方案。目前的 SDK 覆盖语言有官方的:

    • Go

    • Java or Scala

    • Python

    • Ruby

    也有许多第三方的库,详情可参见此链接:https://prometheus.io/docs/instrumenting/clientlibs/

    这里我们以 Python 为例进行说明。

    首先安装 Prometheus 的 Python SDK:

    ☸ ➜ pip install prometheus-client
    

    然后创建一个名为 app.py 的文件,内容如下所示:

    1. from prometheus_client import CollectorRegistry, Counter, Gauge, push_to_gateway
    2. registry = CollectorRegistry()
    3. g = Gauge('container_memory''Container memory data', ['node'], registry=registry)
    4. g.labels(node='node1').inc()      # +1
    5. g.labels(node='node2').dec(10)    # -10
    6. g.labels(node='node3').set(4.2)   # 4.2
    7. c = Counter('my_requests_total''HTTP requests total', ['method''endpoint'], registry=registry)
    8. c.labels(method='get', endpoint='/').inc()
    9. c.labels(method='post', endpoint='/submit').inc()
    10. push_to_gateway('192.168.0.106:30893', job='batchA', registry=registry)

    首先引入了 Prometheus 的 Python SDK,然后创建了一个 CollectorRegistry 实例,分别创建了一个 Gauge 和 Counter 类型的指标,其中第一个参数为指标名称,第二个参数为指标的注释信息,第三个参数为相关的标签,然后为不同的标签值设置不同的指标值,最后通过 push_to_gateway 函数将指标数据发送到指定的 Pushgateway 服务上去。

    直接执行上面的 Python 文件即可将数据推送到 Pushgateway:

    ☸ ➜ python app.py
    

    API 推送

    此外使用 Prometheus 文本协议,推送指标也是非常简单的,无需提供单独的 CLI。只需使用 curl 之类的命令行工具即可。

    不过需要注意,在文本协议中,每一行都必须以换行符结尾('LF' 或 '\n'),以其他方式结束一行,例如使用 'CR''\r')、'CRLF''\r\n')或只是数据包的结尾,将导致协议错误。

    推送的指标按组进行管理,由任意数量的标签组成的分组键识别,其中第一个必须是 job 标签。

    比如我们现在将单个样本推送到由 {job="some_job"} 标识的组中:

    ☸ ➜ echo "some_metric 3.14" | curl --data-binary @- http://192.168.0.106:30893/metrics/job/some_job
    

    需要注意由于没有提供类型信息, 所以这里的 some_metric 将是 UNTYPED 无类型的。

    上面的命令执行完后我们可以重新前往 Pushgateway 的 Web 页面查看。

    可以看到页面中就出现了上面我们推送的 some_metric 这个指标,而且位于 job="some_job" 这个分组下面。

    接下来我们再推送一些相对复杂的指标,推到 {job="some_job",instance="some_instance"} 标识的分组中去,继续之前记得将上面的分组删除,然后执行下面的命令:

    1. ☸ ➜ cat <binary @- http://192.168.0.106:30893/metrics/job/some_job/instance/some_instance
    2.   # TYPE some_metric counter
    3.   some_metric{label="val1"42
    4.   # TYPE another_metric gauge
    5.   # HELP another_metric Just an example.
    6.   another_metric 2398.283
    7. EOF

    该命令会将指标推送到 {job="some_job",instance="some_instance"} 标识的分组中去,要注意指标内容中是如何提供类型信息和帮助信息的,这里我们的指标是都具有类型了。

    在 Web 界面中就可以看到上面推送的两个指标了,一个是 COUNTER 类型,一个是 GAUGE 类型。

    如果你想删除某个分组下面的所有指标,我们也可以通过 curl 命令来实现。比如删除由 {job="some_job",instance="some_instance"} 标识的分组中的所有指标,可以通过下面的命令来实现:

    ☸ ➜ curl -X DELETE http://192.168.0.106:30893/metrics/job/some_job/instance/some_instance
    

    这里需要注意的是删除是根据分组标识进行删除的,比如我们要删除由 {job="some_job"} 标识的分组中的所有指标,那么可以用下面的命令来实现:

    ☸ ➜ curl -X DELETE http://192.168.0.106:30893/metrics/job/some_job
    

    但是需要注意这里是不包括上面示例 {job="some_job",instance="some_instance"} 分组中的指标的,即使这些指标具有相同的 job 标签,这点非常重要。

    如果你想删除所有组中的所有指标,可以使用下面的命令来实现:

    1. ☸ ➜ curl -X PUT http://192.168.0.106:30893/api/v1/admin/wipe

    但是需要注意需要通过 Pushgateway 的命令行标志 --web.enable-admin-api 来启用管理 API。

    抓取指标

    现在我们需要将 Pushgateway 的指标配置到 Prometheus 中去,让 Prometheus 去主动抓取 Pushgateway 的指标数据,我们当然也可以使用服务发现的方式,这里我们单独为 Pushgateway 创建一个抓取任务,在 Prometheus 中添加如下所示的抓取配置:

    1. scrape_configs:
    2.   - job_name: "pushgateway"
    3.     kubernetes_sd_configs:
    4.       - role: endpoints
    5.     relabel_configs:
    6.       - source_labels:
    7.           [__meta_kubernetes_namespace, __meta_kubernetes_service_name]
    8.         action: keep
    9.         regex: kube-mon;pushgateway
    10. # 省略其他配置......

    我们这里同样采用基于 endpoints 的自动发现的方式来进行配置,去匹配 kube-mon 这个命名空间下名为 pushgateway 的服务即可。正常更新上面的配置后 Prometheus 就会自动去发现 Pushgateway 这个服务了。

    现在我们重新推送下面的指标:

    1. ☸ ➜ cat <binary @- http://192.168.0.106:30893/metrics/job/some_job/instance/some_instance
    2.   # TYPE some_metric counter
    3.   some_metric{label="val1"42
    4.   # TYPE another_metric gauge
    5.   # HELP another_metric Just an example.
    6.   another_metric 2398.283
    7. EOF

    推送完成后我们就可以在 Prometheus 中去查询 some_metric 和 another_metric 这两个指标了。

    Prometheus 会给每个抓取的指标附加一个 job 和 instance 的标签,job 标签来自 scrape 配置,我们这里抓取 Pushgateway 的 job 标签为 job="pushgateway"instance 标签的值会自动设置为抓取目标的主机和端口,所以所有从 Pushgateway 抓取的指标都会有 Pushgateway 的主机和端口作为 instance 标签,但是这可能会和你附加推送到 Pushgateway 指标上的 job 和 instance 标签冲突,这个时候 Prometheus 会将这些标签重命名为 exported_job 和 exported_instance

    但是,在抓取 Pushgateway 时,通常不希望出现这种行为。更多的时候你可能更希望保留推送到 Pushgateway 的指标的 job 和 instance 标签,这个时候我们只需要在 Pushgateway 的抓取配置中设置 honor_labels: true 即可,我们重新更新 Prometheus 的配置:

    上面抓取 Pushgateway 的任务中我们新增了一个 honor_labels: true 的配置,更新后我们重新去查询推送到 Pushgateway 中的两个指标。

    可以看到 job 和 instance 这两个标签变成了我们推送到 Pushgateway 中的标签值了,这个可能更符合我们的预期。

    另外需要注意的是 Pushgateway 不提供任何强一致性保证,没有高可用的方案,它可以做的最好的事情就是将每个指定时间段的指标保存到磁盘了,总之不到万不得已的情况下最好别用 Pushgateway。

    已获独家授权,尊重原创!

    推荐阅读:

    Kafka 高吞吐、高性能核心技术及最佳应...

    高并发服务中的智能流控...

    Mysql 数据库优化秘籍...

    数据库分库分表可扩展及数据倾斜/热点问题...

    Java 的进化之路到了尽头...

  • 相关阅读:
    Nginx学习(12)—— 配置指令整理
    5.4 Go语言中自定义类型与结构体(Struct)
    Elasticsearch 8.10 中引入查询规则 - query rules
    Cesium案例(八) Terrain
    PAT 1061 Dating
    手写vue路由
    spring整合mybatis
    认识kubenetes的核心组件之一kubelet
    Go复合类型之数组类型
    安装自己build iso报错
  • 原文地址:https://blog.csdn.net/qq_34417408/article/details/126298458