公有云故障案例分析——Microsoft Azure 的飞来人祸

阅读数:2833 2015 年 4 月 9 日

话题:微软AzureDevOps语言 & 开发架构

公有云早已飞入寻常百姓家,除了初创的企业,很多大公司也将自己的服务部署在共有云平台上,因此公有云的稳定性和可靠性是十分重要的。平日里谈起公有云,大家总把注意力放在行业老大 Amazon Web Services 上,不太提及 Microsoft Azure,今天就让我们来看一下去年 11 月 Azure 发生的将近 11 个小时的故障。

首先,来回顾一下故障的经过,根据《Update on Azure Storage Service Interruption》这篇官方博客的介绍,这起编号为 3071402 的故障名为“Microsoft Azure Service Incident : Connectivity to multiple Azure Services – Partial Service Interruption”,影响了 19 种 Azure 服务,涉及 12 个 Region,当时似乎只有澳大利亚数据中心幸免于难。

从 11 月 19 日 00:50 发现该问题后的 5 个小时中,多个主要 Region 的存储服务出现问题,大量客户在此之间受到影响;上午 11 点存储故障恢复,大部分客户服务已经恢复,但少数客户的虚拟机由于此前的故障仍存在问题,自动恢复一直持续到 21 日早晨。

讽刺的是多个微软自己的服务也受到了牵连,Windows Store 和 Xbox Live 都受到不同程度的影响。而 Azure 的 Service Health Dashboard 也受故障影响,在故障发生之初尽然显示一切正常,Azure 也真是“醉”了。

一个月后,Azure 团队在其官方博客上就此次故障发表了详细的说明——《Final Root Cause Analysis and Improvement Areas: Nov 18 Azure Storage Service Interruption》,文中剖析了造成故障的原因。本次变更主要是针对 Azure Storage Table Front-Ends 的,目的是减少 CPU 开销,提升存储服务的性能。在测试和预生产环境中,本次变更顺利地通过了健康检查,同时显著提升了系统性能,还解决了几个已知的问题。但是在后续的增量部署中,不幸发生了,Azure Blob Storage Front-Ends 错误地开启了该功能,触发了一个 Bug,导致系统进入死循环无法再提供服务了。几分钟后,监控发现问题,工程师团队在 30 分钟内回滚了 Azure Blob Storage Front-Ends 的变更,对于已经进入死循环的系统进行了重启。

存储系统的故障还影响了虚拟机服务,主要可以将问题归纳为三类,都发生在存储故障和故障恢复阶段:

  1. 磁盘挂载超时(大部分虚拟机重启即可恢复)
  2. 虚拟机配置失败(仅影响 Windows 虚拟机,Linux 虚拟机没有问题)
  3. 虚拟网络编程错误(几小时后工程师团队打了补丁,受影响的虚拟机无需重启即可恢复)

如果说代码的 Bug 未在测试中被发现尚情有可原,那么在换一个灯泡都需要将近 50 个工程师参与,流程极为繁琐苛刻的微软,不遵守流程就是不可原谅的了,《Microsoft confirms Azure outage was human error》一文直接就在标题上将其称为“人祸”。

Azure 的部署遵循名为“flighting”的流程,这个流程大致如下:

  1. 在内部测试环境进行部署,随后测试并验证其功能;
  2. 在预生产环境进行部署,在正常的生产级负载下进行测试;
  3. 经过上两步的验证,就能在生产环境中进行小规模部署,一般会部署多个小集群;
  4. 每个小集群都通过验证后就能进行更大规模的增量部署了,通常这种部署在地理上是隔离的。

负责本次性能优化的工程师认为该变更已经在生产环境的小集群上正常运行几个星期了,应该没有问题,在整个 Azure 上开启该功能没有太大风险。而配置工具也没有强制遵循增量部署变更的策略,导致该变更被部署到了整个系统上。

所谓没有规矩不成方圆,有了规矩不能贯彻执行也没用,在小公司或者初创团队,避免繁琐的流程的确能够带来很多便捷,但是在大型团队或者一些核心系统中,流程还是必须的。同时,必须还要有系统能够保证流程得以正确执行,人是会犯错的,人是会走捷径的,就像造成本次故障的那位同学,所以才要系统来进行约束。

Hacker News 上围绕 Azure 团队的故障分析展开了讨论,大家都对 Azure 团队的公开透明表示赞赏(其实在 Azure 的官网有个页面专门记录故障,相比某些公司出了问题遮遮掩掩,这种做法显然更受欢迎),同时不少人也在关心造成这次故障的那位同学的命运,一位读者引用了 IBM 的 Thomas Watson 的话:

最近有人问我会不会开除那个给公司造成 60 万美元损失的员工,我说不会,我刚花了 60 万美元培训了他,为什么要让别人来坐享他的经验?

曾经在支付宝的运维团队也有位朋友这么告诉我——“对运维操作要有敬畏之心”,这句话一直被我记在心中,相信他一定是在背了重大故障之后才会有此感悟。估计 Azure 的那位同学后续一定在操作时会更加仔细,遵循规范。

不知各位读者在了解了 Azure 的这次故障后,是否也能有所收获,当然,如果您在工作中也有过类似的经验教训,不妨也和大家分享一下吧。