目录

从故障中我们学到了什么?

继阿里云之后,滴滴崩了上了热搜,故障原因了解了一些,会在文章最后谈到。近期国内多个公司发生了 P0 事故,当然也包括我司,只不过可能不出名,很多人不知道而已。本文聊一聊我对这些故障的理解。首先做个声明,下文都是根据个人所了解到的信息以及个人的认知所写,并没有消遣的意思,可能会有一些偏激,如果问题,欢迎互喷。

故障年年有,今年特别多

从年初到现在,小红书,京东,语雀,阿里云,再有昨天的滴滴,都是 P0 故障,小红书和京东都是拿相关人祭天,语雀和阿里云的处理不清楚。故障原的话,对阿里云、京东、滴滴的故障原因有一些了解。

京东的故障个人感觉被裁的研发同学算是背锅的,系统太脆弱了经不起任何的风吹草动,就看谁是那个倒霉蛋来触发这个隐藏彩蛋,像这种服务端不去限流、熔断导致的问题,个人看法就是一律服务端背锅,别管是谁调用导致的。

阿里云的比较出名,影响范围非常广,从故障处理时间线来看整体问题定位和恢复速度还是比较快的。至于故障的原因,从官网给的通告看,算是一个比较低级的问题,白名单生成内容出错,问题影响范围之大本身还是和故障的组件有关,相当于入口出了问题。

前段时间阿里云的故障,不乏大佬出来讲自己的认知,如前阿里的毕玄大佬,总结了一篇《稳定性,难的不是技术,而是》,分别从代码、设计、变更层面给出了做好稳定性的通用指导思想,最后也给出了核心观点:

做好稳定性,难的不是技术,而是……

大家可以看下,是不是在很多故障复盘的改进措施里,都会重复看到上面的影子,说明其实指导思想、解决方案是不缺的,技术上真的没有那么的难,想当年淘宝稳定性很差的某一年,新任 CTO 上来后把稳定性列在了第一考核指标,三个月后淘宝的稳定性就提升了 N 个档次。

但难就难在没有银弹,只能靠大量的细节来落地做好稳定性这个系统工程的事情,这意味着的是大量的投入,能不能在稳定性这件事上保持持续的一定的投入,甚至当成做业务功能实现一样的必须的投入,这才是真正做好稳定性最难的,毕竟就算有指导思想、解决方案、能力,但没有相应的投入,那自然只能有一定的取舍,最终呢,总是要还的。

很多做过稳定性这事的人都知道,做这个事情最麻烦的是很难被认可,做的好,不出问题,不懂的人不知道你做了什么,出了问题的时候觉得你到底做了什么,所以会看到很多公司都是运动式地做稳定性,一阵一阵的。

要解决这个问题其实挺难的,我看到做得好一些的,基本是因为稳定性对业务而言是致命的,例如某些行业,稳定性出问题,业务基本就没法进行下去了;还有就是某些处于非常激烈竞争,但又有关键时间点的业务,例如外卖。

只有把稳定性当成业务的功能实现一样,有相应的人员配备和投入,例如做一个业务可能需要多少人,相应的稳定性这块也固定投入多少人,你说到底多少比例合理呢,其实也说不太清楚,但这种简单粗暴的方式其实是最有效的,当然,是不是要把稳定性上升到这样的高度,也需要根据业务的性质、业务所处的阶段来具体判断,以及有这样的投入的情况下,怎么去评判相应职责的团队也仍然是个很复杂的话题。

简单总结一下就是

  • 人性:医之好治不病以为功,搞稳定性就是费力不讨好,不出问题,没人会知道你的存在和重要性;
  • 投入:既要有系统的方案,又要有大量的细节,还有持续投入,无论是技术上、人员配备上都是如此;

故障驱动了没?

运动式的稳定性,可以理解为我们常说的故障驱动,虽然听起来很挫,真正能做好的也不容易,往往是故障也有了,没有驱动,或者驱动也有了,但没有结果或者没有该有的效果,付出远大于回报,不知道驱动了半天驱动了个啥,该故障还是故障,甚至是同样的故障。

