一篇文章显得略长,本文对应第5-6章、附录、认证考试、参考资源等。
前言、第1-2章请参考Part 1,第3-4章内容,请参考Part 2。
持续学习与实验的技术实践
通过以下方式制定有关提高安全性、持续改进和边做边学的制度:
- 建立公正的文化,使人们有安全感;
- 通过故障注入的方式,增强生产环境可靠性;
- 将局部发现的经验知识转化成全局提升;
- 预留专门的时间段,用来开展组织性的改进和学习活动。
将学习融入日常工作
可恢复型组织:熟练地发现问题,解决问题,并通过在整个组织中提供解决方案来扩大经验的效果。具有自我愈合的能力。
Chaos Monkey:Netflix首创,通过不断地随机删除生产服务器,来模拟AWS环境故障。不断地将故障注入到预生产和生产环境中,从而实现运维上的恢复性目标。
这一做法后来为业界广泛模仿和参考,并形成一个系统性学科:混沌工程,Chaos engineering,一门对系统进行实验的学科,旨在了解系统对应生产环境的各种混乱状况的能力,建立对系统的信心。
学习型组织是如何思考故障、事故和错误的:将其视为学习的机遇,而不是惩罚的机会。如何通过定期演练和人为模拟故障的方式加速学习。
坏苹果理论:Sidney Dekker博士提出,人为错误并不是问题的原因;恰恰相反,人为错误是提供的工具存在设计问题而造成的后果。
两个有助于创造公正的学习型文化的有效实践:
- 不指责的事后分析;
- 在生产环境中引入受控的人为故障,用于创造机会针对复杂系统中不可避免的问题进行练习。
当事故和重大事件发生时,应该在问题解决后进行不指责的事后分析(对事不对人的事后分析、事后反思)。
应对措施的范例包括:新增能检测部署流水线异常状况的自动化测试,添加更深入的生产环境遥测指标,识别需要额外同行评审的变更类型,以及在定期的演练日里进行针对此类故障的演习。
广泛地公开这些事后分析文档并鼓励组织中的其他人阅读,能增进组织学习。对于提供线上服务的公司来说,针对影响到客户的事故发布事后分析报告也越来越普遍。可显著提高对内部和外部客户的透明度,也反过来增强客户对Google的信任。
Morgue:Etsy公司开发的工具,更加轻松地记录每个事故各方面的细节(如平均恢复时间(MTTR)和严重性),更好地解决时区问题,纳入其他数据(如Markdown富文本、图片、标签和历史记录等)。Morgue的设计宗旨是让团队更加轻松地记录:
- 该问题是由于计划中还是计划外的事件引起的;
- 事后分析会议的负责人;
- 相关IRC聊天日志;
- 相关的JIRA工单,包含纠正措施及其到期时间;
- 到客户论坛帖子的链接(客户在那里对问题发牢骚)。
在复杂系统中工作时,放大微弱的故障信号对于防范灾难性故障是至关重要的。想一想宇宙飞船等系统。
两种典型的组织结构模型:
- 标准化模型:用制度和系统管理一切,包括严格遵守时间表和预算;
- 实验模型:在一种类似于研究和设计的实验室文化中,对每天的每次实验和每条新信息进行评估和辩论。
DevOps必须允许这种创新,并接受因此带来的风险。在生产环境中会遇到更多的失败。但这是一件好事,不应该惩罚。
Game Day:演练日,亚马逊引入的灾难恢复演练。
DiRT:Disaster Recovery Testing,谷歌的灾难恢复计划,参考SRE、CRE。
不指责的事后分析会议和在生产环境中注入故障都强化了这样一种文化:每个人都应该坦然面对失败,承担责任,并从失败中学习。组织唯一的可持续竞争优势就是比对手更快的学习能力。
将局部经验转化为全局改进
在整个组织的全局范围里共享和应用局部获得的新经验和优化方法,从而大大提高组织的全局知识和改进效果。
使用工具自动积累组织知识
ChatOps:最早始于GitHub的技术实践,将自动化工具集成到聊天室的会话中,帮助确立工作透明度和创建工作文档。
Hubot,聊天应用软件,用来在聊天室中和运维团队进行交互。能够触发各种自动化工具:Puppet、Capistrano、Jenkins、Resque(一个Redis维护的、创建后台作业队列的库)和GraphMe(从Graphite生成图形)。
软件中便于重用的自动化、标准化流程
与其将专业知识写到Word文档中,不如将其转化为一种便于执行的形式,提供其易用性。如将其保存在集中的源代码库里,使之成为所有人都可以搜索和使用的工具。
ArchOps机制:将手动操作流程转换为可自动化执行的代码,流程得到广泛采纳,并为所有的使用者提供价值。
创建全组织共享的单一源代码库
在全企业范围内建立共享的源代码库是一种用来整合组织内所有局部发现的强大机制。当源代码库(例如,共享库)中的任意东西更新时,都会被自动地迅速传播给所有调用它的其他服务,并且通过每个团队的部署流水线进行集成。
Google使用单一源代码库,一个优点:每个用户都可以方便地访问到所有最新的代码,不需要进行协调。
保存在共享源代码库里的不仅是代码,还有包含其他学习经验和知识的工件:
- 程序库、基础设施和环境(Chef的配方文件、Puppet类文件等)的配置标准;
- 部署工具;
- 测试标准和工具,包括安全方面;
- 部署流水线工具;
- 监测和分析工具;
- 教程和标准。
运用自动化测试记录和交流实践来传播知识
采用测试驱动开发(TDD)实践,即在编写代码之前编写自动化测试,好处是测试几乎全部自动化。这个原则将测试套件变成活跃、保持更新的系统规范。任何想知道如何使用系统的工程师都可以查看测试套件,找到系统API的可行使用示例。
通过确定非功能性需求来设计运维
当开发部门跟进下游工作、参与生产事故的解决过程时,应用程序的可维护性就会设计得更好。此外,当我们为了适应快速的流动和可部署性,开始谨慎地设计代码和应用程序时,可能会确定一套非功能性需求,并将其集成到所有的生产服务中。
非功能性需求示例:
- 对各种应用和环境进行充分的遥测;
- 准确跟踪依赖关系的能力;
- 具有弹性并能正常降级的服务;
- 各版本之间具有向前和向后的兼容性;
- 归档数据来管理生产数据集的能力;
- 轻松搜索和理解各种服务日志信息的能力;
- 通过多个服务跟踪用户请求的能力;
- 使用功能开关或其他方法实现简便、集中式的运行时配置。
把可重用的运维用户故事纳入开发
如果某些运维工作无法完全自动化或自助化,DevOps的目标是尽量将这种反复发生的工作变得能够重复、确定地执行。
协助自动执行的工作流工具:Rundeck、JIRA、ServiceNow。
确保技术选型有助于实现组织目标
谷歌官方的编译语言(C++)、脚本语言(Python、后来转为Go)和用户界面语言(UI,Java和JS)。尽管也可以通过某些方式支持其他语言,但坚持这三大语言意味着支持程序库、工具,以及更便于找到合作者的方式。”
预留组织学习和改进的时间
改善闪电战(improvement blitz或kaizen blitz)的实践,是丰田生产系统的重要组成部分,指的是在一个专门集中的时间段里解决特定问题,通常长达几天。
DevOp道场:塔吉特公司。
强度最大的是30天挑战:开发团队带着工作进入道场,目标是解决长期困扰他们的内部问题,并取得突破。
道场还提供较低强度的参与模式,如闪速构建,指多个团队在一起参加为期1~3天的活动,目标是在结束时交付最小化可行产品(MVP)或一种能力。
偿还技术债务的制度化惯例
安排和进行为期几天或几周的改善闪电战,让团队里的每个人(或整个组织)自行组织来解决关心的问题——日常工作中遇到的具体问题,不允许进行任何功能性工作。可着眼于代码、环境、架构、工具等的一个问题点。由开发、运维和信息安全工程师组成,横跨整个价值流。
HipHop PHP编译器就是Facebook企业这种实践的一个产物:尝试将PHP代码转换为可编译的C++代码,希望能够大幅度提升现有基础架构的容量。将Facebook所有生产服务从解释型的PHP程序文件转换为编译型的C++二进制文件。HipHop使Facebook的平台能够处理比原生PHP程序高6倍的生产负载。
HHVM:为了进一步提高HipHop编译器性能,并降低它对开发人员生产力的限制。采用即时编译方式的HipHop虚拟机项目,HipHop Virtual Machine。
让所有人教学相长
全美互惠保险公司的学习文化:周四教学,为同伴安排的每周一次的学习时间。
终身学习者,向同行学习。
传播实践的内部顾问和教练
Google的测试认证(Test Certified,TC)提供改进自动化测试实践的路线图。
总结:预留偿还技术债务的时间;创建论坛,使大家能够在组织内部和外部互相学习和指导;通过辅导、咨询,或者仅仅设置一段面谈时间,让专家能够为内部团队提供帮助。
集成信息安全、变更管理和合规性的技术实践
把安全控制整合到开发和运维团队的日常工作中,还要创建更易于审计、能证明控制有效性的流程,以遵从监管义务和合同义务。
将信息安全融入每个人的日常工作
实施DevOps原则和模式的最大阻碍:信息安全和合规性不允许。
DevOpsSec:将信息安全工作集成到软件开发生命周期(SDLC)的各个阶段里。
将安全集成到开发迭代的演示中
让特性团队尽早与信息安全团队协作,而不是等到项目结束阶段才开展相关工作。
GE资本美洲公司企业架构(EA)前首席信息官Snehal Antani曾说,他们的三大关键业务衡量标准:开发速度(即向市场提供功能的速度)、客户交互的故障(即服务中断、报错)和合规响应时间(即从审计提出请求到提供所有必需的定量和定性信息的时间)。
将安全集成到缺陷跟踪和事后分析会议中
DevOps的目标:使用开发和运维团队的问题跟踪系统来管理所有已知的安全问题,以确保安全工作的可视性,以及能够将它与其他工作放到一起来安排优先级。
以前,所有的安全漏洞都存储在只有信息安全人员才能够访问的GRC(治理、风险和合规性)工具中;而现在,我们将把所有要做的工作都放在开发和运维使用的系统中。
将预防性安全控制集成到共享源代码库及共享服务中
目标是为所有现代应用程序或环境提供所需的安全类库或服务,例如启用用户身份验证、授权、密码管理、数据加密等。此外,也可以为开发和运维团队应用程序栈中用到的组件提供安全方面的有效配置:
- 用于日志记录、身份验证和加密;
- 代码库及其推荐的配置[例如,2FA(双因素认证库)、bcrypt密码散列、日志记录];
- 使用Vault、sneaker、Keywhiz、credstash、Trousseau、RedOctober等工具进行秘钥、密码管理(例如连接设置,加密密钥);
- 操作系统软件包和构建(例如,用于时间同步的NTP,正确配置的安全版本的OpenSSL,用于文件完整性监视的OSSEC或Tripwire,用于确保将关键安全性日志都记录到集中式ELK系统里的syslog日志配置)。
将安全集成到部署流水线中
自动化信息安全测试:每当开发或运维人员提交代码时,甚至在软件项目的最早期阶段,在部署流水线中与其他所有测试一起运行安全测试。
Gauntlt:自动化安全测试工具,可集成到部署流水线,使用Gherkin语法格式的测试脚本,可被开发人员广泛地用在单元测试和功能测试中。
保证应用程序的安全性
两种测试:
- Happy Path:愉快路径,开发阶段的测试,关注功能正确性,着眼点是正确的逻辑流程;验证用户的正常操作流程一切都按预期执行,没有例外或出错状况;
- Sad Path:不愉快路径,坏路径,受QA、信息安全人员和欺诈者关注,与事情出错、安全有关。
自动化信息安全测试应该包括:
- 静态分析:从内向外测试,在非运行时环境中执行的测试,期望在部署流水线中进行。静态分析工具将检查程序代码所有可能的运行时行为,并查找编码缺陷、后门和潜在的恶意代码。工具包括Brakeman、Code Climate和搜索禁止代码功能(如exec())。
- 动态分析:从外向内测试,由一系列在程序运行时执行的测试组成。动态测试监视诸如系统内存、功能行为、响应时间和系统整体性能等项目。工具包括Arachni和OWASP ZAP(Zed攻击代理)。有些渗透测试也可以自动执行,而且应该作为Nmap和Metasploit等动态分析工具的一部分使用。理想情况下,自动化动态测试应该在部署流水线的自动化功能测试阶段执行,甚至针对生产环境中的服务执行。为了确保安全性措施的有效性,可以把OWASP ZAP等工具配置为攻击服务的浏览器代理,并在测试工具中检视网络流量。
- 依赖组件扫描:这是另一种静态测试,通常于构建时在部署流水线里执行。它会清点二进制文件和可执行文件依赖的所有包和库,并确保这些依赖组件没有漏洞或恶意二进制文件。Ruby的Gemnasium和bundler审核,Java的Maven以及OWASP依赖性检查就是其中的几个例子。
- 源代码完整性和代码签名:所有开发人员都应该有自己的PGP密钥,可以在诸如keybase.io之类的系统中创建和管理。向VCS中提交的一切都应该签名——使用开放源代码工具gpg和git直接配置。此外,CI创建的所有包都应该签名,并且将其散列值记录在集中式日志记录服务中,为审计所用。
OWASP发布的Cheat Sheet系列:
- 如何存储密码;
- 如何处理忘记的密码;
- 如何处理日志记录;
- 如何防止跨站点脚本(XSS)漏洞。
确保软件供应链的安全
DBIR:Data Breach Investigations Report。Verizon(美国一家电信公司)发布的关于因持卡人数据丢失或被盗而造成数据泄露的最权威意见。
CVSS:Common Vulnerability Scoring System,通用漏洞评分系统。
确保环境的安全
Nmap:Network Mapper,一款用于网络发现和安全审计的网络安全工具,功能很多,如:确保只开放预期端口。
Metasploit:渗透测试工具。
Compliance Masonry:一款原型工具,可将SSP(系统安全计划,System Secure Plan)数据存储为机器可读的YAML文件,然后自动转化为GitBook和PDF格式。
安全遥测系统
除了完善应用程序,还需要在环境中创建全面的遥测系统,以便能够尽早检测未授权访问的迹象,特别是对于运行在非受控基础设施上(例如,托管环境、云端)的组件。
遥测系统的监控指标:
- 生产程序的异常终止:如段错误、内核转储等;
- 数据库语法错误;
- SQL注入攻击的迹象
保护部署流水线
支持CI和CD流程的基础设施,成为易受攻击的新领域。流水线面临的风险包括开发人员引入导致未授权访问的代码(通过代码测试、代码评审和渗透测试等控制措施缓解),以及未经授权的用户获取应用或者环境的访问权限(通过以下控制措施减缓:确保配置始终处于已知和良好的状态,及时有效地打补丁)。
缓解风险的措施:
- 必须减少针对部署流水线的攻击向量
- 加固持续构建和集成服务器,并确保可以用自动化的方式重建它们,就像构建面向客户的生产服务基础架构一样,防止持续构建和集成服务器受到破坏;
- 审查任何提交到VCS的变更——可以在提交时进行结对编程,也可以在提交和主干合并之间设置代码评审流程——从而防止持续集成服务器运行不受控代码(如UT可能包含允许或触发未授权访问的恶意代码);
- 检测包含可疑API调用的测试代码(例如访问文件系统或网络的单元测试)是何时签入到代码库中的,然后可以立即隔离并触发代码审查;
- 确保每个CI流程都运行在自己的隔离容器或虚拟机里;
- 确保CI系统使用的版本控制凭据是只读的。
保护部署流水线
将安全和合规性集成到变更批准流程中。
ITIL将变更分为如下3种类型:
- 标准变更:遵循既定批准流程的低风险变更,但也可以是预批准的。这种类型的变更包括应用程序税表或国家/地区代码的每月更新,网站的内容和样式变更,以及有已知影响的应用或操作系统补丁。变更申请人在部署变更之前是不需要审批的,变更的部署可以完全自动化,而且应该留下用于追溯的日志。
- 常规变更:风险更高、需要权威机构评审或批准的变更。在许多组织中,将审批职责交给变更顾问委员会(CAB)或紧急变更顾问委员会(ECAB)是不太合理的,因为他们可能缺乏理解变更全部影响的必要专业知识,往往导致令人无法忍受的漫长交付周期。对于大规模代码部署而言,这个问题尤为严重。大规模部署可能包含几百名开发人员在几个月的开发过程中提交的数十万(甚至数百万)行代码。为了完成对常规变更的授权,变更顾问委员会几乎肯定会要求提供定义清晰的变更请求单(RFC),为做决策提供所需信息。变更请求单通常包含期望的业务结果、计划的效用和保障、写明风险和规避方案的业务案例,以及建议的时间表。
- 紧急变更:在紧急情况下必须立即投入生产环境的变更(如紧急安全补丁、恢复服务),属于潜在的高风险变更。通常需要得到高级管理层批准,但也允许先执行变更操作,之后补上文档。目标是简化常规变更流程,使其同样适用于紧急变更。
将大量低风险变更重新归类为标准变更。
变更管理系统:Remedy或ServiceNow。
不能归类为标准变更的变更属于常规变更,在部署前至少需要得到变更顾问委员会部分成员的批准。
减少对职责分离的依赖:应避免使用职责分离作为控制手段。选择结对编程、持续检查代码签入和代码审查等措施。
与高绩效DevOps团队相关的所有优势都是脆弱的:即使对于具有高度信任和共同目标的团队而言,实施低信任控制机制也可能让成员陷入挣扎。
附录
DevOps大融合
精益运动
衍生自丰田生产系统(TPS)。TPS包括价值流映射、看板和全面生产维护等。
两个主要原则:
- 坚信前置时间(把原材料转换为成品所需的时间)是提升质量、客户满意度和员工幸福感的最佳预测指标;
- 小批量尺寸是短前置时间的一个最佳预测指标,理论上讲最理想的批量尺寸是单件流(即1×1的流,库存为1,批量尺寸为1)。
敏捷运动
敏捷宣言由17位软件开发领域的顶尖大师编写,目的是掀起一场推广轻量级软件开发方法(如DP和DSDM-动态系统开发方法)的运动,用敏捷替代瀑布式等重量级软件开发过程以及替代统一软件开发过程(RUP)这样的方法论。
关键原则:
- 频繁地交付可工作的软件,交付周期推荐更短
- 小型的、自我激励的团队应工作在高度信任的模式下
- 小批量尺寸
敏捷实践:Scrum、站会。
Velocity大会运动
目的是为IT运维和网站性能调优人员提供一个聚首的机会。
敏捷基础设施运动
将敏捷原则应用于基础设施,而不仅限于应用程序代码。
Patrick Debois创造DevOps这个词。
持续交付运动
持续交付:确保将代码和基础设施始终处于可部署状态的部署流水线,并且确保所有提交到主干的代码都能安全地部署到生产环境里。
丰田套路运动
丰田成功的关键因素是改进工作习惯,并将其植入到组织里每个人的日常工作中。丰田套路建立一种迭代、增量、科学的解决问题的方法,追求共同的企业目标。
精益创业运动
《精益创业:新创企业的成长思维》,基于《四步创业法》和持续部署技术,最小化可行产品(MVP)、构建-度量-学习的循环。
精益用户体验运动
书籍《精益设计:设计团队如何改善用户体验》
Rugged Computing运动
考察软件开发周期晚期进行应用程序和环境安全加固的无效性。
提出Rugged Computing哲学,旨在构建包含稳定性、可扩展性、可用性、生存性、可持续性、安全性、可支持性、可管理性和防御性等的非功能性需求框架。
约束理论和核心的长期冲突
IT的冲突云如下图所示:
约束理论主要讨论核心冲突云(Core Conflict Cloud,C3)。
制造业里核心的长期冲突,即两项业务目标:提高销量,降低成本。
要降低成本,就应该减少库存,以确保资金没有占用在在制品上。在制品指按客户订单生产的但还不能立即发货的产品。
应用精益原则能解决以上冲突,如减小批量尺寸,减少在制品数量,以及缩短和放大反馈回路。
恶性循环列表
《凤凰项目》中描绘的恶性循环如表
交接和队列的危害
队列等待时间会随着交接次数的增加而延长,因为队列是由于交接而产生的。
工业安全误区
几个误区:
- 人为错误是意外和事故最主要且唯一的根源;
- 如果遵守既定的规程,系统就是安全的;
- 安全性可以通过设置权限和防护来提升。保护层次越多,安全性就越高;
- 事故发生的根本原因可通过事故分析来确定;
- 事故调查就是识别事实和原因之间的逻辑和关联关系;
- 安全性总是优先级最高的,不容降低。
误区与真相之间的区别
丰田安灯绳
拉下安灯绳后,汽车生产装配线不是立马就停止,而是给领导层50s的时间去解决问题,50s内没有解决,此条装配线停止。
推荐阅读安灯系统-百度百科。
软件包产品
将复杂的软件包产品分析和解离后纳入VCS。
事后分析会议
猿猴军团
Netflix的Chaos Monkey,逐渐演变成一套全系列工具,称之为Simian Army,可翻译为猿猴军团,用来模拟灾难的不同程度:
- 捣乱大猩猩:模拟整个AWS可用区域(ZA)的故障;
- 捣乱金刚:模拟整个AWS地区(Region)的故障,如北美;
- Latency Monkey:延迟猴子,在其RESTful客户端服务器的通信层人为引入的延迟或停机,以模拟服务降级,并确保相关服务正常工作;
- 一致性猴子:查找并关闭不符合最佳实践的AWS实例(例如,实例不属于任何自动伸缩组,或服务目录中没有值班工程师的电子邮件地址);
- Doctor Monkey:医生猴子,检查每个运行的实例,找到不健康实例,如果负责人未及时修复,就主动关闭实例;
- Janitor Monkey:看门猴子,确保云环境没有混乱和浪费,搜索未使用的资源并处理;
- 安全猴子:一致性猴子的升级版,找到并终止有安全违规或漏洞的实例,如AWS安全组配置错误。
上线时间透明化
Lenny Rachitsky:上线时间透明化的优势:
- 支持的成本下降。因为用户能够自己识别系统里的问题,无需打电话或发电子邮件给支持部门。用户不再需要猜测是本地问题还是全局性问题,并且可以在跟运维抱怨之前更快速地定位问题;
- 在宕机期间能与客户更良性沟通。利用互联网传播的优势而不是电子邮件、电话这种一对一性方式,能实现更好的沟通效果。在客户沟通上更省事,就有更多时间来解决问题;
- 让客户在发生宕机事故时有明确的可寻求帮助的途径,不必再四处搜索论坛、Twitter或博客;
- 信任是所有SaaS应用成功的基石。客户将自己的业务和生计都押宝在你的服务或平台上。现有和潜在的客户都需要信任服务。他们想确保当服务出现问题时自己也有知情权。让他们实时了解意外事件是建立信任的最佳方法,向客户隐瞒实情不再可取;
- 认真负责的SaaS提供商早晚都会提供公开的健康度仪表板,这只是时间问题,因为用户有这样的需求。
参考资源
原书参考很多值得一读(或反复阅读)的经典书籍(或blog、视频等):
- 《凤凰项目:一个IT运维的传奇故事》
- 《精益设计:设计团队如何改善 用户体验》
- 《持续交付:发布可靠软件的系统方法》
认证考试
EXIN DevOps Professional认证
参考Blooms Taxonomy(Revised), 基于布鲁姆分类学修订版进行布鲁姆2级和3级测试:
- 2级:理解——记忆(1级)之上的步骤。理解表明考生能够理解呈现的内容,并能够评估如何将学习资料应用到个人所在的环境中。这类题目旨在证明考生能够整理、对比、说明并选择有关事实和想法的正确描述。
- 3级:应用——表明考生有能力在与学习环境不同的背景下使用所学信息。这类题目旨在证明考生能够以不同的方式或新的方式应用所掌握的知识、实例、方法和规则,在新的情况下解决问题。这类题目通常包含一个简短的场景。
考试规范、基本概念列表、参考文献(考试试题以文献为准,如本书)、样题与解析。