********本文是BLUES【公众号ID:bluemidou】向老王约稿,特授权blues独家首发,现转载如此,哈哈********
携程事件的官方解释:5月29日1:30分,经携程技术排查,确认此次事件是由于员工错误操作导致。由于携程涉及的业务、应用及服务繁多,验证应用与服务之间的功能是否正常运行,花了较长时间。携程官方网站及APP已于28日23:29全面恢复正常。对用户造成的不便,携程再次深表歉意。
当我看到这个故障结论的时候,我第一个感觉这是一个运维债务的问题,其次我会去想这个故障报告的措施部分怎么写,因此就有了最佳实践的描述,本文完全遵循该思路。
在之前我写了一篇文章【墨菲定律是运维的魔咒】,只要是概率大于零的事件,就有可能发生,支付宝的光缆挖断(具体内部原因不说)、携程的误操作还有我当时的故障经历等都是小概率事件。每个运维人不需要去庆幸这个事情没发生在我们身上,而是思考该如何避免发生?5.28事件应该是给所有技术人员,包括运维人员,甚至是业务部门提了个醒,是该重视运维的时候了,不要把运维当做成本部门来看待,他们一直在为业务产生价值。之后InfoQ高级运维群和其他人也针对该事件,纷纷表达了各自的意见:
我想在此基础上进一步去谈5.28的问题,虽然看起来是某个人为错误操作导致,但深挖下去能够琢磨出很多深层次的原因。如同Martin Fowler所说的技术债务一样,我把此问题归结为【运维债务】,既然是债,迟早都是要还的。那到底什么叫运维债务?运维为追求短期效应(如效率)而选择一个易于实现(如批量脚本)的方案,而没有进行全面衡量和考虑(比如说安全、质量),从长期来看,埋下了消极的隐患(债务)。到底是什么产生了运维债务?运维债务来自于两个方面,技术部门一味的满足业务功能需求、忽略运维需求,匆忙的架构设计,技术无统一规划等等;其次运维部门自身缺乏对技术的全面管理能力而带来的。因此任何谋求从某一个点上去彻底解决这个问题,我觉得都是欠缺的,需要整体性的思考和看待,整体的来看各个方面存在哪些运维债务,然后提出改进方案,才能更有效的规避这个问题再次发生。
一、流程和规范
5.28事件是因为一次误操作而起,但我还是相信这个变更行为是计划中,并且的确是涉及全网变更的。如果是全网变更,一定要引入相应的变更流程,确保有相应的审核机制。并且在缺少平台支撑的情况下,这种流程更需要实现和遵守。在后续就需要把流程实现在运维平台之中,和事务执行跟流程结合在一起。流程引入的一个好处,就是加强大家对变更的重视,提升质量意识。
1.运维债务
2.最佳实践:
二、工具和平台
如果5.28的事件,是运维人员通过批量脚本变更产生的问题,这个问题可以简单一些,必须铲掉那个中控机器,并且严格要求以后禁止使用中控机器来对现网发起变更,和当时我们在腾讯所经历的一样,这种运维能力也就是智锦所说的黑盒运维能力。中控机铲除之后,接下来都会面临一个共性的问题,建立的工具平台如何避免人误操作?此时可以把工具平台的问题分成两个方面,第一工具设计开始是否考虑了对人误操作的保护,避免提供粗粒度的操作能力,提供灰度机制来保护操作,第二,当变更事务失败的时候,是否有回滚能力来保证刚才的操作可回滚的。
第一个工具的灰度能力很容易实现,特别是在可视化工具平台里面建立相应灰度发布机制,轻松容易实现。
第二个工具如何提供回滚的能力,对于应用级的变更来说,回滚能力是核心能力之一,这个时候就依赖于一个完整的版本管理历史,从而方便快速回滚。对于系统层面的变更来说,我们往往会忽视对历史变更记录的保存。所有国外的人把puppet称之为配置管理,它会对所有的配置管理都建立基线和版本管理机制,确保每个操作都是可以回滚的。
回滚有时候还要依赖一份基础信息,那就是服务器上的配置信息库,这个时候可以发挥CMDB的作用,让CMDB管理服务器上的应用状况。
1.运维债务
2.最佳实践
三、安全之权限管理
5.28所暴露出来的一个核心问题就是安全问题,更精确的说是权限管理的问题,一个运维人员拥有那么大的权限对现网发起那么大规模的变更实在有点不合理。
当年进YY的时候,第一件事就是提D/O分离,当时从安全的角度讲了D/O分离的必要性,当我们提D/O分离的时候,要做权限回收,很多研发就说会影响效率。因为当时的情况是研发主导变更,所有的变更脚本都是研发写的。我们当时承诺给建立变更平台来解决效率问题。后来就实现一套完整的应用部署平台,覆盖了YY语音所有业务的部署,并且花了一个Q的情况下,强制业务接入,最终隔绝了开发人员直接登陆服务器操作的过程。
就这个事件本身来说,从支言片语中,我没法去识别具体误操作影响范围,因此也就没法知道具体的权限管理问题。从我个人来说,隔离这种操作影响,把权限管理分成几个方面:
根据不同的用户对象,服务属性和管控要求设定不同的安全区域。从管理对象来说,比如说要设置开发、测试、生产、构建区域等等,这些区域之间的权限彼此隔离,严格禁止SSH互通。
到生产环境,此时根据实际的管控需要,建立核心数据管理区域,对于核心重要的数据集中存放管理。
为了适应发布和变更的需要,需要建立一个发布中控机器,在发布区域构建一个命令和文件下发通道,能够直达到开发、测试、生产和构建服务器等区域,从而建立起版本在各个环境之间的流转。
运维到达生产环境必须是经过明确的实名授权的,无论是LDAP还是堡垒机机制等等,都确保运维的后续操作可追踪和回放。
root登陆权限必须回收(破坏力太大),禁止ssh直接登陆,其次开发应用运行用户权限和只读用户权限(日志查看的需要)。
应用系统运行的属主必须在普通用户下,进一步降低用户对root权限的需求,这属主的权限只能对有限目录开放,禁止权限放大后带来的破坏性后果。
1.运维债务
2.最佳实践
四、灰度机制
我把这个问题单独拿出来说,是因为它太重要了,是腾讯【海量服务运营之道】中的一个篇章。从昨天的故障来看,操作人员应该是没有遵循灰度发布的过程,否则这个故障的影响是可控的。
灰度发布:发布过程不能一蹴而就,是一个逐步渐进式的过程。我把灰度的理解是有两种:一种是运维灰度,基于机器级别,运维的变更和业务的发布经常会使用到;另外一种是基于应用级别,可以基于一些用户的特性,比如说移动的用户、北京的用户才能使用新的功能,这个是应用控制的,非运维变更工具能控制。
可以说灰度是避免运维踩大坑的有效方式,特别是机器灰度。有些场景的确需要运维执行批量变更,而这种变更如果不用灰度过程控制,不可预知的变更后果会覆盖到全网,造成的后果没法预估。
1.运维债务
2.最佳实践
对于业务服务的变更:
五、意识
意识是一个主观的东西,但是是可以被影响到的。其实在早期腾讯的运维经历中,也遇到过这类问题,之后我们不断去形成制度、规范、培训去影响大家的意识,最终其实是让运维对自己的操作形成敬畏之心。记得前不久还有一篇分享讲【对运维操作要有敬畏之心】,其中里面也是讲到微软公有云Azure的一次变更的故障分析过程。但目前互联网运维团队的一个现实情况是:新人的加入和不同企业背景的人加入,会让这种操作敬畏之心被稀释掉。另外互联网的生产环境是最容易触达的,也一定程度上忽略了对它的重视。不像银行,登陆到业务系统需要经过层层控制,堡垒机、单独的操作区、操作审核等等,一定程度上会影响你的操作行为。但我也不建议因噎废食,还是要勇敢前行。
前几天也有朋友说线上有人把rm -rf 目录/*写成了 rm -rf 目录 /*,在目录后多增加了一个空格,结果就把系统干掉了,这种经历在每个公司都碰到过。问我解决方法,我说良好的编程习惯和意识更重要,而非技术手段。一般我们会先cd 到那个目录,然后再删除,类似:cd 目录 && rm -rf *。
一个系统管理员根本没法评估它的一个命令在服务器上产生的影响,因此会产生盲点,忽视了操作带来的后果。另外环境分离之后,我们会逐步缩小SA管理的范围,到最后其实根本不需要专职SA。在之前所在的腾讯部门,根本就没有专职的SA存在,其次业务也逐渐降低了在系统管理上的依赖,最后内核参数的调优都交给了应用上线初始化的时候完成。
1.运维债务
2.最佳实践
六、环境管理
5.28也暴露出环境管理的问题,为什么一个人的权限可以那么大,能够对所有环境进行操作?因此环境的混乱管理带来的是职责不清和安全的问题。
从持续集成的过程分类,你可以分编译、开发、测试和生产环境;从业务架构来说,环境分为:前端程序环境、数据库环境、分布式文件存储环境等等。从持续集成的环境来看,职责很容易界定出来。但是对于线上环境来说,严格禁止环境的混合部署,这个地方很容易出现的声音是分离部署带来的成本提升。不要关注这一点,成本和业务安全和技术架构优化相比,实在算不了什么。
1.运维债务
2.最佳实践
七、数据管理
对运维来说,数据分成两类数据:线上数据管理和运维侧管理数据。数据管理的核心目标是在正常保证服务的情况下确保数据安全,同时为服务异常时提供恢复保障。线上数据管理,往往运维部建立了各类规范和要求,比如说容灾的要求,备份的要求等等,就不说运维,研发也会提相应的需求给到运维。而对于运维自身平台的数据管理,往往就忽略了。如果运维数据的备份、容灾策略没有建设完备的话,运维平台的故障会影响线上服务的恢复效率,甚至是直接影响到服务是否能够恢复。5.28外部传言是删除了数据,我相信这个应该不大可能,因为我一直觉得DBA是非常专业的,一般都会本地备份,然后远程使用hadoop平台备份。其次从权限管理的角度来说,一般DBA的设备是不允许其他人直接操作,而DBA自身很少有批量的指令发到操作系统上,几乎无系统管理的需求。
1.运维债务
2.最佳实践
八、应急机制
在核心的业务保障上面,需要有容灾演练机制,来确定制定的应急预案是否OK,这是对人、系统和流程的全面检验,越真实越好。
在出现重大故障的时候,一定要快速成立故障决策小组,一定要由核心leader组成,最好是总监级别,然后运维总监牵头负责事务的总体跟进,这个应急小组需要对整个故障的处理、跟进、信息周知、资源协调等负责。否则很容易形成等待,底下人不知道做什么,最后就陷入混乱,从而影响故障的时长。因此在真实进入实施之前,核心人员(不宜过多的人)在一起讨论恢复方案,方案确定之后,立马确定负责人,分头实施。
1.运维债务
2.最佳实践
九、架构
这个架构不能深入谈太多,这样会涉及到很多方面。从本质上说,架构的设计是有两个目标的,一个是可运维性;其次是业务的高可用。可运维性,就是架构是否具备可管理性、可移值性、可恢复性等等,而高可用,完全是一个分布式系统的要求,比如说无状态的要求、统一服务调度的要求、柔性可用、过载保护等等。就本次事件问题,我更多的聚焦在可管理性。
可管理性体现在运维对业务技术架构的管理能力上。糟糕的情况是业务研发设计的架构根本就不通知运维同学,从而让运维从一开始就缺少对架构的了解。另外没有设计清晰的分层架构,导致权限管理混乱,从而产生潜在的安全问题,因此会产生如下运维债务问题。
1.运维债务
2.最佳实践
其实这次故障可以说给我们所有人都提了个醒,如果我们出现误操作了怎么办?首先我们先看遗留多少运维债务,从多个方面来看自己需要改进的地方,文章也给出了我自己的一些最佳实践。