关于java:深度解密|基于-eBPF-的-Kubernetes-问题排查全景图发布

7次阅读

共计 7441 个字符,预计需要花费 19 分钟才能阅读完成。

简介:以后,云原生技术以容器技术为根底,通过规范可扩大的调度、网络、存储、容器运行时接口来提供基础设施。

当 Kubernetes 成为云原生事实标准,可观测性挑战随之而来

以后,云原生技术以容器技术为根底,通过规范可扩大的调度、网络、存储、容器运行时接口来提供基础设施。同时,通过规范可扩大的申明式资源和控制器来提供运维能力,两层标准化推动了开发与运维关注点拆散,各畛域进一步晋升规模化和专业化,达到老本、效率、稳定性的全面优化。

在这样的大技术背景下,越来越对的公司引入了云原生技术来开发、运维业务利用。正因为云原生技术带来了越发纷繁复杂的可能性,业务利用呈现了微服务泛滥、多语言开发、多通信协议的鲜明特征。同时,云原生技术自身将复杂度下移,给可观测性带来了更多挑战:

1、混沌的微服务架构,多语言和多网络协议混淆

业务架构因为分工问题,容易呈现服务数量多,调用协定和关系非常复杂的景象,导致的常见问题包含:

  • 无奈精确清晰理解、掌控全局的零碎运行架构;
  • 无法回答利用之间的连通性是否正确;
  • 多语言、多网络调用协定带来埋点老本呈线性增长,且反复埋点 ROI 低,开发个别将这类需要优先级升高,但可观测数据又不得不采集。

2、下沉的基础设施能力屏蔽实现细节,问题定界越发艰难

基础设施能力持续下沉,开发和运维关注点持续拆散,分层后彼此屏蔽了实现细节,数据方面不好关联了,呈现问题后不能迅速地定界问题呈现在哪一层。开发同学只关注利用是否失常工作,并不关怀底层基础设施细节,呈现问题后须要运维同学协同排查问题。运维同学在问题排查过程中,须要开发同学提供足够的上下游来推动排查,否则只拿到“某某利用提早高”这么抽象的表述,这很难有进一步后果。所以,开发同学和运维同学之间须要共同语言来进步沟通效率,Kubernetes 的 Label、Namespace 等概念非常适合用来构建上下文信息。

3、繁多监测零碎,造成监测界面不统一

简单零碎带来的一个重大副作用就是监测零碎繁多。数据链路不关联、不对立,监测界面体验不统一。很多运维同学或者大多都有过这样的体验:定位问题时浏览器关上几十个窗口,在 Grafana、控制台、日志等各种工具之间来回切换,不仅十分耗时微小,且大脑能解决的信息无限,问题定位效率低下。如果有对立的可观测性界面,数据和信息失去无效地组织,缩小注意力扩散和页面切换,来进步问题定位效率,把宝贵时间投入到业务逻辑的构建下来。

解决思路与技术计划

为了解决上述问题,咱们须要应用一种反对多语言,多通信协议的技术,并在产品层面尽可能笼罩软件栈端到端的可观测性需求,通过调研,咱们提出一种立足于容器界面和底层操作系统,向上关联利用性能监测的可观测性解决思路。

要采集容器、节点运行环境、利用、网络各个维度的数据挑战十分大,云原生社区针对不同需要给出了 cAdvisor、node exporter、kube-state-metics 等多种形式,但依然无奈满足全副需要。保护泛滥采集器的老本也不容小觑,引发的一个思考是是否有一种对利用无侵入的、反对动静扩大的数据采集计划?目前最好的答案是 eBPF。

「数据采集:eBPF 的超能力」

eBPF 相当于在内核中构建了一个执行引擎,通过内核调用将这段程序 attach 到某个内核事件上,实现监听内核事件。有了事件咱们就能进一步做协定推导,筛选出感兴趣的协定,对事件进一步解决后放到 ringbuffer 或者 eBPF 自带的数据结构 Map 中,供用户态过程读取。用户态过程读取这些数据后,进一步关联 Kubernetes 元数据后推送到存储端。这是整体处理过程。

