最近感觉不太太平,某头部大公司接二连三的出现一些运维相关的生产事件,搞得大家议论纷纷。在运维领域中,有一个奇特的分支,或者说灰色地带,叫做“人肉运维”。其实关于“人肉运维”,只要你不是一毕业就进入大厂的核心团队,一般来说你可能也接触过一些类似的事情。
比如歪师傅之前就职于一家小公司,就经常干人肉运维的事情。小公司的好处就是啥都能让你干点,所以我当时开发也要肩负上线的任务。根本就没有什么灾备、切流的操作,处于系统上线的蛮荒时代,完全没有自动化工具,就是人工登录上服务器滚动更新,也就是传说中的人肉运维。
最常见的操作就是连着生产数据库操作数据。说真的,每次操作的时候自己心里都是哆嗦的,会反复的核验 SQL 是否正确。所以后来公司决定收回开发人员的数据库权限,只运行开发人员保留只读权限的时候我特别支持,第一个上交了我的权限。虽然后面流程上复杂了一点,但是至少自己心里不用哆嗦了。或者说,心里哆嗦的,不只是自己了, DBA 也连着一起哆嗦。
前几天我也看到了一篇关于“人肉运维”的文章,觉得写的很棒,简直就是“现身说法”,所以借此机会分享给大家。
以下是正文:
5 年前,大概是 2018 年 12 月份的一个晚上,我接到数据组同事的消息,要求将 A 用户的磁盘快照共享给 B 用户。我对这个线上运维工作早已轻车熟路,登录线上服务器仅用了 2 分钟就完成了。我继续忙着其他事情,3分钟后,我正要打开新的控制台页面,猛然发现控制台上的“ public = true”。我惊慌地查看磁盘快照状态,发现磁盘快照已经共享给了所有用户。任何用户都可以在自己的快照列表中看到这个快照,并用快照创建新的磁盘,这意味着这些快照数据已经泄露了。
这可是公司重要客户的磁盘数据啊!!!!我心里明白,对于云计算行业,数据安全问题比线上bug还要严重!我立刻就慌了,心脏砰砰的跳,手也开始颤抖。我心里很忐忑,一开始试图偷偷回滚,纠结之后,最终选择告诉了组长。我倒吸一口气,一边进行回滚,一边试图平静的说,“我把刚才的快照共享给了所有租户”。
瞬间,组长瞪大眼睛了看着我,“回滚了吗,赶紧回滚……”。我颤抖地编辑SQL,手都麻木了,心脏还在怦怦跳个不停,开始担心这件事的后果。领导边看我回滚,边小声对我说,“赶紧回滚,下次小心点”,看的出来,组长不想声张,他想先看看影响。
”嗯,好“,我努力嗯了一声,组长没大声骂我,我很感动。本以为回滚了,就没事了。
(后来这家小公司黄了,这是被我干黄的第二家公司,你们干黄了几家?)
然而,这远远没有结束。
原本宁静的办公室突然变得热闹起来,周围的同事们纷纷接到了报警通知。他们“兴高采烈”地讨论着报警的原因,我的注意力也被吸引了过去,听起来似乎与我有关,但我却没有心情去理会他们。最终,快照被共享 5 分钟后,回滚完成,我长舒一口气,心想幸好我多看了一眼控制台,否则不知道被泄露多久。
与此同时,邻居组的成员钱哥找到了我,问道:“刚才快照计费数据暴涨了,你们这边有做过什么操作吗?”随后,邻居组的组长王哥也过来了,询问情况如何。我的组长苦笑着告诉他们:“刚才一个磁盘快照错误地被共享给了所有租户,不过现在已经回滚了。”
邻居组的王哥听后惊愕地说道:“卧槽,谁干的?”他的脸上露出了一丝微笑,似乎是看热闹的微笑。我实在不知道该怎么说了,苦着脸问他们:“计费数据能回滚吗?”邻居组的王哥没有回答我的问题,看了我一眼,说:“我叫上老板,先找个会议室讨论一下吧。”
万幸的是这 5分钟里没有用户使用此快照创建磁盘,这意味快照数据没有发生实质性泄露。
至暗时刻
接下来的两天里,我只做了两件事,参加复盘会议和去会议室的路上。这两天是我人生中最难忘的时刻,我尴尬得连脚丫子都能拧成麻花。我真希望能立刻辞职离开这个地方。“别再鞭尸了,老子不干了,行不行。md,不就是共享个快照嘛!”我的心理状态从忐忑变得暴躁~
后来我开始后悔 ,为什么不早点下班,九点多还帮同事进行高危的线上操作,我图个啥。对,我图个啥。我脑子被驴踢了,才提出这个人肉运维方案,一周运维十几次,自己坑自己……
背景
2 个月前,组长接到一个大客户需求,要求在两个租户之间共享云磁盘数据,当时提出很多个方案,其中包括分布式存储系统提供工具共享两个云磁盘数据等非常复杂的方案。我当时听到这个需求,就立马想到,我们的云管理系统可以实现两个租户的资源共享啊,通过给云磁盘打快照、共享快照等,就实现两个云磁盘的数据共享。
当时我非常得意,虽然我对存储并不是很了解,但是我相信我的方案比存储团队的底层方案更加简单且可行性更高。经过与客户的沟通,确定了这个方案能够满足他们的诉求,于是我们定下了这个方案。由于大客户要的比较急,我改了代码就急匆匆上线,这个需求甚至没有产品参与,当客户需要共享数据时,需要我构造请求参数,在线上服务器上命令行执行共享操作。
第一版方案在线上验证非常顺利,客户对这样快速的交付速度非常满意。因为我们使用了开源的框架,资源共享能力是现成的,所以改动起来很快。只不过有一个核弹级 feature,我忽略了它的风险。public = true 时,资源将共享给全部用户。
“只要不设置这个参数就不会有什么问题。”这是我的想法,我没有考虑误操作的可能,更没有想到自己会犯下这个错误。本以为只是低频的一次性操作,没想到后来客户经常性使用。我不得不一次次在线上执行高危操作,刚开始我非常小心谨慎,仔细的检查每个参数,反复确认后才执行命令。
然而,后来我感到这个工作太过枯燥乏味,于是开始集中处理,一次性执行一批操作。随着时间的推移,我越来越熟悉这件事。这种运维操作我两分钟就能完成……之所以这么快,是因为我不再仔细检查参数,只是机械地构造参数,随手执行。正是我松懈的态度导致闯下了大祸,在那个日常性加班的晚上。
后来我开始反思,从需求提出到故障发生前,我有哪些做的不对的地方。我认为有如下问题:
1.技术方案不能仅限于提供基本的资源共享能力,还要提供可视页面,提供产品化能力。
2.高危接口,一定要严格隔离成单独的接口,不能和其他接口混合在一起,即使功能类似
3.线上重要操作要提供审核能力!或者有double check 的机制!
深刻的反思
任何工作都是有风险的,尤其是程序员无时无刻都在担心发生线上问题,如果不学会保护自己,那么多干一件事就多增加很多风险,增加背锅的风险。拿我来说,本来这个需求不需要我参与,我提出了一个更简单的方案,高效的响应了大客户需求,是给自己长脸的事情。然而,我犯了一个巨大的错误,之前所做的努力都付之一炬。大领导根本不知道我提出的方案更简洁高效,他只认为我办事不可靠。在复盘会议上,我给大领导留下了非常糟糕的印象。
话说回来,在这个事情上如何保护自己呢?
技术方案一定要避免人肉运维,对于高危运维操作要求产品提供可视化页面运维。一定要尽全力争取,虽然很多时候,因为排期不足,前端资源不足等原因无法做到。
如果没有运维页面,等基础能力上线后,继续寻求组长帮助,协调产品提供操作页面,避免一直依赖自己人肉运维去执行高危操作。
在还没有产品化之前,要求客户或上游同事将所有的需求整理到文档上,使用文档进行沟通交流,记录自己的工作量,留存一份自己的“苦劳”。
在低频操作,变为高频操作时,不应该压迫自己更加“高效运维”,而是将压力和风险再次传达给产品和组长,让他们意识到我的人肉运维存在极大危险,需要要尽快提供产品化能力。让他们明白:“如果不尽快排期,他们也会承担风险!”
任何时候,对于线上高危操作,一定要小心谨慎。万万不可麻痹大意!
总之,千万不要独自承担所有的压力和风险。在工作中,我们可以付出辛勤努力,承受一定的风险,但是必须得到相应的回报。(风浪越大,鱼越贵。但是如果大风大浪,鱼还是很便宜,就不要出海了!风险收益要对等)
就这个事情来说,每天我都要执行高风险的运维操作,是一种辛苦而不太受重视的工作。尽管如此,我却必须承担着巨大的风险,并自愿地让自己不断追求更高效的人工运维方式。然而结果却让人啼笑皆非,我终究翻车了。实在是可笑。(挣着卖白菜的钱,操着卖白粉的心,这是我的真实写照。)
吾日三省吾身、这事能不能不干、这事能不能明天干、这事能不能推给别人干。程序员不善于沟通,往往通过加班、忍一忍等方式默默地承担了很多苦活、脏活、累活。但是我们要明白,苦活可以,脏活等高风险的活 千万不要自己扛。你干好十件事不一定传到大领导耳朵里,但是你出了一次线上大事故,他肯定第一时间知道。
好事不出门,坏事传千里。我们一定要对高危的人工运维,勇敢说不!
好了,本文就到这里啦。