写在前面


  • 阿里系列有一本​​《云原生操作系统Kubernetes》​​中作者在前言里讲到
  • Google开源的​​Kubernetes​​​和​​《SRE Google运维解密》​​这本书是剑法和气功的关系
  • 换句话讲​​Kubernetes​​​是术,​​SRE Google运维解密​​是道
  • 作为云原生基础设施的Kubernetes小伙伴么应该多少有些了解
  • 但是对于SRE却很少有人谈及,和小伙伴分享一些SRE的基础知识
  • 博文主要为《SRE Google运维解密》读书笔记整理
  • 主要为第一部分,摘一些感觉重要。

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波


当前云原生是发展趋势,企业服务上云是大势所趋,在某乎上看到有​​Java大军是不是开始卷K8s了​​​之类的话题,但是对K8s的认知,可能仅仅是作为首个CNCF孵化的开源项目,起源于​​Google​​​内部的​​Borg​​​项目,对计算资源进行了更高层次的抽象,作为一个容器编排工具,提供基本的部署、维护以及应用伸缩等功能,其主要实现语言为​​Go语言​​。具体一点常用的资源对象、控制器的使用,声明式API这些

但是对于为什么要定义资源对象,资源控制器定义的标准依据是什么,比如​​RC -> RS -> Deploy​​变迁的原因,很少有人去寻找答案。希望通过对SRE方法论的学习或者说SRE工程师的认识可以深入的理解K8s

SRE 方法论的由来

系统管理员模式

雇佣​​系统管理员(sysadmin)​​​运维复杂的计算机系统,也就是我们俗称的运维岗,是行业内一直以来的普遍做法。系统管理员的日常工作与研发工程师相差甚远,通常分属两个不同的部门:​​研发部(Dev)和运维部(Ops)​​。

传统的​​研发团队和运维团队​​​分歧的焦点主要在​​软件新版本、新配置的变更的发布速度上​​。

  • ​研发部门​​​最关注的是如何能够更快速地​​构建和发布新功能​​。
  • ​运维部门​​​更关注的是如何能在他们​​值班期间避免发生故障​​。

由于绝大部分​​生产故障​​​都是由于​​部署某项变更导致的​​​—不管是部署新版本,还是修改配置,甚至有时只是因为改变了用户的某些行为造成了负载流量的配比变化而导致故障。这两个部门的目标从​​本质上来说是互相矛盾的。​

Google的解决之道:SRE

SRE这种模型是Google尝试着从根本上​​避免产生​​​这种矛盾的结果。SRE团队通过雇佣软件工程师,​​创作软件系统来维护系统运行以替代传统模型中的人工操作​​。

SRE就是让软件工程师来设计一个新型运维团队的结果,​​SRE方法论​​中的主要模块,就是SRE团队的构成。每个SRE团队里基本上有两类工程师。

  • 第一类,团队中50% ~ 60%是标准的软件工程师,符合Google软件工程师标准的一类人
  • 第二类,其他40% ~ 50%则是一些基本满足Google软件工程师标准(具备85% ~ 99%所要求的技能),但是同时具有一定程度的其他技术能力的工程师。

SRE团队成员具有如下特点:

  • 对重复性、手工性的操作有天然的排斥感
  • 有足够的技术能力快速开发出软件系统以替代手工操作

从本质上来说,​​SRE​​​就是在用​​软件工程的思维和方法论完成以前由系统管理员团队手动完成的任务​​。这些SRE倾向于通过设计、构建自动化工具来取代人工操作。

SRE团队的​​终极目标是推动整个系统趋向于无人化运行,而不仅仅是自动化某些人工流程​​。

Google的经验法则是,SRE团队必须将50%的精力花在真实的开发工作上。

SRE模型不仅消除了传统模型中研发团队和运维团队的冲突焦点,反而促进了整个产品部门水平的整体提高。因为SRE团队和研发团队之间的成员可以自由流动,整个产品部门的人员都有机会学习和参与大规模运维部署活动,从中获得平时难以获得的宝贵知识。普通的开发人员有多少机会能将自己的程序同时跑在100万个CPU的分布式系统上呢?

