第九章 故障响应

写在开头:

故障总会发生!如何对故障快速进行有组织的响应?Google方式是一个很好的借鉴。

每个团队都希望服务没有故障发生,但这个世界是不完美的,像断电这类的事件不可避免。当一个紧急故障需要多人或团队协作解决时,如何响应故障并解决问题是我们要应对的。

处理故障的目标是减轻影响或将服务恢复到先前的状态。而故障管理意味着以有效的方式协调团队的响应工作,并确保响应者和利益相关者之间的信息流通。包括谷歌在内的许多科技公司都有自己的“最佳实践”来管理应急响应,并且在不断的完善。

故障管理的基本前提是以结构化的方式响应故障。大规模故障是单人无法解决的;结构化的应急响应可以减少混乱。在灾难发生之前制定沟通和协调规范,使你的团队可以集中精力解决故障,而不用担心沟通和协调问题。

故障响应的过程并不是困难的事情。大量实践经验总结可以为我们提供一些指导,比如在第一本SRE书中的《故障管理》章节。故障响应的基本原则包括以下内容:

  • 保持清晰的指挥线
  • 明确角色
  • 随时掌握调试工作记录
  • 响应进度的实时更新

本章介绍了如何在Google和PagerDuty中进行故障管理。通过一些Case说明我们在其中达到的目标以及没有达到的目标。 “将最佳实践付诸实践”(第191页)中的清单可以帮助你开始创建自己的故障响应实践。

Google故障管理

故障响应是用于响应和管理故障的系统。由一个框架和一组定义的程序组成。Google的故障响应系统是基于故障命令系统(ICS)实现的。

故障指挥系统

ICS成立于1968年,是消防员管理野火的一种方式。该框架提供了在故障响应期间进行通信和明确角色的标准化方法。基于该模型,公司后来采用ICS来应对计算机和系统故障。本章探讨了两个这样的框架:PagerDuty的故障响应流程和Google故障管理(IMAG)。

故障响应框架有三个共同目标,也称为事件管理的“三个C”(3C):

  • 协调响应工作
  • 在故障响应者、组织内部和外部之间进行通信
  • 保持对故障响应的控制

当故障响应出现问题时,罪魁祸首可能出现在其中一个方面。掌握3C对于有效的事件响应至关重要。

故障响应中的主要角色

故障响应中的主要角色是故障指挥官(IC),通信主管(CL)和操作或行动主管(OL)。 IMAG将这些角色组织成一个层次结构:IC引导故障响应,CL和OL报告给IC。

灾难发生时,声明故障的人通常会进入IC角色并指挥故障的高级别状态。 IC专注于3C,并执行以下操作:

  • 命令和协调故障响应,根据需要委派角色。默认情况下,IC会假定尚未委派的所有角色。
  • 有效沟通。
  • 保持对故障响应的控制。
  • 与其他相应人员合作解决此事件。

IC可以将其角色交给其他人并承担OL角色,或将OL角色分配给其他人。 OL通过应用工具来缓解或解决故障,从而对故障做出响应。

虽然IC和OL致力于减轻和解决故障,但CL是故障响应团队的消息通讯核心。 CL的主要职责包括定期向故障响应团队和利益相关者实时更新故障响应的进展。

CL和OL都可以领导一个团队来帮助管理他们特定的故障响应区域。这些团队可以根据需要进行扩展或收缩。如果故障变得足够小,那么CL角色就可以被包含到IC角色中。

案例研究

以下四个大型故障说明故障响应如何在实践中起作用。其中三个案例研究来自Google,最后一个是来自PagerDuty的案例研究,该研究提供了其他组织如何使用ICS派生框架的观点。Google的例子以一个没有有效管理的故障开始,并在有故障管理时对故障响应的改观。

案例研究1:软件错误—灯还开着,但没有人(Google HOME)

这个例子展示了故障发生初期不进行通报,在没有工具快速有效地响应故障时,团队是如何响应故障的。虽然这一故障在没有重大灾难的情况下得到了解决,但是越早组织,就会产生更好的效果。

背景

Google Home是一款智能扬声器和家庭助手,可响应语音命令。语音命令与Google Home的软件(称为Google智能助理)进行交互。

当用户说出一个触发Google智能助理的热门词组时,就会启动与Google Home的互动。多个用户可以通过培训助理来监听给定的热门词汇,从而使用相同的Google Home设备。识别扬声器的热词模型是在客户端进行的,但是数据(例如扬声器识别文件)存储在服务器上。服务器处理数据的双向流,为了在繁忙的时候处理超载,服务器对Google助手有一个配额政策。为了保护服务器免受过大请求值的影响,配额限制明显高于在给定设备上的Google助手的基准使用量。

