跳转至

L14 SRE本质就是一个懂运维的资深开发

SRE 的 7 项原则

SRE 的七项原则包括

  • Embracing risk 拥抱风险
  • Service level objectives 服务水平目标 SLOs
  • Eliminating toil 消除琐事
  • Monitoring 监控
  • Automation 自动化
  • Release engineering 发布工程
  • Simplicity 简洁性

1. 拥抱风险

SRE 使用可用性指标来衡量停机时间风险的可接受性。在一个指标中,99.99% 的可靠年份将包括 52.6 分钟的停机时间。更复杂的指标会考虑某个位置或服务的一个元素发生停机的可能性,而其他部分仍然正常运行。

2. 服务水平目标 SLOs

确定目标并衡量这些目标的实现程度及其原因对于 SRE 团队至关重要。服务水平目标(SLO)是一种具体且可衡量的目标,代表了 SRE 团队设定的质量标准。这些 SLO 可以以各种指标的形式出现,但可用性、查询速率、错误率和响应时间都是常见的指标

这些目标通过使用服务级别指标(SLI)来衡量,SLI 是对性能的原始测量,例如延迟。

  • 在这种情况下,SLI 就是延迟指标,而 SLO 则是该指标保持在某个阈值以下。
  • SLO 可以成为服务级别协议(SLA)的一部分,SLA 是服务提供商与用户之间的合同,其中列出了 SLO 以及未能达到这些指标的后果。

选择服务级别目标(SLO)可能会有些棘手。理想情况下,SLO 应该围绕用户最关心的内容来构建。例如,对于云游戏服务,SLO 可能会围绕低延迟来构建,但对于会计服务来说,延迟的重要性就没那么高了。

3. 消除琐事

SRE 的创造者们明确将“琐事”定义为一种劳动类别,这种劳动与工作有交集,但并不完全相同。琐事指的是那些按线性扩展的手动工作任务,通常是手动且重复的,往往可以通过自动化来完成。

4. 监控

  • 延迟:最基础的来说,满足一个请求需要多长时间?请注意,这可能会根据请求是否成功而有所不同;有时错误消息的服务时间可能会显著更长。
  • 流量:服务承受了多少负载或需求?具体的单位会有所不同;可能是页面浏览量,可能是交易量,也可能是 HTTP 请求。
  • 错误:通常通过错误率来衡量,错误可能包括获取错误的数据、获取数据的速度比 SLA 中规定的要慢,或者根本无法获取数据
  • 饱和度:本质上,饱和度是衡量服务接近其容量的程度。理解饱和度很重要,因为当服务接近 100%饱和度时,一些服务可能会开始失效、变慢或产生更多的错误。

5. 自动化

就像现代技术中的许多其他元素一样,将自动化引入工作流程的目的是为了使工程师免于处理那些不增加价值的重复性任务。有了新拓展的自由时间,工程师们就可以专注于自动化无法完成的任务:创作、创意、大规模指导以及其他更多工作

  • 一致性:重复的手动任务不仅会让人感到无聊并占用更有价值的时间。如果像用户账户创建这样的任务通过自动化工具完成,错误和不一致性可以几乎被消除。新员工可能会以不同于老员工的方式做事;用户可能会不小心在错误的字段中输入值。而自动化流程(通常情况下)不会出现这种情况。
  • 可扩展性:自动化是可扩展性的一个主要长期优势。以我们之前的用户账户创建为例,如果账户创建量呈指数增长,那么负责账户设置的员工的工作量也会呈指数增长,从而将这名员工从其他可能更有价值的工作中抽离出来。而自动化系统则不会出现这个问题。
  • 速度:某些任务,例如查找和修复代码中的错误,可能需要人工花费大量时间。自动化软件系统能够监控大量数据,并且往往能够通过高级模式识别和其他工具比人类更快地检测到错误。修复工作也可以同样快速地完成,通常不需要任何人工干预

6. 发布工程

  • 自动化和自助服务
  • 速度
  • 封闭构建
  • 标准和政策

7. 简洁性

  • Infrastructure:主要负责最基础的硬件设施,网络,类似于 IaaS,做的事情可参考 DigitalOcean
  • Platform:提供中间件技术,开箱即用的一些服务,类似于 PaaS,做的事情可参考 Heroku,GCP,AWS 等
  • 业务 SRE:维护服务,应用,维护业务的正常运行

1 Infrastructure

Infrastructure 和 Platform SRE 其实可有可无,这些年商业化的服务其实越来越多了,比如,如果公司选择全部在 AWS 部署自己的服务的话,那么就不需要自己建立 Datacenter,维护网络之类的工作了,只需要几个 AWS 专家即可

