专栏首页携程技术干货 | 携程容器偶发性超时问题案例分析(二)

干货 | 携程容器偶发性超时问题案例分析(二)

作者简介

李剑,携程系统研发部技术专家,负责Redis和Mongodb的容器化和服务化工作,喜欢深入分析系统疑难杂症。

周昕毅,携程系统研发部云平台高级研发经理。现负责携程容器云平台运维,Cloud Storage及Cloud Network基础设施研发及运维。

本文为容器偶发性超时问题案例分析的第二篇,第一篇点这里

前言

随着内核升级到4.14.67,看上去延迟的问题彻底解决了,然而并没有,只是出现的更加缓慢。几周后,超时报障又找了过来,我们用perf来分析,发现了一些异常。

如图1所示是一个空负载的宿主机升级内核后8天的perf的数据,明显可以看到kworker的max delay已经100ms+,而这次有规律的是,延迟比较大的都是最后四个核,对于12核的节点就是8-11,并且都是同一D厂的宿主机。而上篇中使用新内核后用来验证解决问题的却不是D厂的宿主机,也就是说除了内核,还有其他的因素导致了延迟。

图1

NUMA和CPU亲和性绑定

NUMA全称Non-Uniform Memory Access,NUMA服务器一般有多个节点,每个节点由多个CPU组成,并且具有独立的本地内存,节点内部使用共有的内存控制器,节点之间是通过内部互联(如QPI)进行通信。

然而,访问本地内存的速度远远高于访问其他节点的远地内存的速度,通常有几十倍的性能差异,这也正是NUMA 名称的由来。因为NUMA的这个特性,为了更好地发挥系统性能,应用程序应该尽量减少不同节点CPU之间的信息交互。

无意中发现,D厂的机型与其他机型的NUMA配置不一样。假设12核的机型,D厂的机型NUMA节点分配如下图2所示:

图2

而其他厂家的机型NUMA节点分配如下图3所示:

图3

为什么会出现delay都是最后四个核上的进程呢?

经过深入排查才发现,原来相关同事之前为了让k8s的相关进程和普通的用户的进程相隔离,设置了CPU的亲和性,让k8s的相关进程绑定到宿主机的最后四个核上,用户的进程绑定到其他的核上,但后面这一步并没有生效。

还是拿12核的例子来说,上面的k8s是绑定到8-11核,但用户的进程还是工作在0-11核上,更重要的是,最后4个核在遇到D厂家的这种机型时,实际上是跨NUMA绑定,导致了延迟越来越高,而用户进程运行在相关的核上就会导致超时等各种故障。

确定问题后,解决起来就简单了。将所有宿主机的绑核去掉,延迟就消失了,以下图4是D厂的机型去掉绑核后开机26天perf的调度延迟,从数据上看一切都恢复正常。

图4

新的问题

大约过了几个月,又有新的超时问题找到我们。有了之前的排查经验,我们觉得这次肯定能很轻易的定位到问题,然而现实无情地给予了我们当头一棒,4.14.67内核的宿主机,还是有大量无规律超时。

深入分析

perf看调度延迟,如图5所示,调度延迟比较大但并没有集中在最后四个核上,完全无规律,同样turbostat依然观察到TSC的频率在跳动。

图5

在各种猜想和验证都被一一证否后,我们开始挨个排除来做测试:

1、我们将某台A宿主机实例迁移走,perf看上去恢复了正常,而将实例迁移回来,延迟又出现了。

2、另外一台B宿主机上,我们发现即使将所有的实例都清空,perf依然能录得比较高的延迟。

3、而与B相连编号同一机型的C宿主机迁移完实例后重启,perf恢复正常。这时候看B的TOP,只有一个kubelet在消耗CPU,将这台宿主机上的kubelet停掉,perf正常,开启kubelet后,问题又依旧。

这样我们基本可以确定kubelet的某些行为导致了宿主机卡顿和实例超时,对比正常/非正常的宿主机kubelet日志,每秒钟都在获取所有实例的监控信息,在非正常的宿主机上,会打印以下的日志。如图6所示:

图6

而在正常的宿主机上没有该日志或者该时间比较短,如图7所示:

图7

到这里,我们怀疑这些LOG的行为可能指向了问题的根源。查看k8s代码,可以知道在获取时间超过指定值longHousekeeping (100ms)后,k8s会记录这一行为,而updateStats即获取本地的一些监控数据,如图8代码所示:

图8

在网上搜索相关issue,问题指向cadvisor的消耗CPU过高,

https://github.com/kubernetes/kubernetes/issues/15644

https://github.com/google/cadvisor/issues/1498

而在某个issue中指出

https://github.com/google/cadvisor/issues/1774),

echo2 > /proc/sys/vm/drop_caches

可以暂时解决这种问题。我们尝试在有问题的机器上执行清除缓存的指令,超时问题就消失了,如图9所示。而从根本上解决这个问题,还是要减少取metrics的频率,比较耗时的metrics干脆不取或者完全隔离k8s的进程和用户进程才可以。