Google智能助理1.88版中的错误导致扬声器识别文件的获取频率超过预期的50倍,超出此配额。最初,美国中部的GoogleHome用户只有很少的流量损失。然而,随着所有GoogleHome设备的推出逐步增加,用户在2017年6月3日的周末期间丢失了一半的请求。

故障

太平洋标准时间5月22日星期一上午11:48,谷歌主页on-call开发人员Jasper正在看着每秒查询(QPS)图表并注意到一些奇怪的事情:谷歌助理每隔30分钟就会收到培训数据,而不是像预期的那样每天一次。他停止了已经推到了25%用户的1.88版本发布。他提了一个漏洞——称之为bug 12345——用谷歌的漏洞追踪系统来探索为什么会发生这种情况。在这一问题上,他指出,谷歌助手每天会对数据进行48次的ping请求,导致其超过了QPS的容量。

另一位开发人员Melinda将此问题与先前报告的漏洞相关联,我们将其称为错误67890:每当应用程序刷新设备身份验证和注册状态时,语音处理器都会重新启动。该版本将在版本1.88发布后修复,因此该团队要求临时增加模型的配额,以减轻额外查询的过载。

版本1.88版本再次启动并继续推出,到5月31日星期三达到50%的用户。不幸的是,该团队后来了解到错误67890,虽然负责一些额外的流量,但并不是Jasper所注意到的更频繁的取回的真正根源。

同一天早上,客户开始向Google支持小组报告问题:每当有人说“OK Google”(或任何其他热门词汇来激活Google Home)时,设备都会回复并显示错误消息,此问题阻止用户向Google智能助理发出命令。该团队开始调查可能导致用户报告的错误的原因。他们怀疑配额问题,所以他们要求增加配额,这似乎可以缓解这个问题。

与此同时,该团队继续调查bug 12345,看看是什么触发了错误。尽管在调试过程的早期就建立了配额连接,但是客户端和服务器开发人员之间的误解导致了开发人员在故障排除过程中走错了方向,而完整的解决方案仍然无法实现。

该团队还对为什么Google智能助理的流量不断达到配额限制感到困惑。客户端和服务器开发人员对客户端错误感到困惑,这些错误似乎没有被服务器端的任何问题触发。开发人员将日志记录添加到下一个版本,以帮助团队更好地理解错误,并希望在解决事件方面取得进展。

截至6月1日星期四,用户报告此问题已得到解决。没有报道任何新问题,因此版本1.88版本继续推出。但是,原始问题的根本原因尚未确定。

在6月3日的周六早上,版本1.88的发布超过了50%。这一发布是在一个周末进行的,当时开发团队并没有人值班。该团队并没有遵循在工作日期间执行部署的最佳实践,以确保开发人员在场。

在6月3日星期六,当版本1.88发布的时候达到了100%,客户端又一次达到了Google助理流量的服务器限制。来自客户的错误报告开始出现。谷歌员工报告称,他们的Google HOME设备出现了错误。Google Home支持小组收到了大量关于此问题的客户来电,反馈也包括了推文和Reddit帖子。 Google Home的帮助论坛也出现了正在讨论这个问题的帖子。尽管有大量的用户报告和反馈,bug并没有升级到更高的优先级。

6月4日星期日,随着客户报告数量的不断增加,支持团队最终将错误优先级提升到最高水平。该团队没有通报故障,而是继续通过“常规”方法解决问题—使用bug跟踪系统进行通信。on-call开发人员注意到一个数据中心集群中的错误率,SRE进行了ping操作,要求他们排除它。与此同时,该团队提出了另一项增加配额的请求。之后,开发团队的一名工程师注意到流量通道已将错误推入其他单元格,这为配额问题提供了额外的证据。下午3:33,开发人员团队经理再次增加了Google智能助理的配额,并停止了对用户的影响。故障结束。该团队此后不久确定了根本原因(参见前面的“环境”部分)。

总结

故障处理的某些方面进展顺利,而其他方面则有改进的余地。

首先,工程师在周末处理故障并为解决问题提供了宝贵的意见,这既好又坏,虽然团队重视这些人在周末所付出的时间和精力,但成功的故障管理不应该依赖于个人的英勇行为。如果无法联系到开发人员怎么办?Google鼓励良好的工作与生活平衡——工程师不应在空闲时间内解决与工作相关的问题。相反,我们应该在工作时间进行部署,或者组织一次在工作时间之外提供付费保障的on-call轮换。

