背景
没有资源监控前,应用的资源指标(cpu / mem / db / oss)无法得知,用户很难根据自己的业务规模评估合适的规格配置;不能清楚地发现当前应用状态:是否有内存泄露、是否需要开启弹性伸缩、当前的应用实例数等等。有了资源监控,这些问题统统解决。
实现方案
- 前端轮询后端请求监控数据,后端向 Prometheus 发起 HTTP 查询请求,Prometheus 会根据请求从自带的数据库中查询数据并返回,后端完成整合工作后返回给前端。
- Prometheus 会根据采集规则轮询需要采集的监控目标,将数据指标 (metrics) 存到数据库里。
组件介绍
- Prometheus 是一个开源的监控和警报工具,通过 Pull 模式来获取目标服务的监控指标数据(如cpu和内存等),内置了一个时间序列数据库来存储收集到的指标数据,内置 PromQL 来查询数据(类似于使用SQL语句查询数据库),自带一个 Web UI 来快速验证查询结果。
- Prometheus 的 Exporter 是一种适配器,用于采集非原生支持 Prometheus 的第三方系统或服务的指标数据,并将其转换为 Prometheus 可以识别的格式。Exporter运行为一个单独的服务,周期性地从目标系统中拉取原始指标,然后提供一个HTTP端点,使得 Prometheus 可以从中抓取已转换的指标数据。不同的系统和服务需要不同的Exporter,例如,MongoDB Exporter 用于 抓取 MongoDB 数据库的指标;而 Minio 原生支持Prometheus,不需要单独的 Exporter。
环境搭建和部署
我们想要采集的指标包括 CPU、内存、MongoDB 和 MinIO 的用量,这里只演示前三者
首先部署 Prometheus
使用 Helm 部署 kube-stack-prometheus
> kube-prometheus-stack
是一个 Kubernetes 的监控和告警套件,整合了 Prometheus、Grafana 及其他相关组件,通过 Prometheus Operator 简化部署和管理,提供从节点到Kubernetes 对象的全面监控,并支持通过 Grafana 进行数据可视化。
>
cat <<EOF > values.yaml
fullnameOverride: prometheus
prometheus:
prometheusSpec:
storageSpec:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 20Gi
EOF
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml
为了采集 MongoDB 的 db 大小,需要部署 MongoDB Exporter
DATABASE_URL=<mongodb-uri-need-to-monitor>
helm install prometheus-mongodb-exporter -n laf-system \
--set image.tag="0.39.0"
--set mongodb.uri=${DATABASE_URL} \
--set serviceMonitor.enabled=true \
--set serviceMonitor.additionalLabels.release=prometheus \
--set serviceMonitor.additionalLabels.namespace=monitoring \
prometheus-community/prometheus-mongodb-exporter
- 部署完成后,使用
kubectl port-forward
进入 Prometheus 的 Web UI,查看各采集目标是否都 UP 了。至此,Prometheus 便会根据采集规则定期地去轮询各采集目标,得到采集数据存到数据库中。
编写 PromQL 查询语句验证效果
什么是 PromQL
- 概念:PromQL 是 Prometheus Query Language 的缩写,它是用于 Prometheus 数据库的专用查询语言。Prometheus 主要用于监控系统和时间序列数据库,PromQL 使用户能够查询和分析收集的数据,在 Prometheus 的界面或其他集成工具中,PromQL 可用于生成数据的可视化图表。
- 类比:想象一下 ,SQL 用于关系型数据库,PromQL 就是用于 Prometheus 时间序列数据库的。就像使用 SQL 查询关系型数据库中的数据一样,使用 PromQL 查询 Prometheus 中的时间序列数据。
- 例子:
- 查询某个服务的平均响应时间:
http_requests_duration_seconds_sum / http_requests_total
- 查询在过去5分钟内的平均 CPU 使用率:
rate(node_cpu_seconds_total[5m])
- 根据条件设置警报,例如,当某个服务的请求错误率超过1%时:
rate(http_requests_total{status_code=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.01
我们需要的PromQL
sum(rate(container_cpu_usage_seconds_total{image!="",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[1m])) by (pod)
sum(container_memory_working_set_bytes{image!="",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (pod)
sum(mongodb_dbstats_dataSize{database="${opts.appid}"})
sum(minio_bucket_usage_total_bytes{bucket=~"${opts.appid}.+"})
打开 Prometheus 的 Web UI 页面验证
后端代码实现
我们需要查询的数据包括瞬时值(db 和 oss 的大小)和范围值( cpu 和内存在一段时间内的波动)
const url = "http://prometheus-prometheus.monitoring:9090"
const promql = ""
const range = 3600 // 1 hour
const now = Math.floor(Date.now() / 1000)
const start = now - range // 向前推进一小时
const end = now
const query = {
query: promql,
range,
step: 60,
start,
end,
}
const res = await axios.get(url, { params: query })
return res.data.data.result
const url = "http://prometheus-prometheus.monitoring:9090"
const promql = ""
const query = {
query: promql,
}
const res = await axios.get(url, { params: query })
return res.data.data.result
前端部分