我觉得 Infrastructure SRE 的工作内容可以这样定义:

  • 负责服务器的采购,预算,CMDB 管理。要知道(能查询到)每一台的负责人是谁,在干什么。这个非常重要,如果做不好,会造成极大的资源浪费。
  • 提供可靠软件的部署环境,一般是虚拟机,或者 bare mental
  • 操作系统的版本统一维护,Linux 发行版的版本,Kernel 的版本等。
  • 维护机器上的基础软件,比如 NTP,监控代理,其他的一些代理。
  • 提供机器的登录方式,权限管理,命令审计。
  • 维护一套可观测性的基础设施,比如监控系统,log 系统,trace 系统。
  • 维护网络,大公司可能都会自己设计机房内的网络。其中包括:
  • 网络的连通,这个是必要的。对于上层用户(Platform SRE)来说,交付的服务应该是任意两个 IP 是可以 ping 通的,即管理好 3 层以下的网络。
    • NAT 服务
    • DNS 服务
    • 防火墙
    • 4 层负载均衡,7层负载均衡
    • CDN
    • 证书管理

2 Platform SRE

Infrastructure SRE 维护的是基础设施,Platform SRE 使用他们提供的基础设施建立软件服务,让公司内的开发者可以使用开箱即用的软件服务,比如 Queue、Cache、定时任务、RPC 服务等等

主要的工作内容有:

  • RPC 服务:让不同的服务可以互相发现并调用
  • 私有云服务
  • 队列服务,比如 Kafka 或者 RabbitMQ
  • 分布式的 cronjob 服务
  • Cache
  • 网关服务:反向代理的配置
  • 对象存储:S3
  • 其他一些数据库:ES,mongo 等等。一般来说,关系型数据库会有 DBA 来运维,但是 NoSQL 或者图数据库一般由 SRE 维护

内部的开发环境:

  • SCM 系统,比如自建的 GitLab
  • CI/CD 系统
  • 镜像系统,比如 Harbor
  • 其他的一些开发工具,比如分布式编译,Sentry 错误管理等等

一些离线计算环境,大数据的服务

3 业务 SRE

有了 Platform SRE 的支持,开发人员写代码就基本上不需要关心部署的问题了。可以专注于开发,使用公司开箱即用的服务。这一层的 SRE 更加贴近于业务,知道业务是怎么运行的,请求是怎么处理的,依赖了哪些组件。如果 X 除了问题,可以有哪些降级策略。参与应用的架构设计,提供技术支持。

主要的工作内容有:

  • 参与系统的设计。比如熔断、降级,扩容等策略。
  • 做压测,了解系统的容量。
  • 做容量规划。
  • 业务侧的 Oncall。

对于一个专业的 SRE 来说,上述技能也不应该有明显的界限,比如说业务 SRE 也需要掌握一些网络技能,Infra SRE 也要写一些代码。很多工具每一个岗位的人都多少用的到,比如 Ansible/Puppet/SaltStack 这种 IT 自动化工具,或者 Grafana/Prometheus 这种监控工具,只有理解才能用的正确

换个角度讲,对于业务 SRE 来说,虽然基本上不会去管理四层以下的网络,但是如果遇到网络问题,能通过已有的工具和权限排查到交换机问题,去找 Infra SRE 帮忙:“请帮我看下 xx IP 到交换机是否有异常,因为 xxx 显示的结果是 xx”,总比 “我怀疑 xx 有网络问题,请帮忙排查下” 要好一些吧?

4 部署服务

部署分成两种:

  • Day 1:将服务部署上线的那一天
  • Day 2+:服务部署之后,还会进行很多更新,升级,配置更改,服务迁移等等

Day 2+ 的工作要做很多次,Day 1 做的很少,在不断的迭代升级之后,还能保证有一个可靠的 Day 1 操作是很难的。换句话说,我们在服务部署之后一直改来改去,还要保证这个服务在一个全新的环境能够可靠的部署起来。

部署环境的硬编码,奇奇怪怪的 work around,都会破坏 Day 1 的可靠性。之前一家公司,扩容一个新机房的过程简直是噩梦,太多的奇怪配置,hardcode,导致踩过无数个坑才能在一个新的机房部署起来全部的服务。

Day2+ 的操作也不简单,主要要关注稳定性。对于重要的变更操作要设计好变更计划,如何做到灰度测试,如果出了问题应该如何回滚,如何保证回滚可以成功(如何测试回滚)等等。

部署的操作最好都是可以追踪的,因为并不是所有会引起问题的操作都会立即引起问题。比如一个操作当时做完没有什么问题,但是过了 1 个月,偶然的重启或者内存达到了某一个指标触发了问题。如果能记录操作的话,我们可以回溯之前做过的变更,方便定位问题。现在一般都用 Git 来追踪部署过程的变更。

5 Oncall

Oncall 简单来说就是要保证线上服务的正常运行。典型的工作流程是:收到告警,检查告警发出的原因,确认线上服务是否有问题,定位到问题,解决问题。