接下来,该团队致力于缓解这一问题。Google首先要求是阻止故障的影响,然后找到根本原因(除非根本原因只是在早期发现)。一旦问题得到缓解,找到根本原因同样重要,以防止问题再次发生。在这个故障事件中,成功地在三个不同的场合控制了故障影响,但团队只有在发现根本原因后才能防止问题再次发生。在第一次故障得到控制之后,最好是等到根本原因完全确定后再开始实施,避免周末发生大混乱。最后,在问题首次出现时,团队没有通告故障。我们的经验表明,管理故障可以更快地解决。尽早通告故障可确保:

  • 防止客户端和服务器开发人员之间的沟通错误。
  • 根源识别和故障解决发生得更快。
  • 相关团队提前进入,使外部沟通更快捷顺畅。

集中式通信是IMAG协议的重要原则。例如,当灾难发生时,SRE通常聚集在一个“作战室”中。作战室可以是像会议室一样的真实环境,也可以是虚拟的:团队可能聚集在IRC频道。这里的关键是将所有的故障响应者集中在一个地方,并实时沟通以管理并最终解决故障。

案例研究2:服务故障—如果可以,请对我进行缓存

下面的故障说明了当一个“专家级”团队试图调试一个具有复杂交互系统时会发生什么——没有一个人能够掌握所有的细节。

背景

Kubernetes是一个由许多公司和个人贡献者共同建立的开源容器管理系统。 Google Kubernetes Engine(或称GKE)是Google管理的系统,可为用户创建、托管和运行Kubernetes群集。用户以最适合他们的方式上传和管理工作负载。当用户首次创建新群集时,GKE将获取并初始化其群集所需的Docker镜像。理想情况下,这些组件是在内部获取和构建的,因此我们可以验证它们。但Kubernetes是一个开源系统,新的依赖关系有时会让系统出现问题。

故障

在太平洋标准时间一个星期四上午6点41分,伦敦GKE的on-call人员Zara寻访了多个区域的CreateCluster探查器故障,新的集群没有被成功地创建。 Zara检查了prober仪表板,发现两个区域的故障率都在60%以上。他确认此问题影响了用户创建新群集的功能,但现有群集的流量未受影响。 Zara遵循GKE的文件化程序,于上午7:06对故障进行了通告。最初,有四人参与处理了这一故障:

  • Zara是第一个注意到这个问题的人,因此被指定为默认故障指挥官。
  • Zara的两名队友。
  • Rohit由故障程序分配的客户支持工程师。

由于Rohit总部设在苏黎世,Zara(IC)开设了一个GKE Panic IRC频道,团队可以在那里一起调试。在另外两个SRE深入调查监控和错误信息时,Zara解释了故障及其对Rohit的影响。截至上午7点24分,Rohit向用户发布通知称,创建集群的功能在欧洲西部地区出现故障。这提高了故障的等级。早上7点到8点20分,Zara、Rohit和其他人一直致力于解决这个问题。他们检查了集群启动日志,其中显示了一个错误:无法运行Kubelet;无法创建证书签名——他们需要确定证书创建的哪个部分失败。SRE研究了网络、资源可用性和证书签名过程。所有这些似乎都运作得很好。上午8点22分,Zara向故障管理系统发布了故障调查摘要,并寻找可以帮助他的开发人员。值得庆幸的是,GKE有一位on-call开发人员可以在紧急情况下提供协助。开发人员Victoria加入了该频道。他要求跟踪错误,并要求团队将问题上报给基础架构的on-call团队。现在是上午8点45分,第一个西雅图SRE,II-Seong来到办公室,轻轻地泡了杯咖啡,为这一天做好了准备。 II-Seong是一名资深的SRE,在故障响应方面拥有多年的经验。当他得知正在发生的故障时,他立即进入故障响应频道。首先,II-Seong根据警报的时间检查当天的发布情况,并确定当天的发布不会导致事故障的发生。然后,他开始整理工作文件,收集笔记。他建议Zara将故障升级为基础架构,云网络和计算引擎团队,以尽可能多地消除这些根源。由于Zara升级,其他人加入了故障响应:

  • GKE节点的开发负责人
  • 云网络值班人员
  • 计算引擎值班人员
  • Herais,另一个西雅图SRE

上午9点10分,故障频道有十几个参与者。故障发生2.5小时,没有找到根本原因,也没有控制住影响。沟通成为了一种挑战。通常情况下,从伦敦到西雅图的on-call交接时间是上午10点,但Zara决定在上午10点之前将故障指挥权移交给II-Seong,因为他对IMAG有更多的经验。作为故障指挥官,II-Seong建立了一个正式的响应组织结构来解决这一事件。然后,他指定Zara为Ops Lead,Herais为通信(Comms)负责人。 Rohit仍然是外部沟通负责人。 Herais立即发送了一封“全体人员齐上阵”的电子邮件给GKE,包括所有开发人员的负责人,并要求专家加入故障响应。到目前为止,故障响应者了解到了以下情况:

  • 当节点试图向主机注册时,集群创建失败。
  • 错误消息表明证书签名模块是罪魁祸首。
  • 欧洲所有集群创建都失败了;其地区都正常。
  • 欧洲没有其他GCP服务出现网络或配额问题。

