开发者学堂课程【如何发现 Kubernetes 中服务和工作负载的异常:如何发现 Kubernetes 中服务和工作负载的异常】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/948/detail/14760
如何发现 Kubernetes 中服务和工作负载的异常
内容介绍:
一、 Kubernetes 异常定位存在痛点
二、 Kubernetes 监控如何发现异常
三、 典型场景分析&DEMO
一、Kubernetes 异常定位存在痛点
在当下的互联网架构中,越来越多的公司采用微服务加 Kubernetes 这样的架构,这样的架构有如下特点:
首先,应用成绩与微服务,微服务由几个服务相互调用构成,服务一般职责分明,连接明确,造成的结果是一个简单的产品也有几十甚至上百个微服务,相互之间的依赖、调用是非常复杂的。这个调用问题带来比较大的成本;
同时,每个服务可能来自不同的团队,不同的开发,使用不同的语言,对我们监控的影响是每一种语言都需要监控工具的介入,投资回报率低;还有一个特点是多协议,每个装令箭都有不同的协议,不同的协议具有不同的格式,不同的格式具有不同的解析方法,怎么做到快速的对这些协议进行数据的采集、指标的收集是不小的挑战,虽然Kubernetes 和容器对上层应用屏蔽了底层的复杂度,但是带来两个结果:基础设施一层变得越来越复杂,上层应用和基础设施之间信息变得越来越割裂。举个例子,用户反馈网络反应很慢,管理员在查看了访问日志、服务状态以及资源水位之后都没有发现问题,这时不知道问题出现在哪里,即使怀疑基础设施有问题,但也没有办法定论,只能一个个排查,效率比较低,问题的根源就是上层应用和基础设施之间缺少上下文的关联,没有办法做到端到端的串联。
最后一个特点是数据比较散,工具比较多,奔于疲命,影响效率,举个例子,假如收到一个告警,要用一个浏览器看指标,用一个浏览器看日志,还要登录到机器上看,然而登录到机器上机器可能就重启了,可能问题不是出现在这个上面,又得看另外一个,总而言之,工具用了一大堆,浏览器开了十几个,效率比较低,体验比较差。
这三个痛点分别归纳成成本、效率、体验。针对这些痛点,我们一起看一下 Kubernetes 监控体的数据体系,怎样更好的解决成本、效率、体验三大问题。
二、Kubernetes 监控如何发现异常
金字塔自顶向下表示信息的密度或者详细程度,越靠下,信息越详细。
Trace 以多协议、无入侵、多语言的方式采集的应用层协议数据,协议数据会进一步解析成容易理解的请求详情、响应详情和各阶段延时分析。
指标通常由黄金指标、网络指标、K8S 体系中的指标组成。黄金信号指标和网络指标无入侵,支持各种协议;网络指标主要用来监控网络指标是否正常;K8S、容器、进程。
事件明确告诉我们发生什么,遇到比较多的是机器重启等。对 K8S 事件进行持久化的存储,方便未来定位问题。巡检事件、健康检查支持以事件的形式上报。
告警是监控系统的最后一环。当我们发现某些特定异常可能对业务有损之后,就应该对指标和事件进行告警的配置。告警目前支持基于 PromQL、支持智能告警,对历史数据进行智能算法检测,从而发现潜在的异常事件、支持动态阈值,通过调节灵敏度的方式来配置告警。
有了 Trace、指标、事件、告警之后,我们用拓扑图将这些信息和K8S事件关联起来,每个节点对应 K8S 中的服务和工作负载,服务之间的调用用线来表示。有了拓扑图,我们就像拿了一张地图,就能快速识别拓扑图中的异常,并对其中的异常进行进一步分析,对上下有依赖,影响进行分析,从而对系统有更全面的掌握。
最佳实践
首先需要有反映服务健康状态的指标,第二需要有各种各样的协议数据做进一步分析;第三,需要一张拓扑图,将指标、Trace、事件汇总起来,串联起来,形成一张图,用来做架构感知,上下文分析等等,通过这三种方法的分析,服务和工作负载的异常通常就暴露无疑了。但我们不应该就此停止,应该对这些经验进行总结,并且配置成告警,从而自动化的管理起来。
三、典型场景分析&DEMO
网络性能监控,以重传为例
重传,是指发送方认为发生了丢包的现象,就应该重发这些数据包,重传带来的结果是 RT 上升,这种情况下,代码和日志是观察不出来的。所以比较难找到根源问题。为了能快速定位这个问题,需要一组更深一层的网络性能指标来提供定位的依据,包含以下指标:P50/P95/P99指标来表示延迟,流量,重传,RTT,丢包率这些指标来表征网络情况。
首先,我们看到拓扑的边是红的,调用是没问题的,红的判断逻辑是根据延时错误来判断的,当发现红色的边时,点击线,进而看到右边侧边栏对应的黄金指标,比如请求数、错误数、平均响应时间、RTT 等等。点击左下角最左边的按钮,可以查看当前服务的网络数据列表,可以根据平均响应时间、重传、RTT,可以发现第一个服务调用延时比较高,快到1秒的反馈时间,同时重传比较高,相比于其他服务高出很多,其实是通过工具注入重传高的过程,看起来更明显些。这样看下来,我们就知道可能是网络的问题,进一步找网络的同时去排查,可以把这些数据哪一个服务,来源是谁,目标是谁,请求数多少,平均响应时间多少,重传多少,流量多少,都提供出来,这样也方便其他同学去排查。
第二个例子是 DNS 解析异常的例子,DNS 解析通常是协议通讯的第一步,比如 http 请求,第一步就是先拿到 IP,也就是我们通常所说的服务发现的过程,如果第一步出现问题,整个调用失败,在关键路径上不能掉链子,在Kubernetes 集群中,所有的 DNS 解析走的都是 CoreDNS,所以 CoreDNS 比较容易出现瓶颈,一旦出现问题,影响面也是非常大的。可能整个集群都不可用了。
举一个鲜活的例子,一著名的公司发生了 DNS 故障,导致众多网站无法访问,事故持续了一个多小时,在Kubernetes 集群中,DNS 解析有比较核心的几个场景,调用外部 API 网关、阿里云的云服务、外部中间件。
K8SECoreDNS 常见问题:配置问题( ndots 问题), ndots 是一个数字,表示域名中点的个数小于 ndots,搜索就优先,域名搜索就优先走 search 列表的优先查找,这样会产生多次查询,对性能的影响还是很大的;由于 K8S 所有的域名都走 CoreDNS,所以容易成为性能瓶颈,并发达到5000~8000QPS 时,就应关注性能问题了,尤其是依赖外部的访问量比较大的;CoreDNS 组件版本过低;语言不支持连接池特性,导致每次都需要解析 DNS,创立连接,这个现象也是值得关注的。大家可以作为参考,排查自己集群上有没有类似的问题。
K8S、CoreDNS 中容易出现问题的地方:首先,应用跟 CoreDNS 之间的网络可能有问题;第二,CoreDNS 本身有问题,比如 CoreDNS 返回 refuse 这些错误码;第三,与外部 DNS 通信发生网络中断,性能问题,或者说外部 DNS 不可用。针对这些问题点,总结出以下步骤来排查。
首先从客户端侧,请求查看 Trace,查看返回码、如果返回是错误码,说明是客户端的问题,慢解析看一下时间瀑布流,查看时间耗在哪个阶段;查看网络是否正常,查看流量(RX、TX),查看重传、丢包、RTT 这几个指标来定位网络问题;查看服务器,服务器端的网络,充满饱和度这几个指标,查看黄金指标,也可以结合 CPU,内存,磁盘资源结合来看;外部 DNS,同样可以通过请求 Trace、返回码,查看流量(RX、TX),查看重传数、RTT 进一步定位。
看一下例子,中间黄色的是 CoreDNS,黄色的原因是有错码或异常等,红色的线表示有异常的 DNS 调用,点击这些红色的边,我们就能看到调用的黄金信号指标,点击查看列表,弹出详情页面,可以看请求的详情。
请求的域名是
cn-hangzhou-intranet.arms.aliyuncs.com.cluster.local,返回是域名不存在,这就是为什么线变黄的原因。同时可以看到 CoreDNS 对外提供的服务,有比较多的异常,有三个请求来源的服务都有问题,所以可以进一步排查其他调用是什么原因。
第三个例子是全链路压测,对大促这种场景,峰值是平常的数倍,如何保障大促的稳定,需要通过一系列的压测来验证系统能力,稳定性,容量规划,识别瓶颈。一般会有几个步骤,先预热下,预热的主要作用就是验证链路是否正常,逐步加流量到峰值,峰值一般就是我们预测的最高值,摸高看能支持的最大TPI是多少,再加流量看服务是否能正常限流,再加流量破环性能流量。在这个过程中我们需要关注哪些点呢?
首先,针对多语言、多协议的微服务架构,如 Java,python 应用等,同时其中有多种协议,需要有各种语言,各种协议的黄金信号指标来验证系统能力;第二,需要有各种资源指标识别系统瓶颈,提供容量规划的依据;第三,对于复杂架构,需要一张全局的拓扑图帮助梳理上下游依赖,用来确定爆炸的半径。比如这里的 checkoutService 就是关键的服务,这个点如果出现问题,影响面就会很大。
这个拓扑就对应着上边的架构,可以看到支持各种协议,各种语言的黄金信号指标,通过查看列表可以进一步看调用的详情。第二,可以查看对应的 CPU 等资源指标;最后是整个拓扑图能够反应整个架构形态,所以我们有一个前驱的视角查看哪里可能会成为一个瓶颈,比如这里的 checkoutService 有可能会成为瓶颈。
第四个案例是访问外部 MySQL,常见的问题如下:首先是慢查询,体现为延时比较高,查看 Trace 语句详情,查询的是哪张表,哪些字段,是不是查询量太大,表太大等问题。查询语句过大,会导致产出非常耗时,网络稍微抖动就可能失败或重试,还可能引发被占用的问题,一般是批量的更新插入导致的。出现这种问题,延时指标会超高,可以选择 Trace 看语句&Size;错误码返回,那么解析出其中的错误码就比较有帮助了,再进一步看详情就比较容易定位出问题,最后一个是网络问题,一般配合着延时指标、RTT、重传这些网络指标来定位。
看下实际的例子,中间框着的应用依赖了外部的 MySQL 服务,点击拓扑线可以查看具体的黄金信号指标,点击查看列表可以进一步看请求的详情,响应等等,同时可以看一下网络的性能指标,网络指标的是将当前拓扑中的网络数据根据目标和来源进行归类,可以分别查看请求数,响应时间,重传,RTT等等。
第五个案例是多租户架构,多租户指的是不同的租户,可能是不同的用户,工作负载或团队公用一个集群,并且工作负载与团队之间还需要实现资源的逻辑隔离或者物理隔离,保证互不影响,互不干扰,一定的安全级别。
常见的场景有:
1.企业内部用户。每个租户对应一个命名空间,同一个命名空间内网络流量不受限制,用网络策略控制不同命名空间的网络流量。
2.SaaS 提供商多租户:租广和平台控制面板在各自命名空间中,不同租户应用在不同命名空间中。
虽然 K8S 的命名空间特性给多租户架构带来了便利,但也给可观测带来了几个挑战:
1一个租户对应一个命名空间,命名空间多,查找信息变得繁琐,增加观测、监控成本;
2租户之间有流量隔离需求,命名空间较多情况下,无法做到准确、全面地发现异常流量;
3多语言、多协议支持。
一位用户属于 SaaS 提供商的多租户架构,一共400多位用户,集群里面有400多个命名空间,管理起来非常痛苦,而且应用是多语言、多协议的,需要付出很多改造的计划。
现实中的例子,这是产品的首页,可以看到首页概览这里是按命名空间进行分类且支持查询的,气泡图上展示对应命名空间上的实体数,红色代表有异常的实体数,点进去可以进一步看异常,首页下边是按照黄金信号指标排序的性能概览,能够快速筛选出异常的命名空间。
在拓扑图中,如果命名空间比较多,可以通过过滤功能过滤出需要查询的目标,或者通过搜索的方式快速定位到想看的命名空间,由于节点是以命名空间分组的,所以能够通过命名空间之间的线来查看命名空间之间的流量,这样就能方便的查看有哪些命名空间之间的流量是否有异常流量等等。
下面总结一下前面介绍的几个场景:
首先,网络监控方面,如何通过网络指标确定是否有网络问题,如何通过拓扑图分析评估影响范围;第二是服务监控,如何根据指标确定服务是否健康,如何通过支持多协议的 Trace 查看详情?第三个场景是中间件、基础设施监控,如何通过指标分析中间件、基础设施异常,如何通过网络指标 Trace 数据,快速定界自身服务问题,还是网络问题;最后一个场景是架构感知,如何通过拓扑感知架构,掌控全局?如何保障架构升级过程中的可观测性?如何发现系统瓶颈,分析爆炸半径?
从这几个场景中又进一步列举几 个case:服务健康检查、中间件架构升级、新业务上线验证、服务性能优化、容量评估、方案选型、全链路压测等等。
Demo 分成两部分,一是简要的介绍,二是以 dns 解析异常为例,看一下整个异常发现的过程。
这是 K8S 监控的首页,可以看到服务和命名空间分类的气泡图,每个气泡图代表实际的数量,比如在 kube-system 上有7个 service,红色代表有异常或告警,有1个,点击进去可以进一步查看 service 列表,service 列表上会有一些标签,就是 Kubernetes 的 label,可以查看错误数、请求数、平均响应时间等等,有1个告警数,根据告警判断服务是否有异常,继续点击进入 K8DNS 的详情页,第一排是一些概览的数据,告警数、错误数、请求数等。
点击错误数可以跳到错误数的指标上,可以看到明细列表,点击明细列表可以看到有哪些错误的请求,错误的请求是域名请求,响应是域名不存在;同样可以查看慢调用的指标,有一些告警的事件,告警的事件是通过 Prometheus 实现的,有了告警的事件后,可以查看告警的详情,通过告警的上下文推断到底是什么问题。
详情下边是一张拓扑图,展示的是这个服务上游和下游的一些交互,可以看到 kube-dns 是有一个服务在调用它,下游是一个外部 dns,同时 kube-dns 又跟 default 命名空间有交互,同样可以点击线来查看异常,找到错误数,详情主要分三大部分,上边的列表可以点击切换不同的详情,中间部分是详情解析出来的请求和响应;下边是时间瀑布流,也就是说请求经历了三个阶段,发送请求,等待响应,下载。从时间来看,这三个阶段没有问题,因为dns是一个很快的请求。
当我们发现了这些异常之后,如果觉得这些异常是比较重要的,需要被监控,可能会对用户有影响的,我们就可以对这些异常进行告警的配置,主要两种配置办法:第一种,直接在指标的右上角点击领导,就可以弹出创建告警的页面,这里已经把所有的信息都自动填充收集起来了,所以一般情况下不需要做配置,可能需要对域值做一些调整就可以了。
第二种是在告警配置里面,当我们需要对很多服务,指标进行配置的时候就可以在这个页面进行配置,支持批量的管理,创建告警这里面可以选一些模板,模板都是比较使用的。
dns 解析异常为例,看一下整个异常发现的过程。打开集群拓扑,集群拓扑是一个全局的视角,能够看到更广泛的东西。找到 Core-dns 的服务,红色表示是有异常的,点击红色的边,看黄金信号,对应的指标是否有问题,有错误数,点击明细列表,查看返回是否有问题,看到返回是域名不存在,这就是一个简单的分析过程。知道 Core-dns 有问题,做一下拓扑图分析,除了要知道异常根源之外,还要影响面,现在就只有一个服务在依赖 Core-dns,看起来影响面是没有问题的,下一个服务也就是外部的 dns,也是没有问题的。
总结一下 K8S 产品的价值
通过多协议、多语言、无入侵的方式采集服务的指标和 trace 数据,最大限度地减少介入的成本,同时提供覆盖度比较全面的指标和 trace,有了这些指标和 trace 之后,我们就能对服务和工作负载进行科学的分析,从而发现异常。
将这些指标和 trace 关联起来做成一张拓扑图,能在一张大图上进行架构感知,上下游分析,影响面分析等等,这样就能更充分地理解架构,评估潜在的性能风险等,最后,提供配置简单的告警配置方法,将经验知识沉淀掉告警中,做到主动发现。