扫码阅读
手机扫码阅读

运维进化的冷思考

416 2023-07-15

站在运维的全局视角,提出了4个问题作为我们讨论的主线。

Q1:一个普通个体能在多大程度上破坏系统?

说到“破坏系统”这档子事,历史上可以追溯到《西游记》,你是否还记得孙悟空大闹地府,硬生生把阎王爷的“地狱数据库”(Hell-DBMS),其实就是生死簿,改的面目全非的故事吧。

话说那孙猴子拿起大笔就把自己的名字,还有他的那些猴孙们的名字一起划了,以此避免了生老病死的轮回。很显然,这个地狱数据库显然是没有做过任何备份,从头到尾就那么一份,删了之后就再也回不去了。当然,这个只是我的一个玩笑。

那么在今天,一个普通个体,能在多大程度上破坏系统?

先说我的观点:在信息时代,一个普通人完全可以摧毁一个系统。是的,你没有听错。这种事情在信息时代以前,是很难想象的。

在人类历史上,一个个体决定一个民族,一个朝代历史走向的事情,也不是没有发生过,但必须是那些位高权重的大人物,你有没有听过,两个普通人聊着聊着,就把人类文明和外星文明都改写的事吧。

听起来很荒唐,但是这样的事情就发生在了刘慈欣的《三体》小说中,地球人叶文洁和三体人1379都是各自世界中的小人物,叶文洁处于对人类的失望,1379处于对生活的失望,在双方建立了联系后改变了人类世界与三体世界在接下来几百年中的命运。虽然这只是小说中所描绘的场景,但是所有的逻辑都是自洽的,就连霍金在接受采访时也表达了相同的观点。

回到运维和DevOps,你有没有发现,现在很多互联网产品运维人员的权限其实是很大的,有时候大到可以直接摧毁一个系统,这种现象在一些B轮或者C轮的企业中尤为普遍,我们先不谈运维人员是否会处于恶意故意破坏自己的系统,但是忙着中出错的概率还是不小的。Gitlab.com的删库其实就是运维人员的误操作导致的,由于过多的终端窗口反复切换,导致原本应该在staging上执行的删库操作实际发生在了生产环境,最终酿成大祸。

所以,这个问题带给我们的启示是,要充分重视个人在系统中可能产生的作用,必须对个人的行为进行严格的监管,避免由个人引发的系统性故障。这也就是为什么大型企业都会建立比较完善的分级和分层发布流程,层层监管和审批,避免个人单点故障的无限放大。当然,这些监管和审批必须要纳入到由技术驱动的DevOps流水线中来完成,而不是靠传统的领导签字来完成。

Q2:“人肉运维”还有多大的生存空间? 

首先解释一下“人肉运维”,我认为那些在生产环境中直接敲命令来完成的各种运维操作都属于人肉运维的范畴。我记得左耳朵耗子就说过“一个公司的运维能力的强弱和你在生产环境敲命令的多少成正比”,运维能力越弱,在生产环境上直接执行各种命令的频次就越高,运维能力越强,人直接和生产环境打交道的机会就越少

所有对生产环境的变更,无论是系统参数、安全策略、网络配置、应用参数、环境参数、文件更新、数据库更新都应该是通过DevOps的流水线走正式的发布上线流程,所有的操作必须是由脚本或者自动化代码来完成,任何个人都不应具有直接在生产环境上执行命令操作的场景。这样做的好处有以下几点:

  1. 发布流程的详细过程可以被记录和回溯;

  2. 发布流程可以被重复,避免操作步骤的遗漏或错误,保证集群中节点状态的一致性,这点对于集群扩容场景非常重要;

  3. 避免生产环境中有人为产生的随机错误;

所以,这个问题的结论显而易见,我们应该尽可能避免任何形式的人肉运维,我们的行为准则是“人管代码,代码管机器”,而不是“人直接管机器”

Q3:运维已经积累了大量实践,为什么依旧举步维艰?

随着软件架构复杂性的不断提升,运维的理念和技术手段也在一直都在不停的演进,从早期的运维,到现在的DevOps,再到日渐完善的AIOps,我们已经积累了大量的经验和最佳实践,但是为什么似乎我们运维人依旧感觉举步维艰。

我认为其中的原因有两个,一个是现在软件架构的发展速度在某种程度上超越了运维自身的发展。你如果回头看一下,运维的技术体系一直在进步,各种CI/CD的工具链,容器技术,自动化部署工具,系统监控方案都在日趋成熟,我们的运维能力的确在不断增强。但是,与此同时,运维的对象也随之变得越来越复杂,无论是依赖关系,还是集群规模都比以往任何时候都复杂,可以说“水涨船高”是现代运维所面临的主要矛盾