eBPF 的超能力体现在能订阅各种内核事件,如文件读写、网络流量等,运行在 Kubernetes 中的容器或者 Pod 里的所有行为都是通过内核零碎调用来实现的,内核晓得机器上所有过程中产生的所有事件,所以内核简直是可观测性的最佳观测点,这也是咱们为什么抉择 eBPF 的起因。另一个在内核上做监测的益处是利用不须要变更,也不须要从新编译内核,做到了真正意义上的无侵入。当集群里有几十上百个利用的时候,无侵入的解决方案会帮上大忙。

但作为新技术,人们对 eBPF 也存在些许担心,比方安全性与探针性能。为了充分保证内核运行时的安全性,eBPF 代码进行了诸多限度,如最大堆栈空间以后为 512、最大指令数为 100 万。与此同时,针对性能担心,eBPF 探针管制在大概在 1% 左右。其高性能次要体现在内核中解决数据,缩小数据在内核态和用户态之间的拷贝。简略说就是数据在内核里算好了再给用户过程,比方一个 Gauge 值,以往的做法是将原始数据拷贝到用户过程再计算。

可编程的执行引擎人造适宜可观测性

可观测性工程通过帮忙用户更好的了解零碎外部状态来打消常识盲区和及时打消系统性危险。eBPF 在可观测性方面有何威力呢?

以利用异样为例,当发现利用有异样后,解决问题过程中发现短少利用层面可观测性,这时候通过埋点、测试、上线补充了利用可观测性,具体的问题失去了解决,但往往治标不治本,下一次别的中央有问题,又须要走同样的流程,另外多语言、多协定让埋点的老本更高。更好的做法是用无侵入形式去解决,以防止须要观测时没有数据。

eBPF 执行引擎可通过动静加载执行 eBPF 脚本来采集可观测性数据,举个具体例子,假如本来的 Kubernetes 零碎并没有做过程相干的监测,有一天发现了某个歹意过程(如挖矿程序)在疯狂地占用 CPU,这时候咱们会发现这类歹意的过程创立应该被监测起来,这时候咱们能够通过集成开源的过程事件检测库来是实现,但这往往须要打包、测试、公布这一整套流程,全副走完可能一个月就过来了。

相比之下,eBPF 的形式显得更为高效快捷,因为 eBPF 反对动静地加载到内核监听过程创立的事件,所以咱们能够将 eBPF 脚本形象成一个子模块,采集客户端每次只须要加载这个子模块里的脚本实现数据采集,再通过对立的数据通道将数据推送到后端。这样咱们就省去了改代码、打包、测试、公布的繁琐流程,通过无侵入的形式动静地实现了过程监测这样的需要。所以,eBPF 可编程的执行引擎非常适合用来将加强可观测性,将丰盛的内核数据采集上来,通过关联业务利用,不便问题排查。

从监测零碎到可观测性

随着云原生浪潮,可观测性概念正深入人心。但仍离不开日志、指标、链路这三类可观测畛域的数据基石。做过运维或 SRE 的同学常常遇到这样的问题:中午被拉到应急群里,披头盖地地被质问为什么数据库不工作了,在没有上下文的状况下,无奈立即抓住问题外围。咱们认为好的可观测性平台应该帮忙用户很好地反馈上下文,就像 Datadog 的 CEO 说的那样:监测工具不是性能越多功能越好,而是要思考怎么在不同团队和成员之间架起桥梁,尽可能把信息放在同一个页面中(to bridge the gap between the teams and get everything on the same page)。

因而,在可观测性平台产品设计上须要以指标、链路、日志为根本,向外集成阿里云自家的各类云服务,同时也反对开源产品数据接入,将要害上下文信息关联起来,不便不同背景的工程师了解,进而减速问题排查。信息没有无效地组织就会产生了解老本,信息粒度上以事件 -> 指标 -> 链路 -> 日志由粗到细地组织到一个页面中,不便下钻,不须要多个零碎来回跳转,从而提供统一体验。

那么具体怎么关联呢?信息怎么组织呢?次要从两方面来看:

1、端到端:开展说就是利用到利用,服务到服务,Kubernetes 的标准化和关注点拆散,各自开发运维各自关注各自畛域,那么端到端的监测很多时候成了”三不管“区域,呈现问题的时候很难排查链路上哪个环节出了问题。因而从端到端的角度来看,两者调用关系是关联的根底,因为零碎调用才产生了分割。通过 eBPF 技术十分不便地以无侵入的形式采集网络调用,进而将调用解析成咱们熟知的利用协定,如 HTTP、GRPC、MySQL 等,最初将拓扑关系构建起来,造成一张清晰的服务拓扑后不便疾速定位问题,如下图中网关 ->Java 利用 ->Python 利用 -> 云服务的残缺链路中,任意一环呈现延时,在服务拓扑中应能一眼看出问题所在。这是第一个管线点端到端。

2、自顶向下全栈关联:以 Pod 为媒介,Kubernetes 层面关联 Workload、Service 等对象,基础设施层面能够关联节点、存储设备、网络等,利用层面关联日志、调用链路等。

接下来介绍下 Kubernetes 监测的外围性能。

永不过期的黄金指标

黄金指标是用来监测零碎性能和状态的最小汇合。黄金指标有两个益处:一,间接了然地表白了零碎是否失常对外服务。二,能疾速评估对用户的影响或事态的严重性,能大量节俭 SRE 或研发的工夫,设想下如果咱们取 CPU 使用率作为黄金指标,那么 SRE 或研发将会奔于疲命,因为 CPU 使用率高可能并不会造成多大的影响。

Kubernetes 监测反对这些指标:

  • 申请数 /QPS
  • 响应工夫及分位数(P50、P90、P95、P99)
  • 谬误数
  • 慢调用数

如下图所示:

全局视角的服务拓扑

诸葛亮曾言“不谋全局者,有余谋一域”。随着当下技术架构、部署架构的复杂度越来越高,产生问题后定位问题变得越来越辣手,进而导致 MTTR 越来越高。另一个影响是对影响面的剖析带来十分大的挑战,通常会造成顾此失彼。因而,有一张像地图一样的拓扑大图十分必要。全局拓扑具备以下特点:

零碎架构感知:零碎架构图是程序员理解一个新零碎的重要参考,当拿到一个零碎,起码须要通晓流量入口在哪里,有哪些外围模块,依赖了哪些外部内部组件等。在异样定位过程中,有一张全局架构的图对异样定位过程有十分大推动作用。

依赖剖析:有一些问题是呈现在上游依赖,如果这个依赖不是本人团队保护就会比拟麻烦,当本人零碎和上游零碎没有足够的可观测性的时候就更麻烦了,这种状况下就很难跟依赖的维护者讲清楚问题。在咱们的拓扑中,通过将黄金指标的上下游用调用关系连起来,造成了一张调用图。边作为依赖的可视化,能查看对应调用的黄金信号。有了黄金信号就能疾速地剖析上游依赖是否存在问题。

分布式 Tracing 助力根因定位

协定 Trace 同样是无入侵、语言无关的。如果申请内容中存在分布式链路 TraceID,能自动识别进去,不便进一步下钻到链路追踪。应用层协定的申请、响应信息有助于对申请内容、返回码进行剖析,从而晓得具体哪个接口有问题。如需查看代码级别或申请界别的详情,可点击 Trace ID 下钻到链路追踪剖析查看。

开箱即用的告警性能

开箱即用的告警模板,各个不同档次全笼罩,不须要手动配置告警,将大规模 Kubernetes 运维教训融入到告警模板外面,精心设计的告警规定加上智能降噪和去重,咱们可能做到一旦告警就是无效的告警,并且告警外面带有关联信息,能够疾速定位到异样实体。告警规定全栈笼罩的益处是能及时、被动地将高风险事件报给用户,用户通过排查定位、解决告警、预先复盘、面向失败设计等一系列伎俩,最终逐渐达成更好的零碎稳定性。

网络性能监测