之后,GKE安全团队成员Puanani加入了这项工作。他注意到证书签发者没有开始。证书签发者试图从DockerHub中提取图像,图像似乎已损坏。Victoria(GKE on-call开发人员)在两个地理位置运行了Docker的图像拉取命令。它在欧洲的集群上运行失败,在美国的集群上成功。这表明欧洲集群是问题的所在。上午9点56分,该团队确定了一个看似合理的根本原因。

因为DockerHub有一个外部依赖,故障控制和故障溯源将特别具有挑战性。对于Docker的工作人员来说,第一个控制故障的方法是快速修复。第二个选择是重新配置集群,从不同的位置获取图像,例如Google容器注册表(GCR),Goole的安全图像托管系统。所有其他依赖项,包括对图像的其他引用,都位于GCR中。 II-Seong指派负责人追查这两种可能。然后,他委派了一个小组去调查失败的集群。讨论对于IRC来说过于密集,因此详细的调试转移到共享文档,IRC成为决策的中心。

对于第二个可能,推送新配置意味着重建二进制文件,这需要大约一个小时。上午10:59,当团队完成90%的重建工作时,他们发现另一个使用错误图像获取路径的位置。作为回应,他们不得不重新启动构建。当IRC的工程师们致力于这两个缓解方案时,SRE中的Tugay有了一个想法。如果他们拦截了Docker的pull请求并使用内部缓存图像替换Docker的响应,那么如何重建配置并将其推出(一个笨重且有风险的过程)呢? GCR有一个镜像可以做到这一点。 Tugay联系了GCR的SRE团队,他们确认团队可以在Docker配置上设置<–registry-mirror =https://mirror.gcr.io>。Tugay开始设置此功能,并发现镜像已经到位!

上午11点29分,Tugay向IRC报告说这些图像是从GCR镜像中拉出来的,而不是DockerHub。上午11点37分,故障指挥官在呼叫GCR值班人员。上午11点59分,GCR值班人员在欧洲存储层清除了腐败的图像。截止到下午12点11分,所有欧洲地区的误差都降至0%。

故障结束了。剩下的只是清理工作,故障文档的整理。在修复之前,CreateCluster在欧洲失败了6小时40分钟。在IRC中,整个事件中出现了41个独立用户,IRC日志扩展到26,000个单词。这项工作在不同的时间分拆了七个IMAG工作组,并且在任何时候都有多达四个同时工作。六支on-call队伍的参与,后期包含28个行动项目。

总结

无论从哪个角度,GKE CreateCluster中断是一件重大故障。让我们探讨一下哪些事情进行得很顺利,哪些事情本可以处理得更好。

什么进展顺利?该团队有几个记录在案的升级路径,熟悉故障响应策略。GKE值班人员 Zara很快就证实了这种影响正在影响实际客户。然后,她使用了一个常用的故障管理系统来通知Rohit,Rohit将故障告知客户。

什么可以更好地处理?该服务本身有一些值得关注的方面。复杂性和对专家的依赖是有问题的。记录对于故障定位来说是不够的,并且团队因为DockerHub上的变化而分散了注意力,而且这不是真正的问题。

故障发生之初,故障指挥官没有制定一个正式的应急预案。虽然Zara承担了这一角色并将对话转移到IRC,但他可以更积极地协调信息和做出决策。结果,少数应急人员在没有协调的情况下进行自己的调查。II-Seong在第一个警报后两小时就建立了正式的故障响应组织。

最后,该故障揭示了GKE灾难准备方面的一个不足:该服务没有任何可以减少用户影响的早期通用预案。通用预案是第一响应者采取的降低影响的操作流程,甚至在完全理解根本原因之前都可以使用。例如,当中断与发布周期相关时,响应者可以回滚最近的版本,或者重新配置负载平衡器以避免错误被本地化时出现区域。值得注意的是,通用预案也有弊端,可能会导致其他服务中断。然而,虽然它们可能具有比精确解决方案更广泛的影响,但是当团队发现并解决根本原因时,它们可以快速到位以停止进一步扩大影响。

让我们再次查看此故障的时间表,看看通用预案可能在哪些方面有效:

  • 上午7点(评估影响)。 Zara确认用户受到中断的影响。
  • 上午9:56(找到可能的原因)。 Puanani和Victoria确定了一个可能的根本原因。
  • 上午10点59分(定制缓解措施)。几个团队成员致力于重建二进制文件以推送一个新配置,该配置将从不同位置获取图像。
  • 上午11:59(找到根本原因并解决问题)。 Tugay和GCR值班人员取消了GCR缓存,并从其欧洲存储层中清除了损坏的图像。

