DevOps的“反人类”实践——从gitlab删库事件浅谈线上系统可靠性的提升

俗话说,天灾可怕,人祸更甚,前两天的gitlab删库曾一度牵动了码界尤其是运维圈的神经,好在gitlab官方开放积极的公关,才让整个事件在肯定中得到平息,关于事故的来龙去脉,我们移步官方声明、知乎和其他同行的分析文章便可清晰还原,所以不再赘述:

https://www.oschina.net/news/81494/gitlab-dot-com-database-incident Gitlab官方对整个数据删除事件的详细说明

https://www.oschina.net/news/81495/gitlab-10-hours-nyancat-video Gitlab的倒霉运维将被罚看 10 小时无聊视频

https://www.zhihu.com/question/55300424?utm_source=weibo&utm_medium=social  【知乎】如何评价 2017 年 2 月 1 日 GitLab 数据库被误删?

平息归平息,从这个事故中反映出来的问题却值得我们引以为戒,随着规模越来越复杂,说到软件系统,我们已经越来越习惯把它归为“人”的问题,因为人类的不确定性,我们一直努力在开发中尽量减少之,而系统运行中用来防御人类破坏的功能更是占了越来越大的比重,也正如整个删库事件一样,人祸成了系统运行中最难预测危害最大的不稳定因素。

“人类是系统可靠性最大的劲敌”也逐渐成了DevOps的教旨,那么基于这点,今天我们就来简单聊一下复杂软件系统可靠性的提升问题,结合这几年在DevOps摸爬滚打的经验,从“决策”“执行”“限制”“反馈”四个不确定性温床中摸索下解决方案。

决策

“机器人不得伤害人类,或因不作为使人类受到伤害。”——阿西莫夫.机器人三定律-1
“除非违背第一定律,机器人必须服从人类的命令。”——阿西莫夫.机器人三定律-2

决策权现在还掌握在不靠谱的人类手里,我们只能先从这里下手。

不要疲劳驾驶

我们姑且不论“8小时工作制”是否真正科学,所有脑力劳动,违背用脑规律甚至使之处于过载疲劳状态,都会显著降低脑部的能量转换效率,大幅增加决策能力的不确定性,虽然针对疲劳的措施,纳入法律的只有“疲劳驾驶”,但疲劳所带来的危害却越来越被人们关注。

这让我想起当年为了尽快上线而挑灯夜战导致脚本出错用rsync –delete干掉一台线上服务器的光荣事迹,而gitlab的删库事件也正是操作员疲劳状态下进行线上操作所酿成的,更令人担心的是,我们的大脑在疲劳的时候更容易放弃思考而轻易得出“这点疲劳碍不啥事”的结论(等同于醉酒),这必须引起警惕,虽然故障并不会选择在我们清醒的时候来光顾,但在此还是要给出我的建议:科学用脑,将时间用在效率最高的地方。

pair

防止单点故障已经是系统运行可靠性老生常谈的手段了,而对于决策者来说,一个搭档,会让决策的不确定性降低至少一半。运维工作的性质导致我们并不能保证故障就要在我们清醒的时候发生,正如pair会让开发人员尽可能的集中注意力,合理搭配双方的高效时间,在进行线上系统重要操作的时候,多一双眼睛盯着,操作失误率会大幅提升——因为我们的pair绝不会是我们的完美复制品,这也是符合“系统多样性带来可靠性提升”的原理。

执行

“除非违背第一及第二定律,机器人必须保护自己。”——阿西莫夫.机器人三定律-3

一个有序体应当与熵战斗,尽可能让自己免受破坏,这是生命体的关键特性。

变化率一致性

这次事故中,损坏丢失的数据并不是git代码主库,而是保存有issue、MR等信息的外挂数据库,为了方便使用版本控制和冲突管理特性而建立在git库基础上的wiki也因此幸免于难。一个完整的workflow要被分割存在于两个变化率不同的容器,让我这洁癖码农始终觉得不大踏实,分割存储不是备份冗余,后者的基础是单点数据完整。

当然在讨论中有朋友有提到,对于频繁数据交换、开关、状态流转,传统db较之git库,有着先天的优势,但将已归档的流式数据合并入git库中来获得一致的数据变化率也不失为一个好办法,所以个人觉得,数据变化率一致性上,还是有关注的必要。

多样化冗余备份

在2017年1月31日23:00 左右 —团队成员1认为, pg_basebackup 拒绝执行是因为 PostgreSQL 的数据目录存在(尽管是空的),于是决定删除该目录。经过一两秒钟,他注意到他运行在 db1.cluster.gitlab.com,而不是 db2.cluster.gitlab.com。