网络性能问题在 Kubernetes 环境中很常见,因为 TCP 底层机制屏蔽了网络传输的复杂性,应用层对此是无感的,这对生产环境定位丢包率高、重传率高这种问题带来肯定的麻烦。Kubernetes 监测反对了 RTT、重传 & 丢包、TCP 连贯信息来表征网络情况,上面以 RTT 为例,反对从命名空间、节点、容器、Pod、服务、工作负载这几个维度来看网络性能,反对以下各种网络问题的定位:

负载平衡无法访问某个 Pod,这个 Pod 上的流量为 0,须要确定是否这个 Pod 网络有问题,还是负载平衡配置有问题;

某个节点上的利用仿佛性能都很差,须要确定是否节点网络有问题,通过对别的节点网络来达到;

链路上呈现丢包,但不确定产生在那一层,能够通过节点、Pod、容器这样的程序来排查。

Kubernetes 可观测性全景视角

有了上述产品能力,基于阿里巴巴在容器、Kubernetes 方面有着丰盛且极具深度的实际,咱们将这些贵重生产实践演绎、转化成产品能力,以帮忙用户更无效、更快捷地定位生产环境问题。应用这个排查全景图能够通过以下办法:

大体构造上是以服务和 Deployment(利用)为入口,大多数开发只须要关注这一层就行了。重点关注服务和利用是否错慢,服务是否连通,正本数是否合乎预期等

再往下一层是提供真正工作负载能力的 Pod。Pod 重点关注是否有错慢申请,是否衰弱,资源是否富余,上游依赖是否衰弱等

最底下一层是节点,节点为 Pod 和服务提供运行环境和资源。重点关注节点是否衰弱,是否处于可调度状态,资源是否富余等。

**
网络问题 **

网络是 Kubernetes 中最辣手、最常见的问题,因为以下几个起因给咱们定位生产环境网络问题带来麻烦:

  • Kubernetes 的网络架构复杂度高,节点、Pod、容器、服务、VPC 交相辉映,几乎能让你目迷五色;
  • 网络问题排查须要肯定的专业知识,大多数对网络问题都有种天生的恐怖;
  • 分布式 8 大舛误通知咱们网络不是稳固的、网络拓扑也不变化无穷的、延时不可漠视,造成了端到端之间的网络拓扑不确定性。

Kubernetes 环境下场景的网络问题有:

  • conntrack 记录满问题;
  • IP 抵触;
  • CoreDNS 解析慢、解析失败;
  • 节点没开外网。(对,你没听错);
  • 服务拜访不通;
  • 配置问题(LoadBalance 配置、路由配置、device 配置、网卡配置);
  • 网络中断造成整个服务不可用。

网络问题千千万万,但万变不离其宗的是网络有其表征其是否失常运行的”黄金指标“:

  • 网络流量和带宽;
  • 丢包数(率)和重传数(率);
  • RTT。

上面的示例展现了因网络问题导致的慢调用问题。从 gateway 来看产生了慢调用,查看拓扑发现调上游 product 的 RT 比拟高,然而 product 自身的黄金指标来看 product 自身服务并没有问题,进一步查看两者之间的网络情况,发现 RTT 和重传都比拟高,阐明网络性能好转了,导致了整体的网络传输变慢,TCP 重传机制覆盖了这个事实,在利用层面感知不到,日志也没法看出问题所在。这时候网络的黄金指标有助于定界出问题,从而减速了问题的排查。

节点问题

Kubernetes 做了大量工作,尽可能确保提供给工作负载和服务的节点是失常的,节点控制器 7×24 小时地查看节点的状态,发现影响节点失常运行的问题后,将节点置为 NotReady 或不可调度,通过 kubelet 把业务 Pod 从问题节点中驱赶进来。这是 Kubernetes 的第一道防线,第二道防线是云厂商针对节点高频异样场景设计的节点自愈组件,如阿里云的 node repairer:发现问题节点后,执行排水驱赶、置换机器,从而做到自动化地保障业务失常运行。即便如此,节点在长期应用过程中不可避免地会产生各种奇奇怪怪的问题,定位起来比拟费时耗力。常见问题分类和级别:

针对这些繁冗的问题,总结出如下排查流程图:

以一个 CPU 打满为例:1、节点状态 OK,CPU 使用率超过了 90%

2、查看对应的 CPU 的三元组:使用率、TopN、时序图,首先每个核的使用率都很高,进而导致整体 CPU 应用高;接下来咱们天然要晓得谁在疯狂地应用 CPU,从 TopN 列表来看有个 Pod 一枝独秀地占用 CPU;最初咱们得确认下 CPU 飙高是什么时候开始的。

服务响应慢

造成服务响应十分多,场景可能的起因有代码设计问题、网络问题、资源竞争问题、依赖服务慢等起因。在简单的 Kubernetes 环境下,定位慢调用能够从两个计划去动手:首先,利用本身是否慢;其次,上游或网络是否慢;最初查看下资源的应用状况。如下图所示,Kubernetes 监测别离从横向和纵向来剖析服务性能:

横向:次要是端到端层面来看,首先看本人服务的黄金指标是否有问题,再逐渐看上游的网络指标。留神如果从客户端来看调用上游耗时高,但从上游自身的黄金指标来看是失常的,这时候十分有可能是网络问题或者操作系统层面的问题,此时能够用网络性能指标(流量、丢包、重传、RTT 等)来确定。

纵向:确定利用自身对外的延时高了,下一步就是确定具体哪个起因了,确定哪一步 / 哪个办法慢能够用火焰图来看。如果代码没有问题,那么可能执行代码的环境是有问题的,这时能够查看零碎的 CPU/Memory 等资源是否有问题来做进一步排查。

上面举个 SQL 慢查问的例子(如下图)。在这个例子中网关调用 product 服务,product 服务依赖了 MySQL 服务,逐渐查看链路上的黄金指标,最终发现 product 执行了一条特地简单的 SQL,关联了多张表,导致 MySQL 服务响应慢。MySQL 协定基于 TCP 之上的,咱们的 eBPF 探针辨认到 MySQL 协定后,组装、还原了 MySQL 协定内容,任何语言执行的 SQL 语句都能采集到。

第二个例子是利用自身慢的例子,这时候天然会问具体哪一步、哪个函数造成了慢,ARMS 利用监控反对的火焰图通过对 CPU 耗时定期采样(如下图),帮忙疾速定位到代码级别问题。

利用 /Pod 状态问题

Pod 负责管理容器,容器是真正执行业务逻辑的载体。同时 Pod 是 Kubernetes 调度的最小单元,所以 Pod 同时领有了业务和基础设施的复杂度,须要联合着日志、链路、零碎指标、上游服务指标综合来看。Pod 流量问题是生产环境高频问题,比方数据库流量陡增,当环境中有成千上万个 Pod 时,排查流量次要来自哪个 Pod 就显得特地艰难。

接下来咱们看一个典型的案例:上游服务在公布过程中灰度了一个 Pod,该 Pod 因代码起因响应十分慢,导致上游都超时了。之所以能做到 Pod 级别的可观测,是因为咱们用 ebpf 的技术来采集 Pod 的流量、黄金指标,因而能够通过拓扑、大盘的形式不便地查看 Pod 与 Pod、Pod 与服务、Pod 与内部的流量。

总结

通过 eBPF 无侵入地采集多语言、多网络协议的黄金指标 / 网络指标 /Trace,通过关联 Kubernetes 对象、利用、云服务等各种上下文,同时在须要进一步下钻的时候提供专业化的监测工具(如火焰图),实现了 Kubernetes 环境下的一站式可观测性平台。

如果您在架构云原生监测的过程中,有以下困扰,那么请毫不犹豫的分割咱们一起探讨:

对 Kubernetes 不相熟,须要一整套残缺的对立监测计划;
Prometheus、Alertmanager、Grafana 等多个零碎的数据割裂和上手难;
容器环境下利用、基础设施埋点老本过高,正在寻找低成本或无侵入的解决方案;

原文链接
本文为阿里云原创内容,未经容许不得转载。

正文完
 0