在步骤2(找到可能的原因)之后的通用预案在这里将非常有用。如果响应者在发现问题后将所有发布回滚到已知的良好状态,则故障将在上午10点之前得到缓解。为了缓解故障,不必完全了解详细信息——你只需要知道根本原因的位置即可。能够在完全理解其中断之前缓解中断对于运行具有高可用性的强大服务至关重要。

在这种情况下,响应者可以从某种回滚的工具中受益。通用预案工具确实需要时间来开发。创建通用缓解工具的正确时间是在故障发生之前,而不是在应对紧急情况时。浏览postmortems是一种发现缓解故障的好方法,这些缓解故障在回滚过程中非常有用,并将它们构建到服务中,以便在将来更好地管理故障。

重要的是要记住,第一响应者必须优先考虑通用预案,否则解决问题的时间还会拉的很长。实施通用预案措施(例如回滚)可加快恢复速度并使客户更快乐。最终,客户并不关心你是否完全理解导致中断的原因。他们想要的是停止接收错误。将控制影响作为首要任务,应以下列方式处理积极故障:

  • 评估故障的影响。
  • 减轻影响。
  • 对故障进行根本原因分析。

故障结束后,定位故障的原因并写下事后分析报告。之后,你可以运行故障响应练习演练来修复系统中的漏洞,并且工程师可以在项目中处理这些漏洞。

案例研究3:断电—闪电从未发生过两次……直到它发生

前面的示例表明,如果没有良好的故障响应策略时,会出现什么问题。下一个示例演示了成功管理的事件。当你遵循一个定义良好且清晰的响应协议时,您甚至可以轻松地处理罕见或异常的事件。

背景

电网事件(例如雷击)导致进入数据中心设施的电力变化很大。影响电网的雷击是罕见的,但并不出人意料。Google可以使用备用发电机和电池来防止突发的意外断电,这些设备经过了充分的测试,并且已知可以在这些情况下正常工作。

Google的许多服务器都有大量的磁盘连接到它们,这些磁盘位于服务器上方或下方的一个单独的托盘上。这些托盘有自己的不间断电源(UPS)电池。当停电发生时,备用发电机会启动,但启动需要几分钟时间。在此期间,连接到服务器和磁盘托盘上的备用电池提供电力,直到备用发电机完全运行,从而防止电网事件影响数据中心的运行。

故障

2015年年中,比利时谷歌数据中心附近的电网在两分钟内被闪电击中四次。数据中心的备用发电机被激活,为所有的机器供电。当备份发电机启动时,大多数服务器都使用备用电池运行了几分钟。

磁盘托盘中的UPS电池并没有在第三次和第四次雷击时将电量用在备用电池上,因为雷击间隔太近了。结果,磁盘托盘失去了电力,直到备用发电机开始工作。这些服务器没有断电,但无法访问那些有电的磁盘。

在持久磁盘存储中丢失大量磁盘托盘会导致许多在Google Compute Engine(GCE)上运行的虚拟机(VM)实例出现读写错误。持久磁盘SRE在调用时立即发送了这些错误。一旦持久磁盘SRE团队确定了影响,就会向所有受影响的各方通报故障。持久磁盘SRE on-call人员承担了故障指挥官的角色。

经过利益相关者之间的初步调查和沟通,我们确定:

  • 由于临时断电而丢失磁盘托盘的每台机器都需要重新启动。
  • 在等待重新启动时,一些客户VMs在读取和写入磁盘时出现问题。
  • 任何同时具有磁盘托盘和客户vm的主机都不能在不丢失未受影响的客户vm的情况下“重新启动”。持久磁盘SRE请求GCE SRE将未受影响的vm迁移到其他主机。

持久磁盘SRE的主要值班人员的保留了IC角色,因为该团队对客户影响的可视性最强。

运维团队成员的任务如下:

  • 安全恢复电源,使用电网电源而不是备用发电机。
  • 重新启动所有非vm主机。
  • 协调持久磁盘SRE和GCE SRE,在重新启动之前安全地将vm从受影响的机器移开。

前两个目标被清楚地定义、很好地理解和记录。数据中心运维值班人员立即开始安全恢复电源,定期向IC提供状态报告。持久磁盘SRE定义了重新启动所有机器而不是虚拟机的程序。一个团队成员开始重新启动这些机器。

第三个目标更加模糊,不包括任何现有的程序。故障指挥员指派了一个专门的行动小组成员与GCE SRE和持久磁盘SRE进行协调。这些团队合作将VMs安全地从受影响的机器移开,以便重新启动受影响的机器。IC密切关注着他们的进展,并意识到这项工作需要快速编写新的工具。IC组织了更多的工程师向运维团队报告,以便他们能够创建必要的工具。