另一个原因是,很多运维的最佳实践在实际工作中被“教条化”了,没有达到这些实践设计的初衷。比如为了防止人为的出错,在做一些关键操作的时候,我们往往会有Peer机制(两个人配对相互检查),也会有Checklist机制(自己检查),但是在实际执行过程中,往往是形式主义占了上风,这一点不用我解释你也能心领神会,所以这些机制并没有发挥出应该有的效果。因此我的建议是把这类方法完整嵌入到流水线的执行步骤中去,而不是靠人为的方式来实施。我常说一句话凡是靠人完成的东西都是不靠谱的,要靠技术手段才靠谱

另外,还有一个我认为不太好的实践,在实际工作中为了引起运维工程师的注意,我们会把系统设计成“危机敏感型”的,也就是说有事没事都输出很多告警信息,或者很多一般的操作都让你反复确认是否要执行。比如,你发起某个命令执行某个操作,系统就会先给出告警,然后让你再次输入“Y”来确定是否继续执行,看起来这是一种风险更低和更稳妥的设计,但是实际上这会造成一定的困扰。我们一定都听过“狼来了”的故事,当你每次都觉得这些信息是无关紧要的话,你就会下意识忽略这些信息,那么当真的狼来的时候,你就惨了。这个问题在以前的波音飞机的设计上也遇到过,因此我的建议是只在那些最有必要的操作上才启用这种双重确认的机制

Q4:运维部门是成本中心吗?

在很多人的眼中,运维部门都被归在成本中心,简单来讲就是花钱的部门。运维是成本中心的宿命论对于运维的发展其实是很不利的。如果运维部门长期处于机械性的发布执行和生产环境救火的状态,那么就会陷入无止境的恶性循环。

很多时候,我们总是解决了看得见的问题,但是看不见的问题往往会在看不见的地方聚集,这类问题一旦出现就都是大问题。所以我们需要转变运维是成本中心的思维定式,让运维的同学能够更积极去思考和解决系统性的问题。 

我们一直说有两种类型的待办事项,一种是既重要又紧急的事,也就是运维同学经常面对的各种救火型任务(生产环境Bug fix、Hotfix发布等),另一种是非常重要但是不紧急的事,也就是我常说的未雨绸缪型任务(自动化运维、监控数据分析统计、模型获取与优化等)。理想情况下,应该将更多的时间放在未雨绸缪型任务上,而只将少量的时间放在救火型任务。当把未雨绸缪型任务做好了,那么救火的概率就下降了。但是现实情况正好相反,运维同学天天忙于各种发布,各种线上救火,根本没有精力去偿还各个时期欠下的技术债,这种模式就难逃成本中心的宿命。

关于未雨绸缪型任务,我还想多说两点。

首先,运维部门有必要在平时定期开展一些故障演练的实践,结合混沌工程(Chaos Engineering)的思想,来确保系统的鲁棒性和可维护性,以此来应对各类突如其来的“黑天鹅”事件。这里我想强调“纸上得来终觉浅,绝知此事要躬行”,只有在实际故障演练的过程中,我们才有可能得到很多一手的宝贵实战经验,光靠想是不行的。

其次,对于日常运维中遇到的各类看得见的问题,不能只是关注表面上的解决,而是要有“刨根问底”的精神。这里我强烈推荐《丰田模式:精益制造的14项管理原则》一书中的方法:N个为什么

举个书中的例子,“工厂地上发现一大片油渍。通常的处理方式就是先清理地上的油,最多再检查一下,机器哪个部位漏油,换掉有问题的零件就好了。但是按照丰田的思路,会引导员工继续追问:为什么地上会有油?因为机器漏油了。为什么机器会漏油?因为一个零件老化,磨损严重,导致漏油。为什么零件会磨损严重?因为质量不好。为什么要用质量不好的零件?因为采购成本低。为什么要控制采购成本?因为节省短期成本,是采购部门的绩效考核标准“。当你连续问了N个为什么之后,漏油的根本原因才找到。所以对漏油事件的根本解决方案,其实是改变对采购部门的绩效考核标准,这样才能防止以后发生类似问题。

对于日常的运维工作也是如此,只有这样才能发现和定位那些未雨绸缪型的任务。

好了,我的分享就到这里。困难的路越走越简单,简单的路越走越困难,祝好运!

原文链接: https://mp.weixin.qq.com/s?__biz=MzkzNDM1MDU3Mg==&mid=2247483998&idx=1&sn=188c5efabd8af0effbbda20cce8c3197