别再混淆了!用Kubernetes和Prometheus实战定义你的服务SLI与SLO(保姆级教程)
·
Kubernetes与Prometheus实战:定义服务SLI/SLO的工程化指南
当你的微服务在Kubernetes集群中运行时,如何知道它们是否健康?错误率上升时,是该立刻叫醒工程师还是可以等到明天早会?本文将带你用Prometheus和Grafana构建一套数据驱动的稳定性保障体系。
1. 从概念到指标:定义可测量的SLI
在Kubernetes环境中定义SLI(服务等级指标)时,需要先回答三个关键问题:测量什么、如何采集、怎样计算。以电商系统的订单服务为例:
# 示例:订单服务的SLI定义清单
sli_definitions:
- name: api_success_rate
description: "HTTP 200响应占总请求的比例"
source: "Nginx ingress控制器metrics"
query: "sum(rate(nginx_ingress_controller_requests{status=~'2..'}[1m])) by (service) / sum(rate(nginx_ingress_controller_requests[1m])) by (service)"
- name: checkout_latency_p99
description: "结账接口99分位响应时间"
source: "应用自定义metrics"
query: "histogram_quantile(0.99, sum(rate(checkout_duration_seconds_bucket[5m])) by (le, service))"
关键决策点:
| 维度 | 选项 | 适用场景 |
|---|---|---|
| 时间窗口 | 滚动窗口(5m/1h) vs 固定窗口(日/周) | 实时告警用滚动窗口,报表用固定窗口 |
| 聚合方式 | 平均值 vs 百分位数 | 用户体验相关用P99,资源规划用平均值 |
| 采样粒度 | 服务级别 vs API端点级别 | 初期监控服务级,问题定位需要端点级 |
提示:避免选择过多SLI指标,初期聚焦3-5个核心指标。指标过多会导致告警疲劳且难以维护。
2. Prometheus中的SLO实现方案
将SLO(服务等级目标)转化为Prometheus告警规则时,需要处理两个技术难点:错误预算计算和告警灵敏度平衡。以下是订单服务可用率SLO的完整实现:
# 错误预算计算规则
record: slo:errors:rate5m
expr: sum(rate(nginx_ingress_controller_requests{status!~'2..'}[5m])) by (service)
/ sum(rate(nginx_ingress_controller_requests[5m])) by (service)
# 30天滚动窗口的SLO达标率
record: slo:30d:ratio
expr: 1 - (
sum_over_time(slo:errors:rate5m[30d])
/ sum_over_time(sum(rate(nginx_ingress_controller_requests[5m])) by (service)[30d])
)
# 基于燃烧率的告警规则
- alert: HighErrorBudgetBurn
expr: slo:errors:rate5m > (0.01/24) # 每月1%错误预算在24小时内耗尽
for: 15m
labels:
severity: page
annotations:
summary: "{{ $labels.service }} is burning error budget too fast"
燃烧率(Burn Rate)策略对照表:
| 严重等级 | 错误预算消耗速度 | 响应时间 | 通知渠道 |
|---|---|---|---|
| Warning | 2x (5%预算/12小时) | 工作时间 | 企业IM |
| Critical | 10x (50%预算/1小时) | 全天候 | 电话呼叫 |
3. Grafana看板设计实战
有效的SLO看板应该让工程师在5秒内判断系统状态。推荐采用三层结构:
-
黄金信号层:全局状态概览
- 当前错误预算剩余百分比
- 燃烧率趋势图
- 核心SLI实时值
-
钻取分析层:
-- 错误请求的维度下钻示例 SELECT status_code, upstream, COUNT(*) as errors FROM nginx_logs WHERE status NOT LIKE '2%' AND time > NOW() - INTERVAL '1 hour' GROUP BY 1, 2 ORDER BY 3 DESC LIMIT 10 -
历史对标层:
- 本周 vs 上周同期对比
- 月度SLO达标进度条
- 重大事件标记(发布/流量高峰)
![看板布局示意图] (左侧:全局状态卡 | 中部:燃烧率趋势图 | 右侧:Top错误分解)
4. 生产环境进阶技巧
多集群场景处理方案:
# 使用Prometheus联邦合并关键指标
scrape_configs:
- job_name: 'federate'
scrape_interval: 1m
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{__name__=~"slo:.+"}'
static_configs:
- targets:
- 'prometheus-us-central1.prod.svc.cluster.local:9090'
- 'prometheus-eu-west1.prod.svc.cluster.local:9090'
避免的常见陷阱:
- 指标基数爆炸:为高维度标签添加聚合规则
# 错误示例:会导致高基数 sum by (status, path, user_id) (rate(requests_total[5m])) # 正确做法:先聚合再计算率 sum(rate(requests_total[5m])) by (status) - 告警风暴:设置合理的告警静默期
- 数据漂移:处理Prometheus重启时的计数器重置
性能优化配置:
# prometheus.yml优化片段
storage:
tsdb:
retention: 30d
wal_compression: true
query_log:
file: /var/log/prometheus/query.log
remote_write:
- url: "http://thanos-receive:10908/api/v1/receive"
queue_config:
capacity: 5000
max_samples_per_send: 2000
在实施过程中,我们发现最耗时的环节往往不是技术实现,而是与各团队对齐哪些指标真正代表业务健康度。曾有一个支付服务将"HTTP 200响应率"设为SLI,后来发现某些错误会返回200状态码,最终改为"业务成功码在响应体中的比例"才真正反映用户体验。
更多推荐
所有评论(0)