沟通负责人观察并询问所有与事件相关的活动,并负责向多个受众报告准确的信息:

  • 公司领导需要关于问题严重程度的信息,并确保问题得到解决。
  • 有存储问题的团队需要知道他们的存储何时可以再次完全可用。
  • 需要主动告知外部客户他们的磁盘在这个云区域的问题。
  • 提交支持票据的特定客户需要知道他们所看到的问题的更多信息,以及关于解决方案和时间安排的建议。

在我们减轻了最初的客户影响之后,我们需要做一些后续工作,例如:

  • 诊断为什么磁盘托盘使用的UPS失败,并确保它不会再次发生。
  • 更换发生故障的数据中心的电池。
  • 手动清除由于同时丢失这么多存储系统而导致的“卡住”操作。

事后分析显示,只有一小部分未写入磁盘——在事故发生期间断电的机器上的等待写入操作。由于持久磁盘快照和所有云存储数据都存储在多个数据中心中以实现冗余,因此只有0.000001%的运行GCE计算机的数据丢失,并且只有运行实例的数据存在风险。

总结

通过及早通报故障,并以明确的领导组织结构有效地处理了这个复杂的故障。

故障指挥官将恢复电源和重启服务器的正常问题委托给了适当的运维负责人。工程师们致力于解决这个问题,并将他们的进展报告给运维主管。

要同时满足GCE和持久磁盘的需求,更复杂的问题需要在多个团队之间进行协调决策和交互。事故指挥员确保从两个小组中指派适当的行动小组成员来处理事故,并直接与他们一起工作,朝着解决问题的方向努力。事故指挥官明智地将注意力集中在事故最重要的方面:尽快解决受影响客户的需求。

案例研究4:PagerDuty事件响应

作者:PagerDuty的Arup Chakrabarti

PagerDuty在几年的时间里开发并完善了内部故障响应实践。最初,配备了一名常设的全公司故障指挥官,并为每个服务配备专门的工程师参与故障响应。随着PagerDuty发展到超过400名员工和几十个工程团队,故障响应过程也发生了变化。每隔几个月都会仔细检查故障响应流程,并更新它们以反映业务需求。所有的经验总结都记录在https://response.pagerduty.com上。我们的故障响应过程并不是一成不变的;它们就像我们的业务一样不断变化和发展。

PagerDuty重大事件响应

通常,小的故障只需要一个值班工程师来响应。当涉及到更大的故障时,我们非常重视团队合作。在高压力和高影响的情况下,工程师不应该感到孤独。我们使用以下技巧来促进团队合作:

参与模拟演习

我们教授团队合作的一个方法是参加“失败星期五”。PagerDuty从Netflix公司的Simian Army(猿人部队)里汲取灵感,制作了这个节目。最初,Failure Friday是一个手动的故障注入练习,目的是了解更多关于我们的系统可能崩溃的方式。今天,我们还使用这个每周练习来重现生产和事件响应场景中的常见问题。

在“失败星期五”开始之前,我们提名一个故障指挥官(通常是一个训练成为IC的人)。在进行故障注入练习时,他们应该表现得像真正的IC一样。在整个演练过程中,主题专家使用与实际事件相同的过程和术语。这种做法既使新值班工程师熟悉事故障响应语言和流程,又为经验丰富的值班工程师提供了一种复习。

玩限时模拟游戏

虽然“失败星期五”练习对工程师在不同角色和过程中培训大有帮助,但它们不能完全复制实际重大事故的紧迫性。我们使用具有时限紧迫性的模拟游戏来捕捉事件响应的这一方面。

“继续说下去,没有人会爆炸”是我们大量使用的一款游戏。它要求玩家在限定时间内共同拆除炸弹。游戏的压力和密集的交流性质迫使玩家有效地合作和有效地协同工作。

从以往的故障中吸取教训

从过去的故障中学习可以帮助我们更好地应对未来的重大故障。为此,我们进行并定期审查故障分析报告。

PagerDuty事后调查过程包括开放式会议和全面记录。通过使这些信息易于访问和发现,我们的目标是减少未来事件的解决时间,或防止未来故障一起发生。

我们还会记录所有涉及重大故障的电话,这样我们就可以从实时通信feed中学习。