DevOps还是SRE?

我们可以认为​​DevOps是SRE核心理念的普适版​​,可以用于更广范围内的组织结构、管理结构和人员安排。同时,SRE是DevOps模型在Google的具体实践,带有一些特别的扩展。

SRE方法论

一般来说,​​SRE​​​团队要承担以下几类​​职责​​​:​​可用性改进,延迟优化,性能优化,效率优化,变更管理,监控,紧急事务处理以及容量规划与管理。​

我想这也是K8s以及基于K8s生态相关组件做要担负的职责

确保长期关注研发工作

Google将SRE团队的运维工作限制在​​50%以内​​。SRE团队应该将剩余时间花在研发项目上。

SRE处理运维工作的一项准则是:在每​​8~12小时的on-call​​​轮值期间最多只处理两个紧急事件。这个准则保证了on-call工程师有足够的时间跟进紧急事件,这样SRE可以正确地处理故障、恢复服务,并且要​​撰写一份事后报告​​。

​事后总结​​​应该包括以下内容:​​事故发生、发现、解决的全过程,事故的根本原因,预防或者优化的解决方案。Google的一项准则是“对事不对人”,事后总结的目标是尽早发现和堵住漏洞,而不是通过流程去绕过和掩盖它们。​

在保障服务​​SLO​​的前提下最大化迭代速度.

SLO(服务等级目标)指定了服务所提供功能的一种期望状态。SLO 里面应该包含了所有能够描述服务应该提供什么样功能的信息。

​产品研发部门​​​和​​SRE​​​之间可以通过​​消除组织架构冲突​​​来构建良好的合作关系。在SRE模型中,我们选择正面面对这种矛盾,使用的工具是​​错误预算​​。

“错误预算”起源于这样一个理念:任何产品都不是,也不应该做到100%可靠(显然这并不适用于心脏起搏器和防抱死刹车系统等)。一般来说,任何软件系统都不应该一味地追求100%可靠。因为对最终用户来说,99.999%和100%的可用性是没有实质区别的。从最终用户到服务器之间有很多中间系统(用户的笔记本电脑、家庭WiFi、网络提供商和输电线路等),这些系统综合起来可靠性要远低于99.999%。所以,在99.999%和100%之间的区别基本上成为其他系统的噪声。​​就算我们花费巨大精力将系统变为100%可靠也并不能给用户带来任何实质意义上的好处。​

如果​​100%​​​不是一个正确的可靠性目标,那么多少才是呢?这其实并​​不是一个技术问题,而是一个产品问题​​。要回答这个问题,必须考虑以下几个方面:

  • 基于用户的使用习惯,服务可靠性要达到什么程度用户才会满意?
  • 如果这项服务的可靠程度不够,用户是否有其他的替代选择?
  • 服务的可靠程度是否会影响用户对这项服务的使用模式?

通过引进​​“错误预算”​​的概念,我们解决了研发团队和SRE团队之间的组织架构冲突。

SRE团队的目标不再是“零事故运行”,SRE团队和产品研发团队目标一致,都是在保障业务服务可靠性需求的同时尽可能地加快功能上线速度。这个改动虽小,意义却很大​​。一次“生产事故”不再是一件坏事,而仅仅是创新流程中一个不可避免的环节,两个团队通过协作共同管理它。​

某种意义上可以理解为将风险分化,由原来的部分承担,变成了全部承担

监控系统

监控系统是SRE团队监控服务质量和可用性的一个主要手段。

监控系统​​不应该依赖人来分析警报信息,而是应该由系统自动分析​​,仅当需要用户执行某种操作时,才需要通知用户。

一个​​监控系统​​应该只有三类输出。

  • ​紧急警报(alert)​​:意味着收到警报的用户需要立即执行某种操作,目标是解决某种已经发生的问题,或者是避免即将发生的问题。
  • ​工单(ticket)​​:意味着接受工单的用户应该执行某种操作,但是并非立即执行。系统并不能自动解决目前的情况,但是如果一个用户在几天内执行这项操作,系统不会受到任何影响。
  • ​日志(logging)​​:平时没有人需要关注日志信息,但是日志信息依然被收集起来以备调试和事后分析时使用。正确的做法是平时没人会去主动阅读日志,除非有特殊需要。