这一点我认为和故障的复盘、负向激励机制有关。

通过复盘来驱动改进,设立改进项,并且跟踪改进项的状态,同时结合上面提到的持续投入,定期的 review。但现实有多少复盘是在糊弄鬼,甚至为了推卸责任,故障报告都会写的含糊其辞的,都在尽可能的大事化小,小事化了。这就从根本上导致改进项不全,甚至发现不了根本问题,也就为后续此类问题的再次发生埋下伏笔,变化的可能只是不同的诱因而已。

国内一般处理 P0 故障先拿相关人员祭天,甚至对应业务负责人也会受影响(当然处理结果除了公司的规章制度外,还和你是不是嫡系,有没有人保,是不是顶风作案等,不好意思,我总是喜欢说实话),但这至少在一定程度上会促进大家保持对稳定性的敬畏之心。当然**负向激励并不是目的,只是一种手段。**并不是所有的公司都有相关的手段,这在一定程度上不利于稳定性的提升,虽然看起来好像很人性一样,但公司不是靠爱发电,业务做好多发福利比出了问题不追责人性化多了。

如何止损?

我们并不是追求百分之百的稳定性,这也不现实,稳定性的提升越到最后,哪怕提升一点,付出也会非常大,ROI 就会比较低,具体到多少合适,还是取决于具体的业务特性,业务对稳定性的容忍程度。在只能降低故障发生概率但无法避免的情况下,如何快速止损也是需要考虑的。

例如公有云上一般会有 SLA,最终会将故障的影响换算为钱,快速止损意味着减少公司的损失。这里也有两方面值得考虑:

  1. 如何缩短故障时长?
  2. 如何降低资损?

第一点比较好理解,就是快速恢复,恢复的越快影响就越小,这很容易理解。站在技术的角度看,第二点很容易被忽略,即不同的业务 SLA 不同,可能有的业务可以接受故障一段时间,或者服务不可用相同时长,不同服务约定的赔偿价格不同或者不同服务在正常时能带来的收益不同,那在进行故障恢复时,就需根据这些数据来排序,先后恢复这些服务。

缩短故障时长本质还是为了降低故障影响(资损),他更像是一种手段,而不是目的。但我们在处理故障时往往舍本逐末,或者没有这个意识,或者有意识,但确实也不知道要先恢复那些服务。

当然如何解决问题,还是需要专业的人出马,靠 ppt 解决故障不现实,至少现在还不现实。这个阶段就能看出来到底谁是老板,谁是干活的,以及人的能力(战斗力)如何。当然出问题,或者恢复时间长也并代表就是没有能力强的人,有没有能力和能力有没有被充分利用起来是两个概念,找到有能力的人来解决问题也是止损甚至避免故障的一个途径。

聊一聊 k8s

有几个 k8s 相关的 P0 故障,作为一个搞了 7 年容器,开发运维都搞的老司机,重点聊聊这几个。

我司的两个 P0 级别的故障(删集群、删库),以及滴滴的这次 P0 故障,都是发生在容器平台,平台异常影响也上面跑的业务。而且这种影响都是集群甚至机房级别的,一挂就是一片,恢复起来也慢。有几个问题值得思考一下:

  1. 我们到底在以什么样的方式使用容器?
  2. 为什么故障范围如此之大,恢复如此慢?

第一个问题,滴滴(前司)在 k8s 的使用方面有一些定制化的工作,为了适配存量的系统,兼顾用户物理机时代的使用习惯,加上最初使用 k8s 版本老一些,扩展能力有限,最终定制的功能会多一些,之前也有一些技术大牛的存在能掌控这些。相对来说我司目前对 k8s 的使用上定制化的开发就少很多了,大部分用的还是原生的组件。在人员组成上,不管哪个公司,真正搞懂 k8s 的并不多,绝大多数还是停留在上层的使用上,一方面是因为 k8s 的复杂性,另一方面也和具体公司的某些机制或者制度有关。最终的现象就是可能看起来搞容器的人很多,但都停留在表面,或者某一方面,都在围绕 k8s 做事情,但真正对 k8s 的掌握不足。

