大家好,我是来自阿里云的李煌东,今天由我为大家分享Kubernetes监控公开课的第二节内容:如何发现Kubernetes中服务和工作负载的异常。
本次分享由三个部分组成:
一、Kubernetes异常定位存在痛点;
二、针对这些痛点,Kubernetes监控如何更快、更准、更全的发现异常;
三、网络性能监控、中间件监控等典型案例解析。
Kubernetes异常定位存在痛点
当下的互联网架构中,越来越多的公司采用微服务+Kubernetes这样的架构,这样的架构有如下特点:
首先应用层基于微服务,微服务由解耦开的几个服务相互调用构成,服务一般职责分明、边界明确,造成的结果是一个简单的产品也有几十、甚至上百个微服务,相互之间的依赖、调用是非常复杂的,这给定位问题带来比较大的成本。同时,每个服务的owner可能来自不同团队,不同的开发,可能使用不同的语言,对我们监控的影响是对每一种语言都需要进行监控工具的接入,投资回报率低。还有一个特点是多协议,几乎每种中间件(Redis、MySQL、Kafka)都有他们独特的协议,怎么要做到快速对这些协议进行观测,是不小的挑战。虽然Kubernetes和容器对上层应用屏蔽了底层的复杂度,但是带来的两个结果是:基础设施层越来越高;另一个是上层应用和基础设施之间信息变得越来越复杂了。举个例子,用户反馈网站访问很慢,管理员查看访问日志、服务状态、资源水位发现都没问题,这时候不知道问题出现在哪里,虽然怀疑基础设施有问题,但无法定界的情况下只能一个一个排查效率低,问题的根源就是上层应用和基础设施之间缺少上下问题关联,无法做到端到端串联。最后一个痛点是数据散、工具多、信息没打通。举个例子,假设我们收到一个告警,用grafana去查看指标,指标只能描述的比较粗略,我们得去看下日志,这时候我们要去SLS日志服务看下有没有对应的日志,日志也没问题,这时候我们需要登录到机器上去看,然而登录到容器里面可能又因为重启导致日志没有了。查了一波之后,可能我们会觉得可能问题不是出现在这个应用,于是我们又去看链路追踪是不是下游有问题。总而言之,工具用了一大堆,浏览器开了十几个窗口,效率低、体验差。
这三个痛点分别归纳为成本、效率、体验三个方面。针对这些痛点,接下来我们一起看下Kubernetes监控的数据体系,看下怎么来更好的解决成本、效率、体验三大问题。
Kubernetes监控如何发现异常
下图金子塔自顶向下表示信息的密度或者详细程度,越往下面信息越详细。我们从底部开始讲,Trace是我们通过eBPF技术以无入侵、多协议、多语言的方式采集应用层协议数据,如HTTP、MySQL、Redis,协议数据会进一步解析成容易理解的请求详情、响应详情、各个阶段的耗时信息。
再上一层是指标,指标主要由黄金指标、网络、Kubernetes体系中的指标。其中黄金指标和网络指标是基于eBPF采集的,所以同样他们是没有入侵的,支持各种协议的,有了黄金指标,我们就能知道服务整体上是否有异常、是否有慢、是否影响用户;网络指标主要是对socket的支持,如丢包率、重传率、RTT等,主要用来监控网络是否正常的指标。Kubernetes体系中的指标是指原来Kubernetes监控体系中的cAdvisor/MetricServer/NodeExporter/NPD这些指标。再上一层是事件,事件直接明确地告诉我们发生了什么,可能我们遇到最多的是Pod重启、拉镜像失败等。我们对Kubernetes事件进行了持久化存储,并保存一段时间,这样方便定位问题。然后,我们的巡检和健康检查也是支持以事件的形式报出来。
最顶层是告警,告警是监控系统的最后一环,当我们发现某些特定异常可能对业务有损后,我们就需要对指标、事件进行告警配置。告警目前支持PromQL,智能告警支持对历史数据进行智能算法检测,从而发现潜在的异常事件。告警的配置支持动态阈值,通过调节灵敏度的方式来配置告警,从而避免写死阈值。有了Trace、指标、事件、告警之后,我们用拓扑图将这些数据和Kubernetes实体都关联起来,每个节点对应Kubernetes实体中的服务和工作负载,服务之间调用用线表示。有了拓扑图,我们就像拿到一张地图,能快速识别拓扑图中的异常,并对异常进行进一步的分析,对上下游、依赖、影响面进行分析,从而对系统有了更全面的掌控。
最佳实践场景分析
接下来我们讲下发现Kubernetes中服务和工作负载的异常的最佳实践。
首先还是先有指标,指标能反应服务的监控状态,我们应尽可能地收集各种指标,并且越全越好,不限于黄金指标、USE指标、Kubernetes原生指标等;然后,指标是宏观数据,需要做根因分析我们得有Trace数据,多语言、多协议的情况下要考虑采集这些Trace的成本,同样尽可能地支持多一点协议、多一点语言;最后,用一张拓扑将指标、Trace、事件汇总起来、串联起来,形成一张拓扑图,用来做架构感知分析、上下游分析。
通过这三种方法的分析,服务和工作负载的异常通常暴露无遗了,但我们不应该就此停止前进的脚步,加入这个异常下次再来,那么我们这些工作得重来一遍,最好的办法是针对这类异常配置对应的告警,自动化地管理起来。
我们用几个具体的场景来详细介绍:
(一)网络性能监控
网络性能监控以重传为例,重传的意思是说发送方认为发生了丢包现象,就重发这些数据包。以图中的传输过程为例:
发送方发送编号为1的包,接收方接受了,返回ACK2发送方发送编号为2的包,接收方返回ACK2发送方发送编号为3、4、5的包,接收方都返回ACK2直到发送方收到3次同样的ACK,就会触发重传机制,重传会导致延迟升高
代码和日志是观察不出来的,这种情形下最终很难找到根因。为了能快速定位这个问题,我们需要一组网络性能指标来提供定位依据,包含以下指标,P50、P95、P99指标来表示延时,然后我们需要流量、重传、RTT、丢包这些指标来表征网络情况。
以某个服务RT高为例:首先我们看到拓扑的边是红的,红的判断逻辑是根据延时、错误来判断的,当发现这个红边的时候,点击上面的边,就可以看对应的黄金指标了。
点击底部最左边这个按钮,可以查看当前服务的网络数据列表,我们可以按平均响应时间、重传、RTT排下序,可以看到第一个服务调用延时比较高,快到一秒的返回时间,同时也看到重传比较高,相比于其他服务高很多。这里其实是通过工具去注入了重传高这么一个故障,看起来更明显一些。这样分析下来我们就知道可能是网络的问题,就可以进一步排查了。有经验的开发一般会拿着网络指标、服务名、ip、域名这些信息去找网络的同事排查,而不是只是告诉对方说我服务很慢,这样对方知道的信息太少,就不会积极去排查,因为别人也不知道从哪里开始,当我们提供了相关数据,对方就有了参考,会顺藤摸瓜进一步推进。
(二)DNS解析异常
第二个场景是DNS解析异常。DNS通常是协议通信的第一步,比如HTTP请求,第一步就是先拿到IP,也就是我们平常说的服务发现过程,第一步出现问题,整个调用就直接失败了,这就是所谓关键路径不能掉链子。在Kubernetes集群中所有的DNS都走CoreDNS的解析,所以CoreDNS上容易出现瓶颈,一旦出现问题,影响面也是非常大的,可能整个集群都不可用了。举个两个月前发生的鲜活的例子,著名的CDN公司Akamai就发生了一个DNS故障,导致众多网站像Airbnb网站无法访问,事故持续了长达一个小时。
在Kubernetes集群中DNS解析比较核心的几个场景有三个:
调用外部API网关调用云服务,云服务一般是公网的调用外部中间件
这里对CoreDNS常见的问题进行了归纳,大家可以参考下,排查下自己的集群上有没有类似问题:
配置问题(ndots问题),ndots是个数字,表示域名中点的个数要是小于ndots,那么搜索就优先走search列表中的域去查找,这样的话会产生多次查询,对性能的影响还是挺大的。由于Kubernetes所有的域名解析都走CoreDNS,非常容易成为性能瓶颈,有人统计过大概qps在~的时候就要