如何设置Spinnaker阶段比较Prometheus指标并控制流水线执行
实现Prometheus指标对比并触发CI阶段失败的方案
一、Bash Script阶段实现
直接在CI的脚本阶段调用Prometheus API获取指标值,通过对比结果的退出码控制阶段成败。
具体脚本示例
# 配置Prometheus地址和查询时间范围 PROMETHEUS_URL="http://your-prometheus-instance:9090" QUERY_RANGE="5m" # 查询MetricA的sum(rate)结果 METRIC_A=$(curl -s "$PROMETHEUS_URL/api/v1/query?query=sum(rate(MetricA{}[$QUERY_RANGE]))" | jq -r '.data.result[0].value[1]') # 查询MetricB的sum(rate)结果 METRIC_B=$(curl -s "$PROMETHEUS_URL/api/v1/query?query=sum(rate(MetricB{}[$QUERY_RANGE]))" | jq -r '.data.result[0].value[1]') # 处理指标查询为空的异常情况 if [[ -z "$METRIC_A" || -z "$METRIC_B" ]]; then echo "Failed to fetch metrics from Prometheus" exit 1 fi # 浮点数对比,满足条件则返回非0退出码触发阶段失败 if (( $(echo "$METRIC_A > $METRIC_B" | bc -l) )); then echo "Failed: sum(rate(MetricA)) ($METRIC_A) is greater than sum(rate(MetricB)) ($METRIC_B)" exit 1 else echo "Passed: sum(rate(MetricA)) ($METRIC_A) is less than or equal to sum(rate(MetricB)) ($METRIC_B)" exit 0 fi
注意事项
- 确保CI环境已安装
curl、jq(用于解析JSON)和bc(用于浮点数计算) - 根据实际业务调整
QUERY_RANGE(比如改为1m或10m) - 若指标存在标签过滤需求,可修改查询语句(如
MetricA{env="prod"})
二、Webhook阶段实现
通过自定义Webhook服务完成指标对比,CI阶段只需调用该服务,根据返回状态码判断成败。
1. 编写Webhook服务示例(Python Flask)
from flask import Flask, jsonify import requests app = Flask(__name__) # 配置Prometheus地址和查询参数 PROMETHEUS_CONFIG = { "url": "http://your-prometheus-instance:9090", "range": "5m" } @app.route('/verify-metrics', methods=['GET']) def verify_metrics(): try: # 查询两个指标的sum(rate)值 resp_a = requests.get( f"{PROMETHEUS_CONFIG['url']}/api/v1/query", params={"query": f"sum(rate(MetricA{{}}[{PROMETHEUS_CONFIG['range']}]))"} ) resp_b = requests.get( f"{PROMETHEUS_CONFIG['url']}/api/v1/query", params={"query": f"sum(rate(MetricB{{}}[{PROMETHEUS_CONFIG['range']}]))"} ) resp_a.raise_for_status() resp_b.raise_for_status() metric_a = float(resp_a.json()['data']['result'][0]['value'][1]) metric_b = float(resp_b.json()['data']['result'][0]['value'][1]) if metric_a > metric_b: return jsonify({"status": "failed", "message": f"MetricA ({metric_a}) exceeds MetricB ({metric_b})"}), 400 else: return jsonify({"status": "passed", "message": f"Metrics check passed"}), 200 except Exception as e: return jsonify({"status": "error", "message": str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
2. CI阶段配置Webhook
在CI的Webhook阶段中设置:
- 请求URL:
http://your-webhook-service:5000/verify-metrics - 请求方法:GET
- 失败触发条件:当Webhook返回非200状态码时,标记该阶段失败
注意事项
- 确保Webhook服务能被CI环境访问(可部署在同一集群或打通网络)
- 可添加API密钥等认证机制提升安全性
- 服务中需处理指标查询失败、无返回结果等异常场景
三、其他可行方案
1. 借助Prometheus Alertmanager
- 先在Alertmanager中配置告警规则:
groups: - name: metric_comparison rules: - alert: MetricAExceedsMetricB expr: sum(rate(MetricA{}[5m])) > sum(rate(MetricB{}[5m])) for: 1m labels: severity: critical annotations: summary: "MetricA exceeds MetricB" - 在CI脚本中使用
amtool查询告警状态:# 查询是否有触发中的目标告警 amtool alert query alertname="MetricAExceedsMetricB" | grep -q "firing" if [ $? -eq 0 ]; then echo "Failed: MetricA exceeds MetricB (alert is firing)" exit 1 fi
2. CI原生监控集成
部分CI平台(如GitLab CI)支持直接集成Prometheus,可在CI配置中直接定义指标查询和判断逻辑,无需额外脚本或服务。
内容的提问来源于stack exchange,提问作者Aman Patel
相关产品推荐
相关产品推荐