让我们看看最近的一个故障,其中PagerDuty不得不利用我们的故障响应流程。故障发生在2017年10月6日,持续时间超过10个小时,但对客户的影响非常小。

  • 下午7:53 PagerDuty SRE团队的一名成员被告知PagerDuty内部NTP服务器正在显示时钟漂移。值班的SRE验证了所有自动恢复操作已经执行,并完成了相关运行手册中的缓解步骤。这个工作记录在SRE团队的专用Slack频道中。
  • 晚上8点20分,PagerDuty软件团队A的一名成员收到了关于他们服务中时钟漂移错误的自动警报。软件团队A和SRE团队致力于解决这个问题。
  • 晚上9点17分,PagerDuty软件团队B的一名成员收到了关于他们服务上时钟漂移错误的自动警报。B组的工程师加入了Slack频道,该频道已经对问题进行了测试和调试
  • 晚上9点49分,值班SRE宣布发生重大故障,并通知值班故障指挥官。
  • 晚上9点55分,IC组建了响应团队,其中包括依赖NTP服务的每个on-call工程师,以及PagerDuty的客户支持。IC让响应小组加入专门的电话会议和Slack频道。

在接下来的8个小时里,响应小组致力于解决和减轻这个问题。当我们运行手册中的程序没有解决问题时,响应团队开始有条理地尝试新的恢复选项。

在这段时间里,我们每四个小时轮换一次on-call工程师和IC。这样做可以鼓励工程师们休息,并为响应团队带来新的想法。

  • 上午5:33,值班的SRE对NTP服务器进行了配置更改。
  • 上午6点13分,IC与他们各自的值班工程师验证所有的服务都恢复了。验证完成后,IC关闭了电话会议和Slack频道,并宣布故障完成。鉴于NTP服务的广泛影响,有必要进行事后分析。在结束故障之前,IC将事后分析分配给值班的SRE小组。

用于故障响应的工具