收到告警并不总意味着真正的问题,也有可能告警设置的不合理。告警和监控面板并不是一个静态的配置,它应该是每天都在变化的,时刻在调整的。如果发现没有标志真正线上问题的告警发了出来,就应该修改告警规则。如果发现当前的监控无法快速定位问题,应该调整监控面板,添加或者删除监控指标。业务在发展,请求量在变化,某些阈值也需要不断地调整。

定位问题没有一概而论的方法了,需要根据看到的实时,结合自己的经验,然后做推测,然后使用工具验证自己的推测,然后确定问题的根因。

但是解决问题是可以有方法论的,叫做 SOP(标准操作流程)即:如果出现了这种现象,那么执行那种操作,就可以恢复业务。SOP 文档应该提前制定,并且验证其有效性。

需要注意的是上述定位问题、解决问题并没有顺序关系。一个经常犯的错误是,在出现故障的时候,花了很长时间定位到故障的根因,然后再修复。这样花的时间一般会比较长。正确的做法是先根据现象看现有的 SOP 能否恢复业务。

比如说当前错误只发生在某一个节点上,那么就直接下线这个节点,具体的原因后面再排查。恢复当前的故障永远是第一要务。但是恢复操作也要经过测试,比如猜测可以通过重启解决问题的话,可以先重启一台做测试,而不是一次性将所有服务重启。大部分情况是需要临场分析的,是一个紧张又刺激的过程。

6 制定和交付 SLI/SLO

维护服务等级协议,听起来像是一个非常简单的事情,只要“设定一个可用率”然后去实现它就好了,然而现实的情况并不是。

比如,制定可用率的时候,并不是说我们去“实现4个9”(99.99% 的时间可用)就够了,我们有以下问题要考虑:

  • 如何定义这个可用率?
    • 比如我们以可用率 > 99.9% 为目标,有一个服务部署了 5 个 Zone,那么有一个 Zone 挂了,其余的 Zone 是可用的,那么可用率被破坏了吗?这个可用率是每一个 Zone 的还是所有的 Zone 一起计算的?
  • 可用率计算的最小单位是什么?
    • 如果 1min 内有 50s 没有达到可用率,那么这一分钟算是 down 还是 up?
  • 可用率的周期是怎么计算的?
    • 按照一个月还是一个周?一个周是最近的 7 天还是计算一个自然周?
  • 如何对 SLI 和 SLO 做监控?
    • 如果错误预算即将用完,有什么措施?比如减少发布?如果 SLI 和 SLO 没有达到会怎么样?

7 故障复盘

故障复盘需要有文档记录,包括故障发生的过程,时间线的记录,操作的记录,故障恢复的方法,故障根因的分析,为什么故障会发生的分析。文档应该隐去所有当事人的姓名对公司的所有人公开。很多公司对故障文档设置查看权限,我觉得没什么道理。有些公司的故障复盘甚至对外也是公开的。

故障在复盘的时候应该将当事人的名字用代码替代,可以营造更好的讨论氛围。

不应该要求所有的故障复盘都产生 Action。之前一家的公司的故障复盘上,因为必须给领导一个“交待”,所以每次都会产生一些措施来预防相同的故障再次发生,比如增加审批流程之类的。这很扯,让级别很高的领导审批他自己也看不懂的操作,只能让领导更痛苦,也让操作流程变得又臭又长,最后所有人都会忘记这里为什么会有一个审批,但是又没有人敢删掉。你删掉,出了事情你负责。

8 容量规划

容量规划是一个非常复杂的问题,甚至有一些悖论。容量要提前做好规划,但是容量的规划需要知道业务的扩张速度,扩张速度这种事情又不是提前能计划好的。所以我一直觉得这个事情很难做,也一直没有见过做的很好的例子。

但是至少可以对维护的系统建立一个模型,知道多少机器,多少资源,能容纳多少容量。这样遇到大促之类的活动也能及时估算需要的资源数量

9 用户支持

用户支持也是日常的一部分。包括技术咨询,以及用户要求的线上问题排查。

这里就需要提到文档的重要性了。如果没有维护好文档,那么用户就会一遍又一遍问相同的问题。写文档也是一个技术活,优秀的需要很长时间的积累。文档也需要经常更新。我一般会这样,保持这样一种状态:用户可以不需要任何人就从文档中找到他需要的所有答案。

有关做项目没有专业团队得不到训练

这方面是听到最多的抱怨。虽然说 SRE 在工作上应该是开发时间和运维时间各 50%,但是真实的情况是,即使 SRE 有一些开发工作,也大部分是面向内部用户,面向公司内部的开发者的。大部分项目是一些想法,需要去尝试一下行不行,基本上不会有专业的设计资源,PM 资源。

面试会问什么?

这个仓库是一个不错的面试题集锦:https://github.com/bregman-arie/devops-exercises