在失去了热备系统的环境下贸然执行危险操作,等同于抛弃了安全带去超速行驶,这种情况下,一块石头就能让人飞出座椅,同样一个简单的rm -rf就能干掉单点主库系统,所以“双机/多机热备”、“本地副本”这些健壮性必备的设施应该始终作为安全带存在,安全带损坏时应该对任何危险操作保持慎重。

而事故升级之后,“5套备份全部失效”应该是此次事故中最闪亮的爆点了吧,乍一看,这个破坏力可谓势不可挡,轻易穿透了5层防御将系统挑于马下。但我们仔细分析官方所说的“5套备份”,却发现从备份类型上却只有一种:冷备份,只是它们使用了不同的参数而已。更不要说为重要数据所建立的“归档数据持久化转储”等业务级备份。

限制

“机器人不得伤害人类整体,或因不作为使人类整体受到伤害。”——阿西莫夫.机器人三定律-0

如有必要,我们应该限制或引导某个异常的决策,使之回到整体有序中。

危险行为限制

人的行为比预想中危险得多,而这个危险通常来自于“人类并不知道这个行为有多危险”和“人类会蓄意执行一个知道有多危险的行为”,所以对危险行为的限制是保证系统可靠性的第一个关口。

这其实是传统运维圈中事实上的门规了:rm、mv、sudo等危险操作应该使用alias等手段严格限制,使用尽量细化的权限认证,禁止直接使用root用户…这些耳熟能详的防御措施在操作系统没有推出专门优化之前,应该是日常运维中必备的check list。

专项工具集

与交付前诸多开发辅助工具同理,既然是自己人,那么破坏系统的行为并不是操作者希望的,为线上危险操作提供一系列具有安全边界的工具,能够有效防止人为不确定性造成的失误和破坏,而持续优化的工具会让决策、操作更加便捷和高效,最常见的业务级后台工具便是很好的例子。

对线上系统逐步建立工具集平台,让线上操作人员工作在安全的受限环境,是智能运维平台的终究要面对的事情,这也是云概念逐渐深入人心的原因之一。

反馈

“黑暗蚀心智,目盲迷此厅”——暗黑3.目盲之书

人的恐惧来源于未知,未知是最大的不确定性,而反馈则是唯一摆脱未知的方法。

服务有效性检测

“在部署的5套备份/复制方法中,没有一套在可靠运行或当初设置正确”,在官方声明中,这句话恐怕是最引人注目的了,为何到事故已经发生的时候才了解到如此低级的错误呢?问题就出在那个最可怕的地方:对错误一无所知。

而直接原因则是,备份服务并没有经过充分测试便上线使用 和 回归测试的缺失,并且,对于这种具有先天惰性的服务,并没有进行定期演练,那么“日本日常地震自救演习大幅提高了生还率”这个看似八杆子打不着的事情用在这里是恰当的。

持续状态报告

在开发环节,我们逐渐认识了QA的重要性和必要性,努力对自己的产出质量进行尽可能多的了解,而同样重要的系统运行质量检测却往往游离在我们的视线之外,这也是开发人员忽略的问题,随着系统越来越复杂,交付后的系统质量并不是一成不变,熵的存在让系统健康度的持续监测变得越来越重要,那么,持续、及时的反馈就变得尤为重要,“日报”、“定期检测报告”、“实时可视化系统”都可以帮助我们获取准确的反馈信息,从而针对异常做出快速反应。

异常行为报警/预警

一个“生命体”能够及时反馈甚至预测危险,是其植物神经最基本的功能,这也是一个“系统”相对于“软件”最关键的区别。所以,针对系统本身的异常行为的及时报警和准确预警,成了系统抵御危险的重要机制,一般我们会更多的关注“安全性”而非“可靠性”,但对于有序体来说,这两者是同一个概念。

对于删库事件中,rm -rf、磁盘容量持续大幅变化等可能影响到系统安全、可靠性的事件,如果能够及时反馈给相关决策者,那么损失可能更容易挽救。

 

然而,说了这么多“反人类”的实践,最后却不得不承认,gitlab正是用了基于“人”的积极公关,才让整个事故的损失降到最低,所以在人类还掌握着处理异常复杂不确定性的优势的时候,我们的工作重点暂时还需要放在“辅助人类高效决策”的方向。

标签: , , , , ,
文章分类 FK Coding, 在路上
1 条评论在 “DevOps的“反人类”实践——从gitlab删库事件浅谈线上系统可靠性的提升” 上
  1. 增达网 说道:

    受教了!呵呵!

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

点赞
如果您觉得很赞,我将非常乐意接受虚拟币的捐赠,以示您对我的肯定。

比特币钱包地址:
1PqpqA8FyH3NbfCrbcRd1YxQk3LEsSEYDV
莱特币钱包地址:
LRTdmovGGVEHCKWz7JdL9aiB7VZkuNycJf
站点勋章
网站统计