我们的故障响应流程利用了三个主要工具:

  • PagerDuty。我们将所有值班的信息、服务所有权、事后分析、事件元数据等存储在PagerDuty中。这使我们能够在出现问题时迅速组建正确的团队。
  • Slack。我们保持一个专门的频道(#incident-war-room),作为所有主题专家和故障指挥官的聚会场所。该频道主要用作记录员的信息分类,用于捕获操作、所有者和时间戳。
  • 电话会议

当被要求加入任何故障响应时,on-call的工程师需要拨打一个固定的会议电话号码。我们希望所有的协调决策都在电话会议中做出,而决策结果都记录在Slack中。我们发现这是做出决策的最快方法。我们还会记录每次通话,以确保我们可以重新创建任何时间轴,以防记录员遗漏了重要的细节。

虽然Slack和电话会议是我们的沟通渠道,但你应该使用最适合贵公司及其工程师的沟通方式。

在PagerDuty中,我们如何处理响应直接关系到公司的成功。我们不是毫无准备地面对这些故障,而是通过进行模拟练习,回顾以往的故障,选择合适的工具来帮助我们应对可能发生的任何重大事故障,从而有目的地为故障做准备。

将最佳实践付诸实践

我们见过一些处理得很好的故障的例子,有些则没有。当警报提醒你一个问题的时候,已经来不及考虑如何处理这个故障了。开始考虑故障管理过程的时间是在故障发生之前。那么,在灾难降临之前,你如何准备并将理论付诸实践呢?本节提供了一些建议。

故障响应训练

我们强烈建议培训应急人员来组织故障,这样他们在真正的紧急情况下就有一个模式可以遵循。知道如何组织一个故障,在整个故障中使用共同的语言,并分享相同的期望,可以减少沟通失误的可能性。

完整的故障指挥系统方法可能超出了你的需要,但是你可以通过选择故障管理过程中对你的组织非常重要的部分来开发处理故障的框架。例如:

  • 让接听电话的人知道,他们可以在故障发生时委派和升级。
  • 鼓励采取缓解措施。
  • 定义故障指挥官、通信主管和运维主管角色。 你可以调整和总结你的故障响应框架,并创建一个PPT展示给新的团队成员。我们了解到,当人们能够将故障反应理论与实际场景和具体行动联系起来时,他们更容易接受故障响应训练。因此,一定要包括亲身实践的练习,分享过去发生的故障,分析哪些进展顺利,哪些进展不太顺利。还可以考虑使用专门从事事件响应课程和培训的外部机构。

事先做好准备

除了故障响应训练,它还有助于事先为故障做好准备。使用以下的技巧和策略来做好准备。

确定沟通渠道

事先决定并同意一个通信渠道(Slack, a phone bridge, IRC, HipChat,等等)——没有事故指挥官想在事故发生时做出这样的决定。练习使用它,这样就不会有意外了。如果可能的话,选择一个团队已经熟悉的沟通渠道,这样团队中的每个人都能舒服地使用它。

让利益相关方知情

除非你承认某个事件正在发生并且正在被积极处理,否则人们会自动地认为没有采取任何措施来解决这个问题。同样,如果你在问题减轻或解决后忘记取消响应,人们会认为事件正在发生。你可以通过定期更新状态,在事件发生的整个过程中不断通知受众,从而抢占这种动态。准备一份联系人列表(请参阅下一条提示)可以节省宝贵的时间,确保你不会错过任何人。

提前考虑如何起草、审查、批准和发布公共博客文章或新闻稿。在Google,团队寻求公关团队的指导。另外,为共享信息准备两三个现成的模板,确保值班的人知道如何发送它们。没有人愿意在没有指导原则的极端压力下写这些公告。这些模板使得与公众共享信息变得简单,压力最小。

准备一份联系人列表

事先准备好要发邮件或浏览的人的名单可以节省大量的时间和精力。在第180页的“案例研究2:如果可以的话缓存我”中,通讯主管通过发送电子邮件给预先准备好的GKE列表,发出了一个“全体人员待命”的电话。

建立故障标准

有时很明显,告警问题确实是一个故障。其他时候,情况就不那么清楚了。有一个确定的标准列表来确定一个问题是否确实是一个事件是很有帮助的。一个团队可以通过查看过去的停机情况,并考虑到已知的高风险区域,从而得出一个可靠的标准列表。

综上所述,在应对事件时,建立协调和沟通的共同基础是很重要的。确定沟通事件的方式,你的受众是谁,以及在事件中谁负责。这些指南易于制定,对缩短事件的解决时间有很大的影响。

演练

故障管理过程中的最后一步是实践你的故障管理技能。通过在不太危急的情况下进行练习,你的团队会在闪电袭击时养成良好的习惯和行为模式——无论是比喻意义上还是字面意义上。通过培训介绍了事件响应理论之后,实践可以确保事件响应技能保持新鲜。

有几种方法来进行故障管理演练。Google在全公司范围内运行弹性测试(称为灾难恢复测试,或DiRT;请参阅Kripa Krishnan的文章《抵御意外》(Weathering theUnexpected)。在这篇文章中,我们创建了一个可控的紧急情况,实际上并不影响客户。团队对受控的紧急情况做出反应,就好像这是真正的紧急情况一样。随后,各小组回顾了应急反应程序,并讨论了发生了什么。接受失败作为一种学习的方式,在发现的差距中发现价值,让我们的领导参与进来是成功在Google建立DiRT计划的关键。在较小的范围内,我们使用诸如“不幸之轮”(参见“网络可靠性工程中的灾难角色扮演”)等练习来应对特定事件。

你还可以通过有意地将次要问题视为需要大规模响应的主要问题来练习事件响应。这可以让你的团队在现实世界中使用低风险的过程和工具进行实践。

演练是一个尝试新的故障响应技能的友好方式。团队中任何可能深入到故障响应的人——SREs、开发人员、甚至客户支持和营销合作伙伴——都应该对这些策略感到满意。

要进行演练,可以制造中断并允许你的团队对事件进行响应。你还可以从事后分析中制造中断,其中包含大量事件管理演练的想法。尽可能使用真实的工具来管理事件。考虑破坏你的测试环境,以便团队能够使用现有工具执行真正的故障排除。

如果这些演习是周期性的,那么它们就会有用得多。你可以通过对每次练习进行跟踪,详细列出哪些做得好,哪些做得不好,以及如何更好地处理事情,来让演练产生影响。进行演练最有价值的部分是检查它们的结果,这可以揭示事件管理中的任何漏洞。一旦你知道了它们是什么,你就可以努力关闭它们。

总结

当灾难来临时做好准备。如果你的团队定期实践和更新故障响应过程,那么当不可避免的故障发生时,便不会感到恐慌。

在故障发生前,你需要与同事合作的圈子会随着事件的规模而扩大。当你和你不认识的人一起工作的时候,流程会帮助你建立你需要的快速解决方案的结构。我们强烈建议在未报警前提前建立这些流程。定期回顾并重复你的事件管理计划和剧本。

事故指挥系统是一个简单的概念,很容易理解。它会根据公司的规模和事件的大小进行放大或缩小。虽然理解起来很简单,但实现起来却并不容易,尤其是在突然发生恐慌时。在紧急情况下保持冷静并遵循反应结构需要练习,练习可以建立“肌肉记忆”。这使你对待真正的紧急情况有了信心。

我们强烈建议在你的团队繁忙的日程中抽出一些时间,定期实践事件管理。确保得到领导的支持,让他们有专门的实践时间,并确保他们了解事件响应如何工作,以防你需要让他们参与到真正的事件中。备灾可以从响应时间中节省宝贵的时间或数小时,并使你具有竞争优势。没有任何一家公司总是能把事情做好——从错误中吸取教训,继续前进,下次做得更好。