我有许多关于警报和仪表板使用的查询,其中有大量的复制/粘贴样板,用于过滤和使用标签进行丰富。
是否没有办法保存并重复使用这种重复的 PromQL 服务器端,就像 SQL 数据库中的视图一样?服务器端函数、宏……什么?
(我知道我可以将查询“保存”为记录规则,但是在加入标签时,这是非常低效的。记录规则必须公开任何人可能想要的每个标签,产生令人痛苦的高基数和昂贵的信息度量。它浪费了存储和内存,通过“只需为 Prometheus 添加另一 TB RAM”来“解决”它在云中很流行,但非常浪费。)
使用
kube-state-metrics
数据考虑此查询:
sum without(job,instance,service,endpoint,metrics_path,prometheus) (
kubelet_volume_stats_available_bytes{kube_cluster="$kube_cluster"}
# enrich with labels
* on (namespace,persistentvolumeclaim)
group_left(some_org_specific_label,other_org_specific_label)
group by (namespace,persistentvolumeclaim,some_org_specific_label,other_org_specific_label) (
kube_persistentvolumeclaim_labels{kube_cluster="$kube_cluster"}
)
* on (namespace,persistentvolumeclaim)
group_left(persistentvolume)
group by (namespace,persistentvolumeclaim,persistentvolume) (
# for some reason kube_persistentvolumeclaim_info uses label "volumename"
# and persistentvolume_info uses "persistentvolume"
label_replace(
kube_persistentvolumeclaim_info{kube_cluster="$kube_cluster"},
"persistentvolume", "$1", "volumename", "^(.*)$"
)
)
* on (persistentvolume)
group_left(csi_driver,csi_volume_handle,storageclass)
group by (persistentvolume,csi_driver,csi_volume_handle,storageclass) (
kube_persistentvolume_info
)
)
这只是说:
kubelet_volume_stats_available_bytes
获取 kube_cluster="$cluster"
kube_persistentvolumeclaim_labels
添加标签 some_org_specific_label
和 other_org_specific_label
kube_persistentvolumeclaim_info
查找与 persistentvolume
关联的 persistentvolumeclaim
名称(处理标签名称不一致)kube_persistentvolume_info
以查找持久卷的 CSI ID 和详细信息它很丑陋,但也不是那么糟糕......直到您还想编写另一个查询来获取可用磁盘空间百分比,以及另一个 I/O 阈值查询,等等。每个都重复相同的样板。 我似乎也需要手动下推过滤条件以实现高效查询,Prometheus 似乎不具备 SQL 引擎的过滤下推逻辑之类的功能。
这是一个
简短的示例。这是另一个,获取一个包含一些 kube pod 标签、kube pod 注释和正在运行的容器映像的工作负载指标:
# This aggregation drops unwanted labels, since PromQL lacks a proper label_drop(...) operator to drop non-cardinal labels
sum without(endpoint,instance,job,prometheus,container,uid) (
some_workload_specific_metric{kube_cluster="$kube_cluster"}
# join on kube_pod_labels for project-id, PGD info, etc
* on (uid)
group_left(org_specific_label_1, org_specific_label_2, org_specific_annotation_1)
# note the group_by (...) expression repeats the labels in both the on (...) join key and
# the subject-labels in group_left(...). This protects against issues where added or unrelated
# labels that aren't of interest can churn. It's probably safe to write
# group ignoring(container,instance,job=)
# in this case, but better to make the query robust:
group by (uid, org_specific_label_1, org_specific_label_2) (
kube_pod_labels{kube_cluster="$kube_cluster"}
)
# join on kube_pod_info for the node hosting the pod and the pod ip address
* on (uid)
group_left(pod_ip,node)
group by (uid, pod_ip, node) (
kube_pod_info{kube_cluster="$kube_cluster"}
)
# join on kube_pod_container_info for the container image. Note that we join on container_id too
* on (uid,container_id)
group_left(image_spec,image_id)
group by (uid,container_id,image_spec,image_id) (
kube_pod_container_info{kube_cluster="$kube_cluster"}
)
# join on kube_pod_annotations for org_specific_annotation_1, if any
* on (uid)
group_left(org_specific_annotation_1)
group by (uid,org_specific_annotation_1) (
kube_pod_annotations{kube_cluster="$kube_cluster"}
)
)
CREATE VIEW
Prometheus 不支持类似公共表表达式的功能(也称为 CTE)。如果您需要这样的功能,请尝试 VictoriaMetrics 的
WITH
表达式。例如,如果您想对不同的指标名称重复使用相同的查询,那么您可以将此查询放入
WITH
模板函数中,该函数接受指标名称,然后在需要时使用不同的指标名称调用此函数:
WITH (
f(m) = some_complex_query_here
)
(
f(foo), # expand the query with `foo` metric
f(bar), # expand the query with `bar` metric
)
免责声明:我是 MetricsQL 的作者。