跳转至

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

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

  • 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