最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

使用 Prometheus 和 Grafana 实现 SLO

  • 2019-02-14
  • 本文字数:4014 字

    阅读完需:约 13 分钟

使用Prometheus和Grafana实现SLO

在线服务的目标应该是提供与业务需求匹配的可用服务。此流程的关键部分应该涉及组织中的不同团队,例如,从业务开发团队到工程团队。


要验证一个服务如何符合这些目标,可以用这些目标可衡量的“成就”来定义“阈值”,例如,“服务必须在 99.9%的时间内可用”,这应该与用户的期望和业务连续性相匹配。

SLA, SLO, SLI

已经有很多关于这些话题的文章,如果你不熟悉这些术语,我强烈建议你先阅读谷歌关于 SLO(服务级别目标)的 SRE 书籍中的文章。


总而言之:


  • SLA:服务水平协议

  • 你承诺向用户提供的服务,如果你无法满足,可能会受到惩罚。

  • 例如:“99.5%”的可用性。

  • 关键词:合同

  • SLO:服务水平目标

  • 你在内部设置的目标,驱动你的测量阈值(例如,仪表板和警报)。通常,它应该比 SLA 更严格。

  • 示例:“99.9%”可用性(所谓的“三个 9”)。

  • 关键字:阈值

  • SLI:服务水平指标

  • 你实际测量的是什么,以确定你的 SLO 是否在满足目标/偏离目标。

  • 示例:错误率、延迟。

  • 关键词:指标。

SLO 关注时间

99%的可用性意味着什么?它不是 1%的错误率(失败的 http 响应的百分比),而是在一个预定义的时间段内可用服务的时间百分比。



在上面的仪表板中,服务在 1 小时内的错误率超过 0.1% (y 轴为 0.001)(错误峰值顶部的红色小水平段),从而在 7 天内提供 99.4%的可用性:



这一结果中的一个关键因素是你选择度量可用性的时间跨度(在上面的示例中为 7 天)。较短的周期通常用作工程团队(例如 SRE 和 SWE)的检查点,以跟踪服务的运行情况,而较长的周期通常用于组织/更广泛的团队的评审目的。


例如,如果你设置了 99.9%的 SLO,那么服务可以停机的总时间如下:


  • 30 天:43 分钟(3/4 小时)

  • 90 天:129 分钟(~2 小时)


另一个无关紧要的“数字事实”是,给 SLO 多加一个 9 都会产生明显的指数级影响。以下是 1 年的时间跨度的时间组成部分:


  • 2 个 9: 99%: 5250min (87hrs 或 3.64 天)

  • 3 个 9: 99.9%: 525min (8.7hrs)

  • 4 个 9: 99.99%: 52.5min

  • 5 个 9:99.999%:5min< -经验法则:5 个 9 -> 5 分钟 (每年)

输入错误预算

在服务可以停机的允许时间内,上面的数字可能被认为是错误预算,你可以从以下事件中消耗这些错误预算:


  • 计划维护

  • 升级失败

  • 意想不到的故障


实际的结果是,上面的任何一种情况都将消耗服务的错误预算,例如,意外的停机可能会耗这些预算,从而在此期间阻止进一步的维护工作。

SLI 与度量有关

从上面可以清楚地看出,必须有服务指标来告诉我们什么时候认为服务可用/不可用。有几种方法可以做到这一点:


  • RED:速率、错误、持续时间。

  • USE:利用率、饱和度和错误。

SLO 实现例子

让我们举一个具体的例子,遵循 RED 方法(因为我们现有的度量标准更适合这种方法):通过 Prmoetheus 和 Grafana 等监控工具创建警报和 dashboard,以支持 Kubernetes API 的目标 SLO。


此外,我们将使用 jsonnet 来构建规则和仪表盘文件,充分利用现有的库助手。



本文不是解释如何在服务超出阈值时发出信号,而是重点介绍如何记录服务处于这种情况的时间。


本文的其余部分将着重于创建 Prometheus 规则,以根据特定度量标准(SLI)的阈值捕获“超出 SLO 的时间”。

定义 SLO 目标和指标阈值

让我们定义一个简单的目标:


  • SLO:99%,来自以下数据:

  • SLI

  • 错误率低于 1%

  • 请求的 90%的延迟小于 200ms


以 jsonnet 的形式编写上述规范(参见[spec-kubeapi.jsonnet]):


slo:: {  target: 0.99,  error_ratio_threshold: 0.01,  latency_percentile: 90,  latency_threshold: 200,},
复制代码

找到 SLIs

Kubernetes API 公开了几个我们可以作为 SLIs 使用的指标,使用 Prometheus rate()函数在短时间内 (这里我们选择 5min,这个数字应该是抓取间隔的几倍):


  • apiserver_request_count:按verbcoderesource对所有请求进行计数,例如,获得最近 5 分钟的总错误率:


sum(rate(apiserver_request_count{code=~"5.."}[5m])) /sum(rate(apiserver_request_count[5m]))
复制代码


上面的公式放弃了所有的指标标签(例如,通过 httpverbcode)。如果你想保留一些标签,你需要做如下的事情:


sum by (verb, code) (rate(apiserver_request_count{code=~"5.."}[5m]))  / ignoring (verb, code) group_leftsum (rate(apiserver_request_count[5m]))
复制代码


  • apiserver_request_latencies_bucket:由动词表示的延迟直方图。例如,要获得以毫秒为单位的第 90 个延迟分位数: (注意,le“less or equal”标签是特殊的,因为它设置了直方图桶间隔,参见[Prometheus 直方图和摘要][promql-直方图]):


histogram_quantile (  0.90,  sum by (le, verb, instance)(    rate(apiserver_request_latencies_bucket[5m])  )) / 1e3
复制代码


在这里了解更多的:


编写 Prometheus 规则来记录所选的 SLI

PromQL是一种非常强大的语言,尽管截至 2018 年 10 月,它还不支持范围的嵌套子查询。我们需要能够计算error ratio或超出阈值的latencytime ratio


另外,作为一种良好的实践,为了减少查询 Prometheus 资源使用的时间,建议在诸如sum(rate(…))之类的预计算表达式中添加记录规则。


举一个例子来说明如何做到这一点,下面的一组记录规则是从我们的[bitnami-labs/kubernetes-grafana-dashboards]存储库中构建的,用于捕获上面的time ratio


创建一个新的kubernetes: job_verb- code_instance:apiserver_requests:rate5m指标来记录请求速率


record: kubernetes:job_verb_code_instance:apiserver_requests:rate5mexpr: |  sum by(job, verb, code, instance) (rate(apiserver_request_count[5m]))
复制代码


  • 使用上面的度量,为请求的比率(总的)创建一个新的kubernetes: job_verb-code_instance:apiserver_requests:ratio_rate5m


record: kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5mexpr: |  kubernetes:job_verb_code_instance:apiserver_requests:rate5m    / ignoring(verb, code) group_left()  sum by(job, instance) (    kubernetes:job_verb_code_instance:apiserver_requests:rate5m  )
复制代码


  • 使用上面的比率指标 (对于每个 http codeverb),创建一个新的指标来捕获错误率:


record: kubernetes:job:apiserver_request_errors:ratio_rate5mexpr: |  sum by(job) (    kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5m      {code=~"5..",verb=~"GET|POST|DELETE|PATCH"}  )
复制代码


  • 使用上面的错误率(以及其他类似创建的kubernetes::job:apiserver_latency:pctl90rate5m,用于记录过去 5 分钟内的第 90 个百分位延迟,为简单起见,未在上面显示),最后创建一个布尔指标来记录 SLO 遵从性情况:


record: kubernetes::job:slo_kube_api_okexpr: |  kubernetes:job:apiserver_request_errors:ratio_rate5m < bool 0.01    *  kubernetes::job:apiserver_latency:pctl90rate5m < bool 200
复制代码

编写 Prometheus 警报规则

上述kubernetes::job:slo_kube_api_ok最终指标对于仪表板和 SLO 遵从性的解释非常有用,但是我们应该警惕上面哪个指标导致 SLO 消失,如下面的 Prometheus 警报规则所示:


  • 高 API 错误率警告:


alert: KubeAPIErrorRatioHighexpr: |  sum by(instance) (    kubernetes:job_verb_code_instance:apiserver_requests:ratio_rate5m      {code=~"5..",verb=~"GET|POST|DELETE|PATCH"}  ) > 0.01for: 5m
复制代码


  • 高 API 延迟警报


alert: KubeAPILatencyHighexpr: |  max by(instance) (    kubernetes:job_verb_instance:apiserver_latency:pctl90rate5m      {verb=~"GET|POST|DELETE|PATCH"}  ) > 200for: 5m
复制代码


请注意,Prometheus 来自已经显示的 jsonnet 输出,阈值可以分别从$.slo.error_ratio_threshold$.slo.latency_threshold中评估得出。

以编程方式创建 Grafana 仪表板