图9

硬件故障

在排查cadvisor导致的延迟的过程中,还发现一部分用户报障的超时,并不是cadvisor导致的,主要表现在没有Housekeeping的日志,并且perf结果看上去完全正常,说明没有调度方面的延迟,但从TSC的获取上还是能观察到异常。

由此我们怀疑这是另一种全新的故障,最重要的是我们将某台宿主机所有业务完全迁移掉,并关闭所有可以关闭的进程,只保留内核的进程后,TSC依然不正常并伴随肉眼可见的卡顿,而这种现象跟之前DBA那台物理机卡顿的问题很相似,这告诉我们很有可能是硬件方面的问题。

从以往的排障经验来看,TSC抖动程度对于我们排查宿主机是否稳定有重要的参考作用。这时我们决定将TSC的检测程序做成一个系统服务,每100ms去取一次系统的TSC值,将TSC的差值大于指定值打印到日志中,并采集单位时间的异常条目数和最大TSC差值,放在监控系统上,来观察异常的规律。如图10所示。

图10

这样采集有几个好处:

1、程序消耗比较小,仅仅消耗几个CPU cycles的时间,完全可以忽略不计;

2、对于正常的宿主机,该日志始终为空;

3、对于有异常的宿主机,因为采集力度足够小,可以很清晰地定位到异常的时间点,这样对于宿主机偶尔抖动情况也能采集到;

恰好TSC检测的服务上线不久,一次明显的故障说明了它检测宿主机是否稳定的有效性。如图11,在某日8点多时,一台宿主机TSC突然升高,与应用的告警邮件和用户报障同一时刻到来。如图12所示:

图11

图12

将采集的日志这样展示后,我们一眼就发现问题都集中在某几批次的同一厂商的宿主机上,并且我们找到之前DBA卡顿的物理机,也是这几批次中的一台。我们收集了几台宿主机的日志详情,反馈给厂商后,确认是硬件故障,无规律并且随时可能触发,需升级BIOS,如图13厂商技术人员答复的邮件所示,至此问题得到最终解决。

图13

总结

本系列的两篇文章基本上描述了我们遇到的容器偶发性超时问题分析的大部分过程,但排障过程远比写出来要艰难。

总的原则还是大胆假设,小心求证,设法找到无规律中的规律性,保持细致耐心的钻研精神,相信这些疑难杂症终会被一一解决。

本文分享自微信公众号 - 携程技术中心(ctriptech),作者:李剑/周昕毅

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 干货 | 携程容器偶发性超时问题案例分析(一)

    李剑,携程系统研发部技术专家,负责Redis和Mongodb的容器化和服务化工作,喜欢深入分析系统疑难杂症。

    携程技术
  • 干货 | 基于 BDD 理念的 UI 自动化测试在携程度假的应用

    Leo Li,携程高级软件工程师,负责度假 BDD-Test UI 自动化测试框架的研发、维护和迭代等工作。

    携程技术
  • 深度学习汇总贴 | 你想看的都在这里

    上个月携程技术中心主办了一场深度学习Meetup,由来自伦敦大学学院、复旦大学、东南大学、南京大学等高校的学术界代表,以及来自携程、华为、搜狗、简书等一线企业的...

    携程技术
  • Vue 组件数据通信方案总结

    初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:

    前端迷
  • Vue 组件数据通信方案总结

    初识 Vue.js ,了解到组件是 Vue 的主要构成部分,但组件内部的作用域是相对独立的部分,组件之间的关系一般如下图:

    政采云前端团队
  • 资源 | 整合全部顶尖目标检测算法:FAIR开源Detectron

    机器之心
  • 【基础安全】基于齐治堡垒机的自动化功能实践1

    在基础安全的工作中,必不可少的会有安全设备运营,活多苦累不用说,还难出成绩。在刚接手各类各式安全设备之前,团队成员已经有意识的去实现自动化,力争解放双手进行更多...

    aerfa
  • 信息化项目软件运维费用都有哪些构成?

    信息化项目软件运维费用应包括软件运维中供方的所有直接成本、间接成本和毛利润,如图1所示。

    软件成本造价评估
  • 5种将死的编程语言

    现在的开发人员都趋向于使用新的编程语言,那么旧的编程语言呢?它们的前途一般是这样两种:仍然可以使用,但逐渐不受大家欢迎;直接完全死去。和之前的十佳最受欢迎的编程...

    Python进击者
  • 5 种前途迷茫的编程语言

    现在的开发人员都趋向于使用新的编程语言,那么旧的编程语言呢?它们的前途一般是这样两种:仍然可以使用,但逐渐不受大家欢迎;直接完全死去。和之前的十佳最受欢迎的编程...

    逆锋起笔

扫码关注云+社区

领取腾讯云代金券