基于 Kubernetes 的云原生 DevOps 第 16 章 Kubernetes 指标
🏷️ Kubernetes 《基于 Kubernetes 的云原生 DevOps》
16.1 什么是指标?
指标是某种事物的数字度量标准。传统服务器领域中最常见的指标是某台计算机的内存使用情况。指标可以告诉我们一种非常有价值的信息,那就是特定时刻的快照。但是指标能做的远不止于此。内存使用率会随着工作负载的启动和停止而不停的上升和下降,但有时我们感兴趣的是内存使用率随时间的变化。
时间序列数据
定期采样内存的使用状况,就可以创建该数据的时间序列。
我们感兴趣的面向云原生可观察性的大多数指标都通过时间序列表示。它们都是数字类型的值。
计数器和计量器
指标往往都用浮点小数表示。指标主要有两种类型:计数器和计量器。计数器只能增加(或重置为零),适用于测试服务请求数量和收到的错误数量等。计量器可以增加或减少,适用于连续变化的数量(例如内存使用率)或表示其它数量的比率。
指标可以告诉我们什么?
指标可以告诉你何时出现了问题。你可以在指标到达阈值时自动生成警报。此外,指标还可以告诉你当前的状况。这些数字的长期趋势对于运维决策和商业智能都非常重要。
16.2 选择指标
你不可能监控所有的指标。即使你可以一次性显示所有指标的图标,也永远无法消化所有消息,更不用说从中推断出任何有用的信息。因此,我们需要找出我们关心的一套指标。
服务:RED 模式
大多数使用 Kubernetes 的人都会运行某种 Web 服务:用户发出请求,然后由应用程序发出响应。
那么,请求驱动系统中有什么值得了解的信息?
- 收到的请求数量。
- 各种方式下失败的请求数量,即错误的数量。
- 每个请求的持续时间。你可以借此了解服务的性能如何,以及用户的不满程度。
RED 模式( Requests Errors Duration ,请求 - 错误 - 持续时间)是一种经典的可观察性工具,最早可追溯到在线服务的早期时代。
工程师 Tom Wilkie 提出了 RED 这一缩写,并在博客文章中概述了这种模式背后的基本原理:
为什么每个服务都应该测量相同的指标?当然每个服务都不一样,但从监控的角度来看,统一处理每个服务可以提高运维团队的可伸缩性。每个服务的外观、感觉和体验都相同,则可以减轻负责响应事件的人员的认知负担。此外,如果所有服务都统一处理,那么许多重复性的任务都可以自动化。
-- Tom Wilkie
常见的服务仪表板可以显示:
- 每秒收到的请求数。
- 返回错误占请求的百分比。
- 请求的持续时间(也称为延迟)。
资源:USE 模式
USE 代表利用率( Utilization )、饱和度( Saturation )与错误( Errros ),是由 Netflix 性能工程师 Brendan Gregg 提出的一种自下而上的可观察性数据方法(RED 是自上而下的方法)。
USE 关注的是资源而不是服务,即物理服务器组件或网络接口和连接。其中任何一个都可能称为系统的瓶颈,而 USE 指标可以帮助我们找出:
- 利用率
资源忙于处理请求的平均时间,或当前正在使用的资源容量。 - 饱和度
资源的过载程度,或等待该资源的请求队列长度。 - 错误
操作该资源失败的次数。
测量系统中关键资源的数据是发现瓶颈的好方法。利用率低,不饱和且没有错误的资源都没有问题;反之则需要小心。
业务指标
大多数企业都在跟踪相关的关键绩效指标(KPI)。这些指标通常来自财务部门,不需要开发人员和基础设施人员的支持。
然而,还有一些业务指标可以由应用程序和服务生成。
- 渠道分析:多少人访问了登录页面,多少人点击进入了注册页面,多少人完成了交易等。
- 注册率和取消率(流失率)。
- 每位客户的收入(用于计算每月的经常性收入以及客户的终身价值)。
- 帮助和支持页面的有效性,例如多少人在“该页面是否解决了您的问题?”的问题中给出了“是”的答案。
- 系统状态公告页面的流量:通常在系统发生中断或服务降级时该页面的访问量会激增。
业务及客户参与度专家所需的可观察性信息,与技术专家所需的可观察性信息之间不一定由明确的界线。实际上,二者之间有很多交集。我们应该尽早与所有利益相关者讨论指标,并就需要收集哪些数据、多久收集一次、如何汇总等问题达成一致。
你可以使用公共数据湖为每组人创建不同的仪表板和报告。
Kubernetes 指标
在最底层,一款名为 cAdvisor 的工具可以监控每个集群节点上运行的容器使用资源的情况和性能统计信息。 cAdvisor 是 Kubelet 的一部分。
Kubernetes 会通过查询 Kubelet 来消费 cAdvisor 的数据,并使用这些信息来决定调度、自动伸缩等。但是,你也可以将这些数据导出到第三方指标服务,然后显示成图表并发出警报。
此外,还可以使用一款名叫 kube-state-metrics 的工具来监视 Kubernetes 本身。该工具会监听 Kubernetes API 并报告有关逻辑对象(例如节点、Pod 和部署)的信息。这些数据对可观察性非常重要。
集群监控指标
- 节点数。
- 节点的健康状态。
- 每个节点以及整体的 Pod 数。
- 每个节点以及整体的资源使用和分配情况。
这些概览指标可以帮助你了解集群的性能、集群是否拥有足够的容量、集群容量的使用随时间变化的情况,以及是否需要扩展或缩减集群。
部署指标
- 部署的数量。
- 每个部署中已配置副本的数量。
- 每个部署中不可用副本的数量。
容器指标
- 每个节点的容器数 / Pod 数,以及总数。
- 每个容器的资源使用和请求 / 约束之比。
- 容器的存活 / 就绪状态。
- 容器 / Pod 重启的次数。
- 每个容器的网络输入 / 输出流量以及错误。
由于 Kubernetes 会自动重启失败或超出资源约束的容器,因此你需要知道这种情况发生的频率。重启次数过多,则可能表明特定容器存在问题。如果容器经常超出资源约束,则表明程序有错误,或者你需要略微增加约束。
应用程序指标
具体应该捕捉以及导出哪些应用程序的指标取决于应用程序的实际功能。
在开发的初期阶段,可能很难知道哪些指标会有用。如果不确定,则可以记录所有指标。记录指标的代价很低。记录一些看似并不重要的指标,通过长期的观察也有可能会发现意料之外的生产问题。
如果指标会变化,则请显示成图表。即使指标没有变化,也应该显示成图表,因为说不定有一天它就会变化。
-- Laurie Deness (Bloomberg)
另一种对业务有帮助的指标是,查看应用程序在服务水平目标(SLO)或服务水平协议(SLA)上的表现,或者提供商的服务在 SLO 上的表现。
运行时指标
- 进程 / 线程 / 例程数量。
- 堆和栈的使用情况。
- 非堆内存使用状况。
- 网络及 I/O 的缓冲池。
- 垃圾回收器的运行和暂停时间(针对使用垃圾回收的语言)。
- 正在使用的文件描述符 / 网络套接字。
在诊断性能不加,甚至即将崩溃的问题时,这种信息非常有用。
16.3 分析指标
数据和信息不是一码事。为了从捕捉的原始数据中获取有用的信息,我们需要对其进行汇总、处理和分析,也就是说我们需要进行统计分析。统计信息是一项繁琐的业务,尤其从抽象的角度分析。
简单的平均值有什么问题?
平均值的含义并不一定很直观。此外,平均值( average )也不止一种。平均值常见的含义是平均数( mean )。一组值的平均数是所有值的总和除以值的数量。另一方面,中位数指的是将集合分成两等分的值,一半包含的值比中位数大,而另一半包含的值则比中位数小。
平均值、中位数和离群值
平均值很容器被离群值带偏,即一个或两个极端的值可能会大大扭曲平均值。因此,受异常值影响较小的中位数是一种比平均值更有效的平均指标。
百分位数
在讨论观察请求驱动系统所需的指标时,我们通常感兴趣的是用户感受的最糟糕的延迟,而不是平均延迟。获得此类信息的方法是将数据分解成百分位。第 90 百分位延迟(通常称为 P90)指的是这个值超过了 90% 的用户感受到的延迟值。根据这种表示方法,中位数是 P50。除此之外,可观察性通常需要测量的百分位还有 P95 和 P99。
将百分位数应用于指标数据
Travis CI 的 Igor Wiedler 根据生产服务 10 分钟内接收到的 135000 个请求数据集,汇总了一篇优秀的说明文章。
一般我们想知道最坏的情况
在上面的例子中,P99 数据可以让我们更真实地了解用户所经历的延迟。
16.4 通过仪表板显示指标的图表
所有服务都使用标准布局
当拥有的服务数量较少时,每个服务都可以按照相同的布局在仪表板上进行展示。
Tom Werkie 在 Weaveworks 博客文章中提出了以下标准格式:
- 一行一个服务。
- 左侧是请求和错误率,错误显示为占请求的百分比。
- 右侧是延迟。
你不一定使用相同的布局,重点是每个仪表板都有相同的布局,而且每个人都很熟悉。你应该定期(至少每周一次)查看关键的仪表板,查看前一周的数据,让所有人都知道正常情况是什么样子。
请求、错误和持续时间仪表板也适用于服务。对于集群节点、磁盘和网络等资源,最实用的信息通常是利用率、饱和度和错误。
利用主仪表板构建信息发射源
如果你的服务很多,则需要更全面的概述。为此,你需要创建一个主仪表板,聚合显示所有服务的请求、错误和持续时间。不要使用面积堆叠图等华而不实的图表,请坚持使用简单的折线图来显示总请求、总粗无百分比以及总延迟。与复杂的图表相比,这类图更易于理解,而且可视化的效果也更好。
理想情况下,你可以使用信息发射源(也叫大屏幕或超大可见图)。通过一个大屏幕显示关键的可观察性数据,让相关团队或办公室中的每个人都可以看到。信息发射源的目的是:
- 一目了然地显示系统地当前状态。
- 发送清晰地信息,说明团队认为哪些指标很重要。
- 让人们熟悉正常情况。
只显示至关重要地信息。至关重要的意思不仅是非常重要,而且关系到系统地生命体征,即这些信息可以告诉你系统的生命信息。如果有数字,则不应该超过四个或者五个数字。如果有图,则最多只能包含四个或五个图。
我们常常会忍不住在仪表板中塞满大量信息,东芝仪表板过于复杂而且技术性很强。但这不是我们的目标。我们的目标是专注于一些关键指标,让房间里的每个人都可以一眼看到。
在仪表板上显示预示故障的数据
还有一个有用的信息来源是故障的发生。每次发生事件或服务中断时,你应该看看某个指标或多个指标的组合,可能这些指标之前就已经提醒过你这个问题了。
我们关心的缓慢逼近的危险,这些危险可能需要几天或几周的时间才会显现。
在事件发生后,你应该思考:“实现了解哪些情况,才能在危险来临之际提前发出警告?”如果答案是你已拥有但没有注意到的数据,那么请采取行动着重显示这些数据。
16.5 根据指标发成警报
警报有什么问题?
警报表明系统意外偏离了稳定的工作状态。然而,分布式系统并没有所谓的“稳定的工作状态”!
大规模分布式系统永远不会“正常运行”,它们总是处于部分降级的状态。这类系统的指标太多了,但凡某个指标超出正常范围就发出警报,那么每天会发出数百页的警告,这毫无意义。
警告疲劳是医学界众所周知的问题。
为了有效利用监控系统,我们必须保证很高的信噪比。虚假的警报不仅招人厌,而且很危险,因为它们降低了人们对系统的信任,并导致人们心安理得地忽略警报。
警报应该意味着一件非常简单的事情:必须有人立即采取行动。
- 如果不采取任何行动,那么就不需要发送警报。
- 如果需要在某个时间(但不是现在)采取行动,则可以将警报降级为电子邮件或聊天消息。
- 如果这个动作可以由系统自动执行,则请自动化,不要吵醒有价值的人类。
值班不应该称为地狱
虽然因为自己的服务而值班时开发运维理念的一项关键活动,但同等重要的是,值班应该是尽可能轻松的体验。
警报呼叫应该非常罕见,而且极其偶然。一旦发生警报,就应该由一套完善有效的程序来处理,将响应者的压力降到最低。
不应该有人一直值班。如果遇到这种情况,则应该实行多人轮岗。值班的人不需要称为某个主题的专家,他的主要任务是对问题进行分类,确定是否需要采取行动,然后分配给合适的人员。
你应该意识到,让某个人值班实际上是在消耗人力资本,所以请精打细算。
紧急、重大且需要付诸行动的警报
可观察性虽好,但你不注意观察就发现不了问题。仪表板虽好,但你不能花钱雇人整天坐在仪表板前。为了检测当前正在发生的中断或问题,并引起人们的注意,根据阈值自动发送警报才是不二之选。
不要针对每个指标都发送警报。你应该从成百上千个指标中挑选少数几个来生成警报。
呼叫应该仅限于紧急、重大且需要付诸行动的警报:
- 重要但不紧急的警报可以在正常工作时间内处理。只有不能等到第二天早上的问题才需要呼叫人员。
- 紧急但不重要的警报不能作为吵醒某人的理由。例如,很少使用的内部服务故障不会影响客户。
- 如果不需要立即采取行动来修复,那么呼叫就没有意义。
跟踪警报、工作时间外的呼叫
对于基础设施来说,员工与云服务和 Kubernetes 集群同等重要,甚至员工更重要。员工更昂贵,而且很难替换。因此,你应该像监控服务状态一样,关心员工的情况。
一周内发送的警报数量可以很好地说明系统的整体运行状况和稳定性。
你应该为紧急呼叫次数设置预算,尤其是在工作时间外,而且这个预算应该非常低。每位值班的工程师每周收到的工作时间外呼叫不应该超过 1 ~ 2 小时。
每周至少审查一次所有的紧急呼叫,并修复或消除任何虚假警报或不需要的警报。
16.6 指标工具和服务
Prometheus
在云原生世界里,事实上的标准指标解决方案是 Prometheus。
Prometheus 是一个基于时间序列指标数据的开源系统监控和警报工具包。Prometheus 的核心是一台收集和存储指标的服务器。它还有其它各种可选组件,例如警报工具,以及编程语言的客户端库,这些都可用于检测应用程序。
你可以使用标准的 Helm Chart,只需一个命令即可将 Prometheus 安装到 Kubernetes 集群。然后,通过抓取自动从集群和所有指定的应用程序中收集指标。
尽管 Prometheus 本身的重点是收集和存储指标,但它还提供了其它面向图表、仪表板和警报的高质量开源工具。 Grafana 是一款功能强大的图形引擎,可用于处理时间序列数据。
Prometheus 项目包含一个名为 Alertmanager 的工具。Alertmananger 的工作是从各种数据源中接收警报并进行处理。
处理警报的第一步是删除重复数据。然后由 Alertmanager 将检测到的相关警报分组。
最后,Alertmanager 将处理后的警报路由到适合的通知服务。
很方便的一点是,Prometheus 指标的格式得到了许多工具和服务的支持,而且这个事实上的标准如今成了 OpenMetrics 的基础。
其它托管指标服务包括如下这些,国内基本上没机会用,详细的介绍就不记了。
- Google Stackdriver
- AWS Cloudwatch
- Azure Monitor
- Dataedog
- New Relic
16.7 小结
- 关注每个服务的关键指标:请求、错误和持续时间(RED)。关注每种资源的关键指标:利用率、饱和率和错误率(USE)。
- 通过检测应用程序公开自定义指标,以实现内部的可观察性及业务 KPI。
- Kubernetes 集群级别的指标包括节点数、每个节点的 Pod 以及节点的资源使用情况。
- 在部署级别,你需要跟踪部署和副本,尤其是不可用的副本,因为它们可能表明容量有问题。
- 在容器级别,你需要跟踪每个容器的资源使用情况、存活/就绪状态、重新启动、网络流量以及网络错误。
- 使用标准布局为每种服务构建仪表板,并通过主信息发射源报告整个系统的生命体征。
- 如果要根据指标发送警报,则应该发送紧急、重大且需要付诸行动的警报。警报噪音会造成疲劳且有损士气。
- 跟踪并查看团队收到的紧急呼叫次数,尤其是半夜和周末被呼叫。
- 在云原生世界,事实上的标准指标解决方案是 Prometheus,几乎所有工具都使用 Prometheus 数据格式。
- 第三方的托管指标服务包括 Google Stackdriver、亚马逊的 Cloudwatch,Datadog 以及 New Relic。