第二个问题的核心在于 k8s 的生命式 API 的设计,在 k8s 之前的物理机或者虚机时代,一般的系统都是命令式的,也就是说一般情况下控制面出现问题的话,影响的是增量的服务,存量的不受影响。但 k8s 并不是这样,反而控制面出问题的时候,存量的服务非常容易受到影响。同时 k8s 中存在着大量的自动操作,需要使用者格外关注,稍不注意就会户问题。比如节点 down 了之后的自动驱逐,节点有资源压力时的自动驱逐,k8s 升级时的各种 checksum 校验引发的资源泄露甚至容器重启等等,这都需要使用者或者管理员对 k8s 有一定的掌握,在设计平台或者进行操作时来规避这些问题。哪怕是是在无法避免,出问题时能快速定位快速止损。

k8s 使用起来容易,管理好了难。

作为 Operator 的开发者,如果只是想基于 k8s 之上实现功能,都有比较经典的模板或者工具直接使用,比如写个 crd 和 operator,通过 Informer 实现增删改查等等。但实现的效果却可能会非常大的差异,无论是从自身组件看还是从对 k8s 的影响看,例如之前见过一段代码,会 for 循环针对每个 namespace 建立一个 informer 并添加对应的 event handler 做一些逻辑处理。说他不能用吧,也能用,但是我们需要清楚他潜在的问题,即在集群内 ns 数量变多时,goroutine 数量会变多,在有几万个 ns 时,就会有几万个 goroutine,这肯定是会有问题的,同时几万个 informer 都会对 kube-apiserver 发起 List & Watch 请求,会不会触发客户端的限流,会不会触发服务端限流,会不会增加服务端的内存压力等等的问题,都是值得考虑的,但是在你不了解 informer 原理,不了解 kube-apiserver 内存消耗的时候是根本没有意识去关注这些问题的。

作为集群管理员,提供一个途径让业务能够高效且体验良好的使用 k8s 很重要,但也需要清楚的知道在上面跑的业务对 k8s 的影响,不只是接入业务就万事大吉了,平台运营需要考虑准入问题,即作为管理员,要清楚跑上来的业务是否会危害到集群的健康,比如上面的那个服务要是跑上来,集群可能就有挂的危险。接入是最简单的,管理才是核心,平台需要提供接入规范,例如用户程序都需要用到哪些集群资源,以什么样的方式访问,QPS 什么量级等,并且提供对应的工具帮助用户自动生成相关数据,组织为对应格式的文件,随着部署文件一并提交,平台侧需要对这些应用进行审核,审核之后的应用才允许被部署。

k8s 提供了通用能力,也就意味着使用者需要根据自己的实际情况来做管理,对管理员的要求就会提高。比如上面提到的一些自动的操作,在没有控制能力的情况下,是否可以先关闭,这是一个值得考虑的问题,众多的问题都是因此而起。但这对于没有经验的人来说,似乎又是必定会踩的坑,这也能侧面反映出来除了写 API 之外,需要有经验有能力的人。

总结的话就是 k8s 虽然已经开源这么多年,很多公司都在用了,但真的是能搞懂的人并不多,再加上设计机制,以及复杂性,在对他缺乏把控力的情况下出问题,影响范围广,回复时间长,似乎也就可以理解了。

最后

这个行业最不缺的就是事后诸葛亮,和写 PPT 的人,真正缺的还是那些挽狂澜于既倒,扶大厦之将倾的人。当然并不是说写 PPT 不好,每个公司或者职位有自己的生存之道,无可厚非,向上管理,汇报也是必要的职场能力,但这本不该是技术人员的重点或者全部。

愿这个世界对程序员友好一些,尤其这些刀口舔血的人。愿每个人都能被温柔以待,做自己喜欢做的事情,做有价值的事情,做有趣的事情,摆脱无效的内卷和精神内耗。卷不过,那就躺平,躺不平,那就一起写 blog 吧,哈哈…

(上文中提到了滴滴故障的原因,有一些东西不方便写,对 K8S 或者各种故障感兴趣的朋友可以加我 WX:YlikakuY,一起交流,一起进步)