创建 Grafana 仪表板通常是通过与 UI 交互来完成的。这对于简单的和/或“标准”仪表板(例如,从https://grafana.com/dashboards )下载)来说是很好的,但是如果你想要实现最好的 devops 实践,特别是对于gitops工作流,就变得很麻烦了。


社区正在通过各种努力来解决这个问题,例如针对jsonnetpythonJavascript的 Grafana 库。考虑到我们的jsonnet实现,我们选择了grafonnet-lib


使用jsonnet来设置 SLO 阈值和编码 Prometheus 规则的一个非常有用的结果是,我们可以再次使用它们来构建 Grafana 仪表板,而不必复制和粘贴它们,也就是说,我们为这些保留了一个真实的来源。


例如:


  • 关于$.slo.error_ratio_threshold,在我们的 Grafana 仪表板中设置 error_ratio_threshold 来设置 Grafana 图形面板的阈值属性,就像我们在前面为 Prometheus 警报规则所做的那样。

  • 记录metric.rules.requests_ratiorate_job_verb_code.record使用情况(而不是’kubernetes: job_verb_code_instance:apiserver_requests:ratio_rate5m'):


// Graph showing all requests ratiosreq_ratio: $.grafana.common {  title: 'API requests ratios',  formula: metric.rules.requests_ratiorate_job_verb_code.record,  legend: '{{ verb }} - {{ code }}',},
复制代码


你可以在dash-kubeapi.jsonnet上了解我们的实现情况,下面是生成的仪表板的屏幕截图:


总结

我们在jsonnet文件夹下的 bitnami-labs/ kubernets-grafana -dashboards 存储库中实现了上述想法。


我们构建的 Prometheus 规则和 Grafana 仪表盘文件来自 jsonnet,如下所示:



  • [spec-kubeapi.[jsonnet]:尽可能多的数据规范(阈值、规则和仪表板公式)

  • rules-kubeapi.jsonnet:输出 Prometheus 记录规则和警报

  • dash-kubeapi.jsonnet:输出 Grafana 仪表盘,通过我们选择的 bitnami_grafana.libsonnet 使用 grafonnet-lib


自从我们开始这个项目以来,社区已经创建了许多其他有用的 Prometheus 规则。点击 srecon17_americas_slides_wilkinson查看有关这方面的更多信息。如果我们必须从头开始,我们可能会使用kubernetes-mixinjsonnet-bundler


2019-02-14 09:5511171
用户头像

发布了 124 篇内容, 共 43.2 次阅读, 收获喜欢 176 次。

关注

评论 1 条评论

发布
用户头像
干货干货
2019-03-04 18:12
回复
没有更多了
发现更多内容

Neo 生态技术月报 | 助力开发者玩转智能合约

TinTinLand

区块链

【LeetCode】爬楼梯的最少成本Java题解

Albert

算法 LeetCode 5月月更

首届 FinClip Hackathon 圆满落幕,亚马逊云科技|云服务平台助力获奖团队高速成长

FinClip

亚马逊 finclip FinClip Hackthon

AIRIOT物联网低代码平台如何配置欧姆龙omron驱动?

AIRIOT

低代码 物联网 驱动配置

AI简报:图像超分模型 EDSR+RDN

AIWeker

人工智能 5月月更 超分 AI简报

移动端异构运算技术-GPU OpenCL 编程(基础篇)

百度Geek说

后端

时间堆原理详解及C++11的实现

C++后台开发

后端开发 Linux服务器开发 C++11 C++后台开发 时间堆

直播回顾 | 后疫情时代,食品行业破局秘籍get一下!

旺链科技

区块链 溯源 产业区块链

Wallys/ AR9531/WiFi Card/ MMCX

wallys-wifi6

AR9531 30dBm high power

茶饮市场当前情况如何?走入下半场的现制茶战局,又将去向何方?

易观分析

茶饮

Squids DBMotion数据库迁移服务上线|助力云端数据畅游无阻!

沃趣科技

云数赋能+数字办公 助力政企数字化

浪潮云

“晕乎乎的概念”:阿里云函数计算的“应用”又是个啥

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

墨天轮访谈 | 京东云曲艺伟:京东零售核心业务背后的数据库实践

墨天轮

数据库 京东云 国产数据库

堡垒机属于什么设备?是网络设备吗?

行云管家

网络安全 服务器 堡垒机 网络设备

性能提升 57% ,SMC-R 透明加速 TCP 实战解析 | 龙蜥技术

OpenAnolis小助手

互联网 网络协议 高性能 TCP/IP 龙蜥技术

当我们谈论服务质量的时候,我们在谈什么?

VoltDB

5G QoS 电信运营商

当开放服务网格 OSM 遇到 Pipy

Flomesh

Service Mesh 服务网格 SMI OSM

设计模式关系图(全网首发)之行为模式

设计模式

云计算和运维工程师冲突吗?运维岗需要云计算知识吗?

行云管家

云计算 运维 IT运维 云运维

改善CRM系统策略的方法

低代码小观

CRM 客户关系管理 企业管理系统 CRM系统 客户关系管理系统

用更云原生的方式做诊断|大规模 K8s 集群诊断利器深度解析

尔达Erda

程序员 运维 云原生 k8s 工具

超潜力公链DFINITY——DeFi 开发者最佳进入时期

TinTinLand

区块链

Hoo网格策略 | 一「网」在手 告别「追涨杀跌」

区块链前沿News

虎符 Hoo 网格交易

前端路由工作原理与使用

CRMEB

【FinClip 黑客马拉松优秀参赛项目@灰鲸疫情地图】疫情之下,安全出行的一站式解决方案

FinClip

finclip FinClip Hackthon 疫情地图

《方博碳讨室》:四问欧洲绿色能源转型

Geek_2d6073

DeFi挖矿智能合约Dapp系统开发搭建

薇電13242772558

智能合约

【直播回顾】如何成为一名优秀的OpenHamrony贡献者?

OpenHarmony开发者

OpenHarmony 贡献代码

深入微服务-服务注册与发现 SpringCloud Eureka之基础

janyxe

微服务 云原生 SpringCloud Eureka 服务注册与发现

fastposter v2.8.1 发布 电商海报生成器

物有本末

Python Pillow fastposter fast-poster

使用Prometheus和Grafana实现SLO_软件工程_JUANJO CIARLANTE_InfoQ精选文章