【深度】阿里巴巴万级规模 K8s 集群全局高可用体系之美
前言
ASI:Alibaba Serverless infrastructure,阿里巴巴针对云原生应用设计的统一基础设施,ASI 是阿里公共云服务 ACK 的阿里集团企业版。
etcd 出现大量的读写延迟。
kube-apiserver 查询 pods/nodes 延时很高,甚至导致 etcd oom。
控制器无法及时感知数据变化,如出现 watch 数据延迟。
ASI 全局高可用概述
云基础相关管理,包括可用区的选择,规划和硬件资产的管理
节点的管理
ASI 集群管理
公共服务
集群运维
应用研发
ASI 全局高可用设计
全局高可用基础能力建设
如何在架构和能力上去提升我们的可用性,降低系统发生故障的概率和影响面?
如何在核心链路性能和架构上做一些突破,能够支撑这么复杂多变的业务场景和业务增长的通用需求?
如何让问题不再追身,做好预防工作,避免应急?
如何在应急发生时,能够快速发现,快速诊断,快速止损?
可用性能力不足:在集团场景下,组件不断在变化,不断增加系统的压力和复杂度,ASI 在生产可用性的能力上缺失,如限流降级、负载均衡等,组件容易乱用造成低级错误,影响集群可用性。
系统风控和 pod 保护能力不足:在人为误操作或系统 bug 时, 容易造成业务 pod 无辜受损或者大面积受损。
容量风险:集群数量几百,组件接近一百;另外历史问题因 podCIDR 和节点 IP 数的配置,大多 ASI 元集群的节点规模被约束在 128 台以内,随着业务快速发展,对容量风险而言存在较大挑战。
单集群规模受限,加上横向扩展能力不足影响业务发展:单集群不断增长规模,以及业务类型变化,组件变化都对单集群支撑的最大规模产生影响,对 SLO 持续稳定产生影响。
1. 高可用基础能力顶层设计
性能优化和高可用架构建设:主要是从性能优化和架构升级的角度来提升整个集群支撑的业务类型和业务量。
组件规范全生命周期管理:主要从规范的角度在组件的整个生命周期去落地,从出生启用和集群准入开始,到每一次变更,到下线整个生命周期都要防止组件乱用、野蛮生长、无限膨胀,控制组件在系统可承受范围之内。
攻防体系建设:主要从 ASI 系统本身触发,在从攻击和防御的角度来提升系统的安全,防御和风控能力。
2. K8s 单集群架构的痛点
对 ApiServer 的掌控能力不够,应急能力不足,我们自己的经历,历次集群 Master 出现异常的次数超过 20+,历次恢复时间最长超过 1 小时。
ApiServer 是 APIServer 集群的单点,爆炸半径大。
单集群规模大, Apiserver 内存水位比较高,压力来源于频繁的查询,写入更多更大的资源对象。
在业务层缺少跨机房的容灾能力,当 ASI 不可用的时候,只能依赖 ASI 的恢复能力。
集群规模的持续扩大,离线任务的大量创建和删除对集群的造成更大压力。
一是通过联邦这样的多集群能力来解决单集群的横向扩展能力以及单地域跨集群容灾能力。
另外一个单集群本身的架构还可以从隔离和优先级策略的架构角度来进行差异化 SLO 保障。
3. ASI 架构升级落地
1)APIServer 多路架构升级
通过分流以降低主链路 apiserver 压力(核心诉求)
P2 及以下组件接入旁路 apiserver,并可以在紧急情况(如自身稳定性收到影响)下,做整体限流。
旁路 apiserver 配合主链路做蓝绿、灰度(次级诉求)
旁路 apiserver 可以使用独立版本,增加新功能灰度维度,如使用独立的限流策略,如开启新的 feature 功能验证。
SLB 灾备(次级诉求)
2)ASI 多集群联邦架构升级
容灾层面:把核心交易应用的中心单元部署在一个集群的风险是很大的,最坏情况下集群不可用导致整个应用服务不可用。
性能层面:对于业务来说,如因核心应用在某一时点使用时极其敏感而设定各种单机最大限制、CPU 互斥独占保证,如果都部署在一个集群的话,会因为集群节点规模限制,导致应用发生堆叠,造成 cpu 热点,性能不满足要求;对于 ASI 管控 Master 来说,单集群无限制扩大,性能总会出现瓶颈,总有一天会无法支撑。
运维层面:当某个应用扩容发现没资源,SRE 还得考虑节点加到哪个集群,额外加大了 SRE 集群管理的工作。
4. K8s 集群遭遇规模增长带来的极大性能挑战
首先是查询相关问题。在大集群中最重要的就是如何最大程度地减少 expensive request。对百万级别的对象数量来说,按标签、namespace 查询 Pod,获取所有 Node 等场景时,很容易造成 etcd 和 kube-apiserver OOM 和丢包,乃至雪崩等问题发生。
其次是写入相关问题。etcd 适用场景是读多写少,大量写请求可能会导致 db size 持续增长、写性能达到瓶颈被限速、影响读性能。如大量的离线作业需要频繁的创建和删除 pod,通过 ASI 链路对 pod 对象的写放大,最终对 etcd 的写压力会放大几十倍之大。
最后是大资源对象相关问题。etcd 适合存储较小的 key-value 数据,在大 value 下,性能急速下降。
5. ASI 性能瓶颈突破
ASI 性能优化的方向
客户端侧,可以做 cache 优化,让各个 client 优先访问本地 informer cache,也需要做负载均衡优化,主要包括对 apiserver,etcd 的负载均衡。同时针对客户端的各种优化,可以通过组件性能规范,在组件启用,准入的时候进行校验是否满足。
APIServer 侧,可以从访问层,缓存层,存储层 3 个层次进行优化。在缓存层,我们重点建设了 cache 的索引优化以及 watch 优化,在存储层上重点通过 snappy 压缩算法对 pod 进行数据压缩,在访问层上重点建设了限流能力。
etcd 存储侧的优化,我们也从几个方面做了很多工作,包括 etcd 内核层面各种算法优化工作,还有通过将不同资源拆分到不同 etcd 集群的能力实现了基本的水平拆分能力,同时也在 etcd server 层做 multi boltdb 的扩展能力提升。
6. K8s 集群的预防能力薄弱
7. ASI 单集群的预防能力加强
1)支持 API 访问层的多维度(resource/verb/client)精细化限流
ua limiter 是根据 ua 提供一个简单的 QPS hard limit。
apf 更加侧重于并发度的控制,考虑的是流量的隔离和隔离后的公平性。
sentinel 功能全面,但是对于公平性的支持并没有 APF 全面,同时复杂度有一些过高。
2)支持业务 POD 级别的精细化限流
类似 kubelet/controller 这样的组件,在一个集群中存在多个进程,任一单一进程都无法看到全局的视图,无法进行准确的限流。
从运维视角,分散在各个组件中的限速规则难以配置与审计,当部分操作因为限流原因失败时,排查链路过长影响问题定位的效率。
K8s 面向终态的分布式设计,每个组件都有决策的能力,那么就需要一个集中的服务对那些危险决策进行风控。
defender server 是 K8s 集群级的服务,可以部署多个,其中一个 active,其余 standby。
用户可以通过kubectl配置风控规则。
K8s 中的组件,例如 controller,kubelet,extension-controller 等,都可以通过 defender sdk 接入 defender(改动很小),在进行危险操作前请求 defender 进行风控,根据风控结果决定是否继续该危险操作。defender 作为一个集群级的风控防护中心,为 K8s 集群的整体稳定性进行保驾护航。
3)数字化容量治理
组件变更不断,业务类型和压力也在变化,线上真实容量(到底能扛多少 qps)大家都不得而知,当业务需要增大流量时是否需要扩容?是否横向扩容也无法解决问题?
早期申请容器资源随意,造成资源成本浪费严重,需要基于容器成本耗费最小化明确指导应该合理申请多少资源(包括 cpu,内存及磁盘)。同一个地域,同一个元集群的业务集群,一个集群浪费了资源就会造成其他集群资源的紧张。
全局高可用应急能力建设
为什么客户总是早于我们发现问题?
为什么恢复需要这么长的时间?
为什么同样的问题会重复出现?
为什么只有几个人能处理线上的问题?
发现问题手段单一:只有 metrics 数据作为最基本暴露问题的手段。
定位问题能力缺乏:只有少数监控大盘,核心组件的可观测能力建设程度没有统一。
恢复手段缺乏体系:线上问题的修复需要临时敲命令,写脚本,效率低且风险大。
应急缺少体系规范:缺乏与业务方联动,工程师思维严重,不是以止损为第一目标,对问题严重度缺乏意识。
长期问题缺乏跟踪:线上发现的隐患,或者事故复盘的跟进项,缺乏持续跟进能力,导致重复踩坑。
缺乏能力保鲜机制:业务变化非常快速,导致一些能力在一段时间后,进入一个“不会用也不敢用,也不能保证一定能用”的尴尬境地。
1. 应急能力建设顶层设计
1-5-10 应急体系:针对线上出现的任何突发风险,都能做到“一分钟发现,五分钟定位,十分钟恢复”的底层能力和机制。
问题追踪跟进:针对线上发现的所有风险隐患,无论严重与否,都能持续跟踪推进的能力。
能力保鲜机制:针对建设的 1-5-10 能力,鉴于其使用频率比较低的本质特性。
2. 应急能力建设子模块建设
1)一分钟发现:问题发现能力
黑盒通道:基于黑盒思想,从客户视角把 ASI 整体当做黑盒,直接发出指令,探测正向功能;比如直接扩容一个 statefulset。
白盒通道:基于白盒思想,借助系统内部暴露出来的各种维度的可观测性数据的异常波动来发现潜在问题;比如 APIServer 的内存异常上涨。
2)五分钟定位:问题根因自动定位能力
3)十分钟恢复:恢复止损能力
止损能力要系统化,白屏化,可沉淀。
一切以止损为目标,而不是以找到绝对的根因为目标。
建设预案中心:中心化沉淀我们所有的止损能力到系统中,白屏管理,接入,运行。一方面也可以将以前散落在各个研发手中或者文档中的预案统一收拢中心端统一管理,实现了对预案的中心化管控。另一方面预案中心也开发了支持用户通过 yaml 编排的方式来录入预案的能力,从而实现低成本接入。
建设通用止损手段集:根据过往历史经验,结合 ASI 的特有特性,建设多种通用的止损能力集合,作为应急时的重要抓手。包括了组件原地重启,组件快速扩容,controller/webhook 快速降级,集群快速切换只读等等常用功能
4)问题持续跟踪机制 BugFix SLO
一方面,定义了一系列分类方法保证问题能够明确到团队和具体的一个负责人。
一方面,定义解决优先级,即解决这个问题的 SLO,L1 - L4,不同优先级代表不同的解决标准,L1 代表必须当天内迅速跟进并且解决。
5)能力验收保鲜机制
常态化故障演练机制
生产突袭演练机制
一方面开始建设自身的故障场景库,将所有场景进行入库,分类,管理,保证场景的覆盖面够全面。
另一方面同质量保证团队合作,充分利用其 chorus 平台提供的注入故障能力将我们的设计场景逐个落地,并且配置为后台持续运行。我们还借助该平台灵活的插件丰富能力,将平台同我们的告警系统,预案系统进行 API 对接,在故障场景被触发注入后,可以完全通过后台自动调用的模式完整的针对这个场景的注入、检查、恢复都通过后台运行完成。
写在最后
数字时代,如何更好地利用云的能力?什么是新型、便捷的开发模式?如何让开发者更高效地构建应用?科技赋能社会,技术推动变革,拓展开发者的能量边界,一切,因云而不同。点击【阅读原文】立即报名活动,2021 阿里云开发者大会将会带给你答案。