Grafana合并Prometheus模板变量的解决方案求助
我明白你的需求:把原本两个分别对应Deployment和Statefulset的模板变量,合并成一个单一下拉选择器,让用户只能选择其中一种资源(要么某个Deployment,要么某个Statefulset),而不是同时选两类。下面是具体的实现步骤,基于Prometheus数据源和kube-state-metrics(这是关键,它能提供K8s资源的元数据指标):
1. 确认依赖:kube-state-metrics部署状态
首先确保你的K8s集群里已经部署了kube-state-metrics,它会暴露K8s资源的核心元数据指标,比如kube_deployment_info(对应Deployment)和kube_statefulset_info(对应Statefulset)。如果还没部署,先通过Helm或者官方YAML完成部署。
2. 创建合并后的模板变量
在Grafana仪表盘中进入「设置」→「变量」→「添加变量」:
- 变量类型选择「Query」
- 数据源选择你的Prometheus实例
- 在「查询」框中输入以下PromQL:
这个查询的作用是:label_replace(kube_deployment_info{}, "resource", "deployment:$1", "deployment", "(.*)") OR label_replace(kube_statefulset_info{}, "resource", "statefulset:$1", "statefulset", "(.*)")- 给每个Deployment的名称加上
deployment:前缀 - 给每个Statefulset的名称加上
statefulset:前缀 - 把两类资源的结果合并成一个统一列表
- 给每个Deployment的名称加上
- 在「标签」下拉框中选择
resource,这样下拉选项就会显示类似deployment:my-app-deploy、statefulset:my-db-sts的内容 - 其他设置:保持「多选」不勾选(符合你“仅选一个”的需求),「排序」可选「字母顺序」让选项更规整。
3. 在面板查询中使用这个变量
当用户选择了某个资源后,你需要在面板的PromQL中拆分这个变量,提取出资源类型和名称。比如:
假设你的变量名叫selected_resource,要查询该资源下Pod的CPU使用率,可以这样写:
sum(rate(container_cpu_usage_seconds_total{ pod=~"${selected_resource:regex_replace(/^.*:/, '')}-.*" }[5m])) by (pod)
这里用了Grafana的变量替换功能regex_replace,把selected_resource中:前面的类型前缀去掉,只保留资源名称,然后匹配对应的Pod(通常Deployment/Statefulset的Pod名称会以资源名称为前缀)。
如果需要更精准的标签匹配,也可以结合kube-state-metrics的指标关联:
sum(rate(container_cpu_usage_seconds_total{ namespace=~"$namespace", pod=~"^(kube-state-metrics:kube_deployment_info{deployment=~\"${selected_resource:regex_replace(/^.*:/, '')}\"} >> on(deployment) group_left(pod) kube_pod_info{})$" }[5m])) by (pod)
不过这种方式稍复杂,前面的前缀匹配在大多数场景下已经足够。
4. (可选)优化下拉选项显示
如果你觉得deployment:xxx的格式不够直观,可以修改PromQL,让选项显示成更友好的样式:
label_replace(kube_deployment_info{}, "resource", "$1 (Deployment)", "deployment", "(.*)") OR label_replace(kube_statefulset_info{}, "resource", "$1 (Statefulset)", "statefulset", "(.*)")
这样下拉选项就会变成my-app-deploy (Deployment)、my-db-sts (Statefulset),用户一眼就能区分资源类型。
内容的提问来源于stack exchange,提问作者Matt