应急事件处理

​可靠性​​​是​​MTTF(平均失败时间)​​​和​​MTTR(平均恢复时间)​​​的函数。评价一个团队将系统恢复到正常情况的最​​有效指标,就是MTTR​​。

通过事先预案并且将最佳方法记录在“​​运维手册(playbook)​​​”上通常可以使​​MTTR降低3倍以上​​。初期几个万能的工程师的确可以解决生产问题,但是长久看来一个手持“运维宝典”经过多次演习的on-call工程师才是正确之路。

Google SRE将大部分工作重心放在“运维手册”的维护上.

变更管理

​SRE的经验​​​告诉我们,大概70%的生产事故由某种部署的变更而触发。变更管理的最佳实践是​​使用自动化来完成以下几个项目​

  • 采用渐进式发布机制(比如基于K8s的蓝绿部署,​​deplay​​滚动更新)。
  • 迅速而准确地检测到问题的发生。
  • 当出现问题时,安全迅速地回退改动(​​deplay​​升级暂停回滚)。

需求预测和容量规划

​需求预测​​​和​​容量规划​​​简单来说就是​​保障​​​一个业务有足够的​​容量和冗余度​​​去服务​​预测中的未来需求​

一个业务的​​容量规划​​​,不仅仅要包括​​自然增长(随着用户使用量上升,资源用量也上升)​​​,也需要包括一些​​非自然增长的因素(新功能的发布、商业推广,以及其他商业因素在内)​​。

​容量规划​​有几个步骤是必需的:

  • 必须有一个准确的自然增长需求预测模型,需求预测的时间应该超过资源获取的时间。
  • 规划中必须有准确的非自然增长的需求来源的统计。
  • 必须有周期性压力测试,以便准确地将系统原始资源信息与业务容量对应起来。

因为​​服务容量对可用性来说是极为重要​​的,很自然的,SRE应该主导容量规划的过程。同时,这也意味着SRE需要主导资源部署的过程。

资源部署

​资源的部署(provisinging)是变更管理与容量规划的结合物​​。新资源的部署与配置是一个相对比较危险的操作,必须要小心谨慎地执行

效率与性能

​高效地利用各种资源​​是任何赢利性服务都要关心的。因为SRE最终负责容量的部署和配置,因此SRE也必须承担起任何有关利用率的讨论及改进。

因为​​一个服务的利用率指标通常依赖于这个服务的工作方式以及对容量的配置与部署上​​。如果能够通过密切关注一个服务的容量配置策略,进而改进其资源利用率,这可以非常有效地降低系统的总成本。

一个业务​​总体资源​​​的使用情况是由以下几个​​因素驱动​​的:

  • 用户需求(流量)
  • 可用容量
  • 软件的资源使用效率。

SRE可以通过模型预测用户需求,合理部署和配置可用容量,同时可以改进软件以提升资源使用效率。通过这三个因素能够大幅度推动一个服务的效率提升(但是并非全部)

软件系统一般来说在负载上升的时候,会导致延迟升高。延迟升高其实和容量损失是一样的。当负载到达临界线的时候,一个逐渐变慢的系统最终会停止一切服务。换句话说,系统此时的延迟已经是无穷大了。

SRE的目标是​​根据一个预设的延迟目标部署和维护足够的容量。​​SRE和产品研发团队应该共同监控和优化整个系统的性能,这就相当于给服务增加容量和提升效率了。


​Google SRE代表了对行业现存管理大型复杂服务的最佳实践的一个重要突破​​。由一个简单的想法“我是一名软件工程师,这是我如何来应付重复劳动的办法”而生,

SRE模型已经发展成一套指导思想、一套方法论、一套激励方法和一个拥有广阔空间的独立职业。