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秒内判断系统状态。推荐采用三层结构:

  1. 黄金信号层:全局状态概览

    • 当前错误预算剩余百分比
    • 燃烧率趋势图
    • 核心SLI实时值
  2. 钻取分析层

    -- 错误请求的维度下钻示例
    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
    
  3. 历史对标层

    • 本周 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状态码,最终改为"业务成功码在响应体中的比例"才真正反映用户体验。

更多推荐