《DevOps 实战笔记》

DevOps(Development 和 Operations 的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

——维基百科1

DevOps经常被描述为“开发团队与运营团队之间更具协作性、更高效的关系”。由于团队间协作关系的改善,整个组织的效率因此得到提升,伴随频繁变化而来的生产环境的风险也能得到降低。

团队间沟通和协作的重要性一点也不亚于写代码、写文档、做测试之类的常规工作。

如何快速地持续交付高质量的软件,满足用户的多样化需求,并借此提升企业的利润和市场占有率,已经成为企业必须要面对的现实问题。

软件开发过程的改进,除了依赖于技术进步,还依赖于流程、理念、文化等全方位的改进,而这正是 DevOps 带给软件开发方式的一场革命。

DevOps 已经成为了所有 IT 从业人员应知应会的必备技能。

《DevOps 实践指南》2

  • 如何梳理出一套清晰的 DevOps 理念和完整的知识体系?
  • 如何获得一线大厂的实践经验,让 DevOps 真正落地?
  • 如何获得一条渐进式的 DevOps 学习曲线,让自己在正确的方向上不断增值?

基础知识篇

DevOps 的定义、价值、实施与衡量,在最开始帮你建立起正确的 DevOps 体系认知。

软件工程诞生以来所历经的三个重要发展阶

  1. 瀑布式开发模式
  2. 敏捷式开发模式
  3. DevOps 模式



整个软件交付过程中,不仅只有开发和运维,业务也是重要的一环。

DevOps 是通过平台(Platform)、流程(Process)和人(People)的有机整合,以 C(协作)A(自动化)L(精益)M(度量)S(共享)文化为指引,旨在建立一种可以快速交付价值并且具有持续改进能力的现代化 IT 组织。

软件慢慢从企业内部的支撑系统和成本中心,变成了企业服务的直接载体和利润中心。

VUCA 时代

  1. 易变性(Volatility)
  2. 不确定性(Uncertainty)
  3. 复杂性(Complexity)
  4. 模糊性(Ambiguity)

软件交付的效率和质量成了当今企业的核心价值和核心竞争力。

“工业革命消灭了绝大多数的手工业群体,却催生了程序员这个现存最大的手工业群体”。

DevOps 的 4 个结果指标

  1. 部署频率:指应用和服务向生产环境部署代码的频率。
  2. 变更前置时间:指代码从提交到成功运行在生产环境的时长。
  3. 服务恢复时间:指线上应用和服务出现故障到恢复运行的时长。
  4. 变更失败率:指应用和服务在生产环境部署失败或者部署后导致服务降级的比例。

软件交付

  1. 交付效率
  2. 交付质量

高效能的组织不仅做到了高效率,还实现了高质量。

工具和文化

  • DevOps 工具

一切软件交付过程中的手动环节,都是未来可以尝试进行优化的方向。

  • DevOps 文化

在不同的文化制度下,相同的人发挥出来的生产力也会有天壤之别。

DevOps 的 3 个支柱

  1. 人(People)
  2. 流程(Process)
  3. 平台(Platform)

技术采纳生命周期定律


步骤与原则

道法术器 DevOps:

  1. 识别差距
  2. 锚定目标
  3. 关注能力
  4. 持续改进

DevOps 实施的过程

部署引力图

落地实践篇

转型路径

最核心的部分。我将带你通盘梳理 DevOps 的转型路径。

VSM 是 Value Stream Mapping 的缩写,也就是我们常说的价值流图。

VSM 是企业 DevOps 转型的第一步。

《DevOps 实践指南》三步工作法

  • 第一步:流动。 通过工作可视化,限制在制品数量,并注入一系列的工程实践,从而加速从开发到运营的流动过程,实现低风险的发布。
  • 第二步:反馈。 通过注入流动各个过程的反馈能力,使缺陷在第一时间被发现,用户和运营数据第一时间展示,从而提升组织的响应能力。
  • 第三步:持续学习和试验。 没有任何文化和流程是天生完美的,通过团队激励学习分享,将持续改进注入日常工作,使组织不断进步。

通过流程和平台的结合,来驱动流程的自动化流转,这才是 DevOps 的正确姿势。

价值流交付图

价值

  1. 看见全貌
  2. 识别问题
  3. 促进沟通
  4. 驱动度量
  5. 价值展现
VSM

实施 DevOps 的常见路径

  • 自底向上
  • 自顶向下

通用路径

  1. 寻找合适的试点项目
    1. 贴近核心业务
    2. 倾向敏捷业务
    3. 改进意愿优先
  2. 寻找团队痛点
  3. 快速建立初期成功
  4. 快速展示和持续改进

DevOps 转型的 J 型曲线

J

转型小组

敏捷实践

如果业务不够敏捷,IT 再怎么努力也没用

业务敏捷和交付能力二者缺一不可

关于需求分析: 影响地图

"Why-Who-How-What” 分析方法

  • Why 代表目标,它可以是一个核心的业务目标,也可以是一个实际的用户需求。
  • Who 代表影响对象,也就是通过影响谁来实现这个目标。
  • How 代表影响,也就是怎样影响用户以实现我们的目标。
  • What 代表需要交付什么样的功能,可以带来期望的影响。
影响地图

卡诺模型(Kano Model)

卡诺模型(Kano Model)
  1. 兴奋型:指超乎用户想象的需求,是可遇不可求的功能。比如用户想要一个更好的功能手机,乔布斯带来了 iPhone,这会给用户带来极大的满足感。
  2. 期望型:用户的满意度会随着这类需求数量的增多而线性增长,做得越多,效果越好,但难以有质的突破。比如,一个电商平台最开始是卖书,后面逐步扩展到卖电脑、家居用品等多个类别。用户更多的线性需求被满足,满意度自然也会提升。
  3. 必备型:这些是产品必须要有的功能,如果没有的话,会带来非常大的影响。不过有这些功能的话,也没人会夸你做得有多好,比如安全机制和风控机制等。
  4. 无差别型:做了跟没做一样,这就是典型的无用功。比如你花了好大力气做了一个需求,但是几乎没有用户使用,这个需求就属于无差别型。
  5. 反向型:无中生有类需求,实际上根本不具备使用条件,或者用户压根不这么想。这类需求做出来以后,通常会给用户带来很大的困扰,成为被吐槽的对象。

核心要做到 3 点

  1. 优先规划期望型和必备型需求,将其纳入日常的交付迭代中,保持一定的交付节奏;
  2. 识别无差别型和反向型需求,这些对于用户来说并没有产生价值。如果团队对需求的分类有争议,可以进一步开展用户调研和分析。
  3. 追求兴奋型需求,因为它会带来产品的竞争壁垒和差异化。

用户故事拆分粒度,遵循 INVEST 原则

  • Independent(独立的):减少用户故事之间的依赖,可以让用户故事更加灵活地验证和交付,而避免大批量交付对于业务敏捷性而言至关重要。
  • Negotiable(可协商的):用户故事不应该是滴水不漏、行政命令式的,而是要抛出一个场景描述,并在需求沟通阶段不断细化完成。
  • Valuable(有价值的):用户故事是以用户价值为核心的,所以每个故事都是在对用户交付价值,所以要站在用户的视角思考问题,避免像最近特别火的那句话一样:“我不要你觉得,我要我觉得。”
  • Estimatable(可评估的):用户故事应该可以粗略评估工作量,无论是故事点数还是时间,都可以。如果是一个预研性质的故事,则需要进一步深挖可行性,避免不知道为什么做而做。
  • Small(小的):用户故事应该是最小的交付颗粒度,所以按照敏捷开发方式,无论迭代还是看板,都需要在一个交付周期内完成。
  • Testable(可测试的):也就是验收条件,如果没有办法证明需求已经完成,也就没有办法进行验收和交付。

MVP 原则

MVP 原则

BizDevOps

引入业务的 DevOps,就成了 BizDevOps,这也是 DevOps 发展的一种潮流。

核心理念:

  • 对齐业务和开发目标、指标;
  • 把握安全、合规指标;
  • 及时对齐需求,减少无用开发;
  • 体现 DevOps 的价值;
  • 让开发团队开始接触业务,不单单是执行,调动积极性。

精益看板

《改变世界的机器》

加快价值流动是精益看板的核心

精益看板的实践方法

  1. 可视化流程

  2. 定义清晰的规则

    1. 可视化规则
      1. 卡片的颜色
        1. 需求(绿色)
        2. 缺陷(红色)
        3. 改进事项(蓝色)
      2. 卡片的内容
      3. 卡片的依赖和阻塞状态
    2. 显式化规则
  3. 限制在制品数量

    1. 需求流入节点
    2. 需求流出节点
  4. 管理工作流程

    1. 每日站会
    2. 队列填充会议
    3. 发布规划会议
  5. 建立反馈和持续改进

看板

看板创始人 David J Anderson 总结了看板方法的成熟度模型,用于指导中大型团队实践看板方法

kmm

工程实践

配置管理:工程实践基础

  1. 版本变更标准化 Git
    1. 提交概要信息
    2. 提交详细信息
    3. 提交关联需求
  2. 将一切纳入版本控制
    1. 制品管理
    2. 生成物不需要版本控制
  3. 全流程可追溯
  4. 单一可信数据源

分支策略:让研发高效协作的关键要素

git flow

  1. 主干开发,分支发布
  2. 分支开发,主干发布
  3. 主干开发,主干发布

git checkout feature1 && git fetch origin && git rebase -i origin/master

最常见的操作包括:

  1. p:选择提交;
  2. r:更新提交的注释信息;
  3. e:编辑提交,可以将一个提交拆分成多个;
  4. s:压合提交,将多个提交合并成一个;
  5. f:类似压合提交,但是放弃这个提交的注释信息,直接使用合并提交的注释信息;

当然,在 git rebase 的交互界面中,你也可以调整提交的顺序,比如将特性功能和关联的 Bugfix 整合在一起。

持续集成 CI

CI 是 Continuous Integration 的缩写,也就是我们熟悉的持续集成

CI 是一种软件开发实践,团队成员频繁地将他们的工作成果集成到一起(通常每人每天至少提交一次,这样每天就会有多次集成),并且在每次提交后,自动触发运行一次包含自动化验证集的构建任务,以便尽早地发现集成问题。

——马丁·福勒(Martin Fowler)

越是痛苦的事情,就要越频繁地做。

实施 CI 三个阶段

  1. 第一阶段:每次提交触发完整的流水线
    1. 统一的分支策略
    2. 清晰的集成规则
    3. 标准化的资源池
    4. 足够快的反馈周期
  2. 第二阶段:每次流水线触发自动化测试
    1. 匹配合适的测试活动
    2. 树立测试结果的公信度
    3. 提升测试活动的有效性
  3. 第三阶段:出了问题可以在第一时间修复

自动化测试:DevOps的阿克琉斯之踵

自动化测试建设也面临着一些问题

  1. 投入产出比
  2. 上手门槛
  3. 维护成本高
  4. 测试设备投入高

自动化测试的设计

DevOps Handbook

Web 应用

自动化测试的开发

  • cURL
  • Postman
  • JMeter

如果自动化测试覆盖率足够高,那么软件质量一定不会差到哪儿去。

自动化测试结果分析

内建质量:丰田和亚马逊给我们的启示

  1. 问题发现得越早,修复成本就越低;
  2. 质量是每个人的责任,而不是质量团队的责任。

在开发阶段,代码评审和持续集成就是一个非常好的内建质量的实践。

内建质量的实施步骤

  1. 第一步:选择适合的检查类型
  2. 第二步:定义指标并达成一致
    1. 参考值的定义是一门艺术
    2. 静态指标就是固定值
  3. 第三步:建立自动化执行和检查能力
  4. 第四步:定义问题处理方式
  5. 第五步:持续优化和改进

核心目标不是为了通过质量门禁,而是为了质量提升,这才是最重要的。

内建质量的常见问题

技术债务:那些不可忽视的潜在问题

什么是技术债务?

老板拍下来一个紧急需求,要求你在 3 天内开发完成上线。

  • 方案 1:采用分层架构,引入消息队列。这样做的好处是结构清晰,功能解耦,但是需要 1 周的时间;
  • 方案 2:直接在原有代码的基础上修修补补,硬塞进去一块逻辑和页面,这样做需要 2 天时间,还有 1 天时间来测试。

代码维护的时间越长,引入的技术债务就会越多,从而使团队背上沉重的负担。

技术债务长什么样?

  • 一份代码里面定义了一堆全局变量,各个角落都在引用;
  • 一个脚本仓库里面,一大堆名字看起来差不多的脚本,内容也都差不多;
  • 一个函数里面修修补补写了上千行;数据表查询各种神奇的关联;
  • 参数传递纯靠肉眼计算顺序;
  • 因为修改一段代码引发了一系列莫名其妙的问题;
  • ……

七宗罪

为什么要重视技术债务?

  1. 额外的研发成本
  2. 不稳定的产品质量
  3. 难以维护的产品

如何量化技术债务?

目前业界比较常用的开源软件,就是 SonarQube。

解决方法和原则

解决技术债务步骤

  1. 共识
  2. 可见
  3. 止损
  4. 改善

4 条原则

  1. 让技术债务呈良性下降趋势。
  2. 优先解决高频修改的问题。
  3. 在新项目中启动试点。
  4. 技术债务无法被消灭,也不要等到太晚。

优先处理

  • 大量重复代码;
  • 类之间的耦合严重;
  • 方法过于复杂;
  • 条件判断嵌套太多;
  • 缺少必要的异常处理;
  • 多表关联和缺少索引;
  • 代码风险和缺陷;
  • 安全漏洞。

部署实践

环境管理:一切皆代码

环境就成了软件行业的“头号背锅侠”。

环境管理的挑战

  1. 环境种类繁多
  2. 环境复杂性上升
  3. 环境一致性难以保证
  4. 环境交付速度慢
  5. 环境变更难以追溯

基础设施即代码就是用一种描述性的语言,通过文本管理环境配置,并且自动化完成环境配置的方式。

典型的就是以 CAPS 为代表的自动化环境配置管理工具,也就是 Chef、Ansible、Puppet 和 Saltstacks 四个开源工具的首字母缩写。

开发运维打通的 GitOps 实践

开发环境的治理实践

采用基础设施即代码的方法,生成一个包含全部工具依赖的 Docker 镜像,并分发给开发团队。

1
2
3
4
5
FROM  harbor.devops.com:5000/test:ansible 
MAINTAINER XX <xx@devops.com>
ADD ./docker /docker
WORKDIR /docker
RUN export TMPDIR=/var/tmp && ansible-playbook -v -i playbooks/inventories/docker playbooks/docker_container.yml

部署管理:低风险的部署发布策略

部署和发布这两个概念,经常会被混用,但严格来说,部署和发布代表两种不同的实践。

部署 是一组技术实践,表示通过技术手段,将本次开发测试完成的功能实体(比如代码、二进制包、配置文件、数据库等)应用到指定环境的过程,包括开发环境、预发布环境、生产环境等。部署的结果是对服务器进行变更,但是这个变更结果不一定对外可见。

发布,也就是 Release,更偏向一种业务实践,也就是将部署完成的功能正式生效,对用户可见和提供服务的过程。

要在保障一定的质量水平的前提下,尽量加快发布节奏,并通过低风险发布手段,以及线上测试和监控能力,尽早地发现问题,并以一种最简单的手段来快速恢复。

  • 一定的质量水平
  • 低风险发布手段
  • 线上测试和监控
  • 快速恢复

低风险的发布手段

  1. 蓝绿部署
  2. 灰度发布
  3. 暗部署

https://www.gocd.org/2017/07/25/blue-green-deployments.html

线上测试和监控

开源的 GoReplay 工具

  1. 采用灰度发布、用户众测等方式,逐步观察用户行为并收集用户数据,以验证新版本的可用性是否符合预期。
  2. 用户反馈
  3. 使用线上流量测试

快速恢复

混沌工程:软件领域的反脆弱

Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the system’s capability to withstand turbulent conditions in production.

混沌工程是一门在分布式系统上进行实验的学科,目的是建立人们对于复杂系统在生产环境中抵御突发事件的信心。

故障演练就是针对以往发生过的问题进行有针对性地模拟演练。

混沌工程不是为了制造问题,而是为了揭示问题。

混沌工程的原则

  • 建立稳定状态的假设
  • 真实世界的事件
  • 在生产中试验
  • 持续的自动化实验
  • 最小影响范围
参考指标

度量改进

正向度量:如何建立完整的DevOps度量体系?

DevOps 希望做到的就是持续、快速和高质量的价值交付。

指标典型特征

  1. 明确受众
  2. 直指问题
  3. 量化趋势
  4. 充满张力

定义指标原则

  1. 全局指标优于局部指标:过度的局部优化可能对整体产出并无意义,从而偏离了度量的核心,也就是提升交付速度和交付质量。
  2. 综合指标优于单一指标:从单一维度入手会陷入只见树木不见森林的困境,综合指标更加客观。所以,要解决一个问题,就需要一组指标来客观指引。
  3. 结果指标优于过程指标:首先要有结果指标,以结果为导向,以过程为途径,一切过程指标都应该归结到结果指标。
  4. 团队指标优于个人指标:优先考核团队指标而非个人指标,团队共享指标有助于形成内部合力,减少内部的割裂。
  5. 灵活指标优于固化指标:指标的设立是为了有针对性地实施改进,需要考虑业务自身的差异性和改进方向,而非简单粗暴的“一刀切”,并且随着团队能力的上升,指标也需要适当的调整,从而不断挑战团队的能力。

如何开启度量工作?

  1. 第 1 步:细化指标
  2. 第 2 步:收集度量数据
  3. 第 3 步:建立可视化平台
  4. 第 4 步:识别瓶颈并持续改进

指标宜少不宜多,宜精不宜烂

持续改进:PDCA体系和持续改进的意义

核心就是团队已经具备了持续改进的能力,而不只是简简单单地引入了几个工具,建立了几个度量指标而已。

鼓励正向回溯和总结

故障回溯并不一定以确定责任为第一要务,更重要的是,要识别系统流程中的潜在问题和漏洞,并通过后续机制来进行保障,比如增加测试用例、增加产品走查事项等等。

其实,大到线上故障,小到日常错误,都值得回溯和总结。

预留固定时间进行改进

在团队的 Backlog 中新增一类任务,专门用于记录和跟踪这类持续改进的内容。

平台工具篇

涵盖平台建设的 3 个阶段、产品研发和设计、不可忽视的开源工具等,帮你找到快速搭建平台的钥匙。

开源还是自研:企业DevOps平台建设的三个阶段

企业 DevOps 平台建设的三个阶段

阶段一:从无到有

核心原则就是选择主流工具

  • 需求管理工具 Jira;
  • 知识管理工具 Confluence;
  • 版本控制系统 GitLab;
  • 持续集成工具 Jenkins;
  • 代码质量工具 SonarQube;
  • 构建工具 Maven/Gradle;
  • 制品管理 Artifactory/Harbor;
  • 配置管理工具 Ansible;
  • 配置中心 Apollo;
  • 测试工具 RF/Selenium/Appium/Jmeter/TestNG;安
  • 全合规工具 BlackDuck/Fortify;
  • ……

阶段二:从小到大

阶段三:从繁到简

你要提供的不再是一个工具,而是一整套的解决方案;不是解决一个问题,而是解决交付过程中方方面面的问题。

DevOps 核心理念

  1. 标准化:一切皆有规则,一切皆有标准;
  2. 自动化:干掉一切不必要的手工操作环节,能一键完成的,绝不操作两次;
  3. 服务化:面向用户设计,而不是面向专家设计,让每个人都能在没有外界依赖的前提下,完成自己的工作;
  4. 数据化:对数据进行收集、汇总、分析和展示,让客观数据呈现出来,让数据指导持续改进。

产品设计之道:DevOps产品设计的五个层次

持续交付平台:现代流水线必备的十大特征

让数据说话:如何建设企业级数据度量平台?

事前:指标共识

数据本身不会说话,是人们赋予了数据意义,而“这个意义“就是度量指标。

事中:平台建设

挑战一:大量数据源平台对接

插件化:数据采集器

数据采集器

挑战二:海量数据存储分析

  1. 数据量大
  2. 数据结构不统一
  3. 数据访问频
数据度量的架构图

事后:规则落地

平台产品研发

开发策略

研发环境容器化

开发协作流程

图片版
文字版

产品运营策略

团队不仅要做得好,还要善于运营和宣传,而这又是技术团队的一大软肋。

很多事情其实没有没有多难,关键就看有没有想,有没有坚持做。

文字版

团队文化建设

  1. 让专业的人做专业的事情
  2. 抓大放小,适当地忽略细节

开源工具

系统的架构图
系统关系示意图

迈向云端:云原生应用时代的平台思考

Cloud native computing uses an open source software stack to deploy applications as microservices, packaging each part into its own container, and dynamically orchestrating those containers to optimize resource utilization.

云原生使用一种开源软件技术栈来部署微服务应用,将每个组件打包到它自己的容器中,并且通过动态编排来优化资源的利用率。

开源软件、微服务应用、容器化部署和动态编排

  1. 自动化生成依赖的配置文件
    1. Dockerfile:用于生成 Docker 镜像
    2. Jenkinsfile:应用关联的流水线配置
    3. Helm Chart:把应用打包并部署运行在 Kubernetes 上的资源文件
    4. Skaffold:用于在 Kubernetes 中生成 Docker image 的工具
  2. 自动化流水线过程
    1. 流水线即代码
    2. 流水线的抽象和复用
    3. 流水线的条件判断
  3. 自动化多环境部署
  4. 使用云原生流水线
Serverless Jenkins 和 Tekton 的关系示意图

转型案例篇

提到的理论、落地实践和工具融入其中,融会贯通。

微软的 Azure DevOps 平台
爆炸半径

成为DevOps工程师的必备技能


  1. https://zh.wikipedia.org/zh-hans/DevOps↩︎

  2. https://time.geekbang.org/column/intro/235↩︎