做者 | 韩堂、柘远、沉醉
来源 | 阿里巴巴云原生公众号
node
台湾做家林清玄在接受记者采访的时候,如此评价本身 30 多年写做生涯:“第一个十年我才华横溢,‘贼光闪现’,令周边黯然失色;第二个十年,我终于‘宝光现形’,再也不去抢风头,反而与身边的美丽相得益彰;进入第三个十年,繁华落尽见真醇,我进入了‘醇光初现’的阶段,真正体味到了境界之美”。
长夜有穷,真水无香。领略过了 K8s“身在江湖”的那种惊心动魄以及它那生态系统的繁花似锦,该是回过头来体味高可用体系境界之美的时候了。毕竟仅能经得起敲打仍是不能独步武林的!
在 K8s 高可用领域有一个问题被你们所熟知,那就是 K8s 单集群规模带来的 SLO 问题,如何持续保障?今天就以单集群的规模增加带来的高可用挑战来做为引子来给你们一个体感。
ASI 单集群规模支撑超过社区的 5000 台,这是个很是有意思且具有极大挑战的事情,对须要进行 K8s 生产化的同窗,甚至具有 K8s 生产化经验的同窗来讲,必定会是个感兴趣的话题。回看 ASI 单集群规模从 100 到 10000 的发展之路,伴随着业务的增加和创新带来的每一次集群规模增加,都在逐步使咱们的压力和挑战发生质变。
web
ASI:Alibaba Serverless infrastructure,阿里巴巴针对云原生应用设计的统一基础设施,ASI 是阿里公共云服务 ACK 的阿里集团企业版。
你们知道 K8s 社区只可以支撑五千个节点,当超过这个规模时,会出现各类性能瓶颈问题,好比:算法
以电商场景为例,100 节点增加到 4 千节点的时候,咱们提早针对 ASI apiserver 的客户端和服务端作了大量的性能优化,从 apiserver 客户端的角度优先访问本地 cache,在客户端去作负载均衡;apiserver 服务端主要作了 watch 优化和 cache 索引优化;在 etcd 内核上利用并发读提高单 etcd 集群读处理能力,基于 hashmap 的 freelist 管理新算法提升 etcd 存储上限,基于 raft learner 技术来提升多备能力等等。
从 4 千节点增加到 8 千节点,咱们又作了 qps 限流管理和容量管理优化、etcd 单资源对象存储拆分、组件规范全生命周期落地经过客户端的规范约束下降对 apiserver 的压力和以及穿透到 etcd 的压力等等。
终于迎来 8 千节点增加到上万节点的时刻,咱们开始如火如荼地开展 etcdcompact 算法优化;etcd 单节点多 multiboltdb 的架构优化,apiserver 的服务端数据压缩,经过组件治理下降 etcd 写放大等;同时开始打造常态化的压测服务能力,持续回答 ASI 的 SLO。
这些例子在高可用挑战中司空见惯,列出的能力也只是其中一小部分,你也许很难看到能力之间的关联和底层的演进逻辑。固然,更多的能力建设沉淀到了咱们的系统和机制当中。本篇文章会做为一个开始,以综述的形式分享咱们在建设 ASI 全局高可用体系中的几个关键部分,再日后会有针对性地对进行技术点和演进路线的详解。若是你们有什么问题或者但愿了解的部分,欢迎在评论区留言。api
高可用是个比较复杂的命题,任何平常的变化例如服务升级、硬件更新、数据迁移、流量突增等均可能形成服务 SLO 受损,甚至不可用。
ASI 做为容器平台,并不是孤立存在,而是与云底层及公共服务造成完备的生态系统。要解决 ASI 的高可用问题,须要纵观全局,找出每层的最优解,最终串联组成最优的总体解决方案。涉及到的层面包括:
缓存
特别是在 ASI 这个场景下,要支撑的业务集群数量庞大,涉及到的研发运维人员众多,功能发布频繁的迭代开发模式以及业务种类繁多带来的运行时的复杂多变,相比其余容器平台来看,ASI 高可用面临更多的挑战,其难度不言而喻。
安全
以下图所示,现阶段高可用能力建设总体策略以 1-5-10(故障 1 分种发现、5 分钟定位、10 分钟止损)为目标牵引,注重将能力沉淀到系统或机制中,让 SRE/Dev 可以无差异的 oncall。
尽可能避免发生问题、尽快发现、定位及恢复问题,是实现目标的关键,为此咱们将 ASI 全局高可用体系的实现分三大部分展开:一是基础能力建设;二是应急体系建设;三是经过常态化压测以及故障演练等完成上述能力的保鲜和持续演进。
性能优化
经过 3 个部分的轮转驱动,实现一个 ASI 全局高可用体系的构建,其顶层是 SLO 体系和 1-5-10 应急体系。在应急体系和数据驱动的体系背后,咱们建设了大量高可用基础能力,包括防护体系、高可用架构升级、故障自愈体系、以及持续改进机制。与此同时,咱们创建了多个基础性平台为高全用体系提供配套能力,如常态化故障演练平台、全链路仿真压测平台、告警平台、预案中心等等。
架构
在建设全局高可用能力以前,咱们的系统在迅速发展和变化下不断出现事故和险情,须要隔三差五去应急,致使让问题追身的局面,而且追身后没高效应对的手段,面临着几个严峻的挑战:
并发
针对这些问题,而且总结出如下几个核心缘由:
app
针对这些解决的问题,咱们作了高可用基础能力的顶层设计,这些基础能力建设总体主要分为几个部分:
下面针对咱们的一些痛点进行几个关键能力建设的描述。
这里面从两个大的角度能够去提升集群架构的可用性,除了在单集群进行架构优化以及性能突破外,还要经过多集群这样的横向扩展能力去支撑更大的规模。
核心方案就是经过对 apiserver 进行分组,经过不一样的优先级策略进行对待,从而对服务进行差别化 SLO 保障。
经过分流以下降主链路 apiserver 压力(核心诉求)
旁路 apiserver 配合主链路作蓝绿、灰度(次级诉求)
SLB 灾备(次级诉求)
目前张北中心的一个机房就几万节点,若是不解决多集群的管理问题,带来的问题以下:
所以 ASI 须要达成统一的多集群管理解决方案,帮助上层各个 Pass、SRE、应用研发等提供更好的多集群管理能力,经过它来屏蔽多集群的差别、方便的进行多方资源共享。
ASI 选择基于社区联邦 v2 版原本开发知足咱们的需求。
在一个大规模的 K8s 集群中性能会遇到哪些问题呢?
ASI 的性能优化能够从 apiserver 客户端、apiserver 服务端、etcd 存储 3 个方面来进行优化。
在 K8s 中,kube-apiserver 做为统一入口,全部的控制器/client 都围绕 kube-apiserver 在工做,尽管咱们 SRE 经过组件的全生命周期进行规范约束卡点改进,好比经过在组件的启用和集群准入阶段进行了卡点审批,经过各个组件 owner 的全面配合改造后,大量的低级错误获得防范,但仍是有部分控制器或部分行为并不可控。
除了基础设施层面的故障外,业务流量的变化,是形成 K8s 很是不稳定的因素,突发的 pod 建立和删除,若是不加以限制,很容易把 apiserver 打挂。
另外非法的操做或代码 Bug 有可能形成业务 pod 影响,如不合法的 pod 删除。
结合全部风险进行分层设计,逐层进行风险防控。
社区早期采用的限流方式主要经过 inflight 控制读写整体并发量,咱们当时在 apf 没有出来以前就意识到限流能力的不足,没有能力去对请求来源作限流。而 apf 经过 User 来作限流(或者说要先通过 authn filter)存在一些不足,一方面由于Authn 并非廉价的,另一方面它只是将 API Server 的能力按配置来作分配,并非一种限流方案和应急预案。咱们须要紧急提供一种限流能力,以应对紧急状况,自研了 ua limiter 限流能力,并基于 ua limiter 简单的配置方式实现了一套限流管理能力,可以很方便在几百个集群当中进行默认限流管理,以及完成应急限流预案。
下面是咱们自研的 ua limiter 限流方案和其余限流方案的详细对比:
ua limiter、APF、sentinel 在限流上的侧重点是不同的:
考虑咱们现阶段的需求和场景,发现 ua limiter 落地最为合适,由于咱们经过 user agent 的不一样,来对于组件进行限流。固然后续进行更加精细的限流,仍是能够考虑结合使用 APF 等方案进一步增强。
限流策略如何管理,数百套集群,每套集群规模都不太同样,集群节点数、pod 数都是不一样的,内部组件有近百个,每一个组件请求的资源平均有 4 种,对不一样资源又有平均 3 个不一样的动做,若是每一个都作限流,那么规则将会爆炸式增加,即使作收敛后维护成本也很是的高。所以咱们抓最核心的:核心资源 pod\node、核心动做(建立、删除、大查询);最大规模的:daemonset 组件、PV/PVC 资源。并结合线上实际流量分析,梳理出二十条左右的通用限流策略,并将其归入到集群交付流程中实现闭环。
当新的组件接入,咱们也会对其作限流设计,若是比较特殊的,则绑定规则并在集群准入和部署环节自动下发策略,若是出现大量的限流状况,也会触发报警,由 SRE 和研发去跟进优化和解决。
全部 pod 相关的操做都会对接 Kube Defender 统一风控中心,进行秒级别、分钟级、小时级、天级别的流控。该全局风控限流组件,实行中心端部署,维护各场景下的接口调用限流功能。
defender 是站在整个 K8s 集群的视角,针对用户发起的或者系统自动发起的有风险的操做进行防御(流控、熔断、校验)和审计的风控系统。之因此作 defender,主要从如下几个方面考虑:
defender 的框架图以下所示:
在只有几个 core 集群的场景下,依靠专家经验管理容量彻底能够轻松搞定,但随着容器业务的快速发展,覆盖泛交易、中间件、新生态、新计算以及售卖区等业务在接入 ASI,短短几年时间就发展了几百个集群,再发展几年数以千计万计?如此多的集群依靠传统的人肉资源管理方式难以胜任,人力成本愈来愈高,特别是面临诸如如下问题,极易形成资源使用率低下,机器资源的严重浪费,最终形成部分集群容量不足致使线上风险。
在 ASI 中,组件变化是常态,组件容量如何自适应这种变化也是一个很是大的挑战。而平常的运维及诊断需要有精准的容量数据来做为备容支撑。
所以咱们决定经过数据化指导组件申请合理的(成本低,安全)容器资源。经过数据化提供平常运维所须要的容量相关数据,完成备容,在生产水位异常时,完成应急扩容。
目前咱们完成了水位监控、全量风险播报、预调度、profile 性能数据定时抓取、进而经过组件规范中推动 CPU 内存以及 CPU 内存比例优化。正在作的包括自动化的规格建议,节点资源补充建议,以及自动化导入节点,结合 chatops 正在打造钉群“一键备容”闭环。另外还在结合全链路压测服务数据,得出各个组件的基线对比,经过风险决策,进行发布卡点,确保组件上线安全。同时将来会结合线上真实的变动,来持续回答真实环境的 SLO 表现,精准预测容量。
高可用基础能力的建设能够为 ASI 提供强有力的抗风险保障,从而在各类风险隐患出现时,尽量保证咱们服务的可用性。可是在风险出现后,如何快速介入消灭隐患,或者在高可用能力没法覆盖的故障出现后,进行有序止损,就变成了一个很是具备技术深度和横向复杂度的工程难题,也让 ASI 的应急能力建设成为咱们很是重要的投入方向。
在建设应急体系之初,咱们的系统因为迅速的发展和变化,不断出现的事故和险情,明显的暴露出当时咱们面临的几个严重的问题:
针对这些问题,咱们也进行了充分的脑暴和探讨,而且总结出如下几个核心缘由:
针对这些亟待解决的问题,咱们也作了应急能力的顶层设计,架构图以下:
应急能力建设总体能够分为几个部分:
针对顶层设计中的每一个子模块,咱们都已经作出了一些阶段性的工做和成果。
为了解决没法早于客户发现问题的难题,咱们的工做最重要的目标就是要作到:让一切问题都无处遁形,被系统主动发现。
因此这就像是一场持久战,咱们要作的,就是经过各类可能的手段去覆盖一个又一个新的问题,攻占一个又一个城池。
在这个目标的驱使下,咱们也总结出一套很是行之有效的“战略思想”,即「1+1 思想」。它的核心观点在于,任何发现问题的手段,均可能由于对外部的依赖或者自身稳定性的缺陷,致使偶发的失效,因此必须有可以做为互备的链路来进行容错。
在这个核心思想的指导下,咱们团队建设了两大核心能力,即黑盒/白盒报警双通道,这两个通道的各有各的特色:
黑盒通道对应的具体产品叫作 kubeprobe,是由咱们团队脱胎于社区 kuberhealthy 项目的思想上进行更多的优化和改造造成的新产品,而且也成为咱们判断集群是否出现严重风险的重要利器。
白盒通道的建设相对更为复杂,它须要建设在完备的可观测数据的基础之上,才可以真正发挥它的功力。因此为此咱们首先从 metrics、日志、事件 3 个维度分别基于 SLS 建设 3 种数据通道,将全部可观测数据统一到 SLS 上管理。另外咱们也建设了告警中心,负责完成对当前上百套集群的告警规则的批量管理,下发能力,最终构造了出了一个数据完备,问题覆盖普遍的白盒告警系统。最近还在进一步将咱们的告警能力向 SLS 告警 2.0 迁移,实现更加丰富的告警功能。
随着线上问题排查经验的不断丰富,咱们发现有不少问题会比较频繁地出现。它们的排查方法和恢复手段基本已经比较固化。即使某个问题背后的缘由可能有多种,可是随着线上排查经验的丰富,基本均可以慢慢迭代出对这个问题的排查路线图。以下图所示,是针对 etcd 集群不健康的告警设计的排查路线:
若是把这些相对比较确认的排查经验固化到系统中,在问题出现后能够自动触发造成决策,势必能够大幅减小咱们对线上问题的处理耗时。因此在这个方面,咱们也开始了一些相关能力的建设。
从黑盒通道方面,kubeprobe 构建了一套自闭环的根因定位系统,将问题排查的专家经验下沉进系统中,实现了快速和自动的问题定位功能。经过普通的根因分析树以及对失败巡检探测事件/日志的机器学习分类算法(持续开发投入中),为每个 KubeProbe 的探测失败 Case 作根因定位,并经过 KubeProbe 内统一实现的问题严重性评估系统(目前这里的规则仍比较简单),为告警的严重性作评估,从而判断应该如何作后续的处理适宜,好比是否自愈,是否电话告警等等。
从白盒通道方面,咱们经过底层的 pipeline 引擎的编排能力,结合已经建设的数据平台中的多维度数据,实现了一个通用的根因诊断中心,将经过各类可观测数据从而排查问题根因的过程经过 yaml 编排的方式固化到系统中,造成一个根因诊断任务,而且在触发任务后造成一个问题的诊断结论。而且每种结论也会绑定对应的恢复手段,好比调用预案、自愈等等。
两种通道都经过钉钉机器人等手段实现相似 chatops 的效果,提高 oncall 人员的处理问题速度。
为了可以提高运行时故障的止损恢复速度,咱们也把恢复止损能力的建设放在第一优先级,这个方面咱们的核心准则是两个:
因此在这两个准则的驱使下,咱们作了两个方面的工做:
针对缺少跟进能力的问题,咱们提出了 BugFix SLO 机制。正如名字所描述的那样,咱们认为每一个发现的问题都是一个要被修复的 “Bug”,而且针对这种 Bug 咱们作了一下工做:
每两周,经过过去一段时间收集的新的问题,咱们会产出一份稳定性周报,进行问题解决程度的通晒以及重点问题的同步。另外也会在每两周进行一次全员拉会对齐,对每一个新问题的负责人肯定,优先级确认进行对齐。
因为稳定性风险是相对低频发生的,因此对稳定性能力的最好的保鲜手段就是演练,因此在这个基础之上咱们设计或者参与了两种演练方案,分别是:
常态化故障演练机制的核心目的在于以更频繁的频率对 ASI 系统相关的故障场景以及针对这个故障的恢复能力进行持续验收,从而既发现某些组件的在稳定性方面的缺陷,也能够验收各类恢复手段预案的有效性。
因此为了可以尽量提高演练频率,咱们:
鉴于常态化演练的演练频率如此之高,咱们一般在一个专用的集群中进行持续的后台演练场景触发,以下降由于演练带来的稳定性风险。
常态化故障演练即使作的再频繁,咱们也不能彻底保证在生产集群真的出现一样的问题,咱们是否可以以一样的方式进行应对;也没有办法真正确认,这个故障的影响范围是否与咱们预期的范围一致;这些问题最根本的缘由仍是在于咱们在常态化故障演练中的集群通常是没有生产流量的测试集群。
因此在生产环境进行故障模拟才可以更加真实的反应线上的实况,从而提高咱们对恢复手段的正确性的信心。在落地方面,咱们经过积极参与到云原生团队组织的季度生产突袭活动,将咱们一些相对复杂或者比较重要的演练场景实现了在生产环境的二次验收,与此同时也对咱们的发现速度,响应速度也进行了侧面评估,不只发现了一些新的问题,也为咱们如何在测试集群设计更符合线上真实状况的场景带来了不少参考输入。
本篇仅做为开篇从总体上介绍了 ASI 全局高可用体系建设上一些探索工做以及背后的思考,后续团队会针对具体的领域好比 ASI 应急体系建设,ASI 预防体系建设,故障诊断与恢复、全链路精细化 SLO 建设和运营、ASI 单集群规模的性能瓶颈突破上等多个方面进行深刻的解读,敬请期待。
ASI 做为云原生的引领实施者,它的高可用,它的稳定性影响着甚至决定着阿里集团和云产品的业务的发展。ASI SRE 团队长期招人,技术挑战和机会都在,感兴趣的同窗欢迎来撩:en.xuze@alibaba-inc.com,hantang.cj@taobao.com。
数字时代,如何更好地利用云的能力?什么是新型、便捷的开发模式?如何让开发者更高效地构建应用?科技赋能社会,技术推进变革,拓展开发者的能量边界,一切,因云而不一样。点击当即报名活动,2021 阿里云开发者大会将会带给你答案。