16
社区成员
发帖
与我相关
我的任务
分享目录
安装
基本使用
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 集群中,对应的资源清单文件如下所示:
# pushgateway.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pushgateway-data
namespace: kube-mon
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
storageClassName: local-path
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pushgateway
namespace: kube-mon
labels:
app: pushgateway
spec:
selector:
matchLabels:
app: pushgateway
template:
metadata:
labels:
app: pushgateway
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: pushgateway-data
containers:
- name: pushgateway
image: prom/pushgateway:v1.4.3
imagePullPolicy: IfNotPresent
args:
- "--persistence.file=/data"
ports:
- containerPort: 9091
name: http
volumeMounts:
- mountPath: "/data"
name: data
resources:
requests:
cpu: 100m
memory: 500Mi
limits:
cpu: 100m
memory: 500Mi
---
apiVersion: v1
kind: Service
metadata:
name: pushgateway
namespace: kube-mon
labels:
app: pushgateway
spec:
selector:
app: pushgateway
type: NodePort
ports:
- name: http
port: 9091
targetPort: http
这里我们 --persistence.file 指定了持久化的文件,然后通过一个 Service 来暴露了服务,直接应用上面的资源清单文件即可:
☸ ➜ kubectl apply -f https://p8s.io/docs/pushgateway/manifests/pushgateway.yaml
☸ ➜ kubectl get pods -n kube-mon -l app=pushgateway
NAME READY STATUS RESTARTS AGE
pushgateway-7684cbb67d-6mbjn 1/1 Running 0 99s
☸ ➜ kubectl get svc -n kube-mon -l app=pushgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
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 的文件,内容如下所示:
from prometheus_client import CollectorRegistry, Counter, Gauge, push_to_gateway
registry = CollectorRegistry()
g = Gauge('container_memory', 'Container memory data', ['node'], registry=registry)
g.labels(node='node1').inc() # +1
g.labels(node='node2').dec(10) # -10
g.labels(node='node3').set(4.2) # 4.2
c = Counter('my_requests_total', 'HTTP requests total', ['method', 'endpoint'], registry=registry)
c.labels(method='get', endpoint='/').inc()
c.labels(method='post', endpoint='/submit').inc()
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"} 标识的分组中去,继续之前记得将上面的分组删除,然后执行下面的命令:
☸ ➜ cat <<EOF | curl --data-binary @- http://192.168.0.106:30893/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
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 标签,这点非常重要。
如果你想删除所有组中的所有指标,可以使用下面的命令来实现:
☸ ➜ 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 中添加如下所示的抓取配置:
scrape_configs:
- job_name: "pushgateway"
kubernetes_sd_configs:
- role: endpoints
relabel_configs:
- source_labels:
[__meta_kubernetes_namespace, __meta_kubernetes_service_name]
action: keep
regex: kube-mon;pushgateway
# 省略其他配置......
我们这里同样采用基于 endpoints 的自动发现的方式来进行配置,去匹配 kube-mon 这个命名空间下名为 pushgateway 的服务即可。正常更新上面的配置后 Prometheus 就会自动去发现 Pushgateway 这个服务了。
现在我们重新推送下面的指标:
☸ ➜ cat <<EOF | curl --data-binary @- http://192.168.0.106:30893/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
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 中的标签值了,这个可能更符合我们的预期。
————————————————
版权声明:本文为CSDN博主「魏小言」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34417408/article/details/126298458
博主博客已看,干货满满,已支持师傅,期望师傅能输出更多干货,并强烈给师傅五星好评
另外,如果可以的话,期待师傅能给正在参加年度博客之星评选的我一个五星好评,您的五星好评都是对我的支持与鼓励(帖子中有大额红包惊喜哟,不要忘记评了五星后领红包哟)
⭐ ⭐ ⭐ ⭐ ⭐ 博主信息⭐ ⭐ ⭐ ⭐ ⭐
博主:橙留香Park
本人原力等级:5
链接直达:https://bbs.csdn.net/topics/611387568
微信直达:Blue_Team_Park
⭐ ⭐ ⭐ ⭐ ⭐ 五星必回!!!⭐ ⭐ ⭐ ⭐ ⭐
点赞五星好评回馈小福利:抽奖赠书 | 总价值200元,书由君自行挑选(从此页面参与抽奖的同学,只需五星好评后,参与抽奖