随着 Kubernetes 逐渐成为云计算的标准,企业中的 Kubernetes 应用正成为主流。根据 CNCF 2019 Kubernetes 使用调查报告的显示:目前 84% 的用户已经在生产环境中使用 Kubernetes,生产环境中容器部署规模超过 1000 的比例是 34%,其中超过 5000 的大规模应用比例是 19%。当集群越来越大、越来越复杂,集群可用性就会面临挑战。
整体指标:集群是否健康,所有组件是否正常工作,集群中 Pod 创建的失败数量有多少等等;
追踪能力:集群中发生了什么,是否有异常,用户做了什么事情等等;
原因定位:出现异常之后,找到是哪个组件出了问题。
想要解决这些问题,比较好的一个方法就是 SLO,通过定义 SLO 来描述集群的可用性,追踪集群中 Pod 的生命周期,一旦出现失败 Pod,快速定位异常组件。本文采访了蚂蚁集团技术专家范康和姚菁华来分享蚂蚁集团的 SLO 体系是如何建立的。
大家常会听到 SLA,其实 SLA 是 SLO 衍生出来的协议,SLA 协议会形成具有法律效力的合同,通常是服务供应商和外部客户之间签订的,而 SLO 是用于内部服务之间,定义服务所提供功能的一种期望状态。
SLO 指标定义
如果我们要通过定义来描述集群的可用性,那么具体的描述指标就成为了需要解决的关键问题。在蚂蚁集团内部,集群可用性的关键指标包含五个:集群健康度、Pod 创建成功率、残留 Terminating Pod 的数量、服务在线率和故障机数量。
集群健康度:通常使用 Healthy,Warning,Fatal 三个值来描述,其中 Warning 和 Fatal 对应告警体系,例如 P2 告警发生,那集群就是 Warning,而 P0 告警发生,那集群就是 Fatal,必须进行处理。
Pod 创建成功率:这是一个非常重要的指标,蚂蚁集团一周的 Pod 创建量在百万级别,如果成功率波动会造成大量 Pod 失败,同时 Pod 成功率下跌也是集群异常的最直观反映;
残留 Terminating Pod 的数量:有人可能会好奇为什么使用残留 Terminating Pod 的数量,而不用删除成功率?这是因为当 Pod 数量达到百万级别后,即使删除成功率达到了 99.9%,Terminating Pod 的数量也有数千,残留这么多 Pod 占用应用容量,在生产环境中是不可接受的;
服务在线率:这个指标是通过探针来衡量的,探针失败则意味着集群不可用;
故障机数量:这是一个节点维度的指标,故障机通常是指无法正确交付 Pod 的物理机,集群故障机需要做到“快速发现,快速隔离,及时修复”,否则会对集群容量造成影响。
以上指标的阈值和 SLO 性能目标都是根据业务方的增长来定义的,随着业务的不断增长,这些指标的定义也可能需要跟着做调整。
以 Pod 创建成功率为例,蚂蚁集团将 Pod 分为了普通 Pod 和 Job 类 Pob,普通 Pod 的 RestartPolicy 为 Never,Job 类 Pod 的 RestartPlicy 为 Never 或 OnFailure,两者的都设定有交付时间,普通 Pod 的交付标准是 1min 内 Pod 已经 Ready;Job 类 Pod 的交付标准是 1min 内 Pod 的状态已达 Running、Succeeded 或 Failed。最开始 Pod 创建成功率的定义是成功创建的 Pod 和总 Pod 的比值,但是很快就发现在排查原因时,系统很难分辨,所以又将 Pod 失败原因调整成用户和系统两部分,创建成功率的定义就变成了创建成功的 Pod 和总的 Pod 减去用户失败 Pod 的比值。
蚂蚁集团的 SLO 体系
确定好 SLO 各项关键指标的定义之后,接下来就是构建 SLO 体系。
据范康介绍,蚂蚁集团 SLO 系统主要包括两个方面,一个方面用于向终端用户 / 运维人员展示当前集群各项指标状,另一方面是各个组件相互协作,分析当前集群状态,获取影响 SLO 的各项因素,为提升集群 pod 交付成功率提供数据支持。
蚂蚁集团 SLO 体系架构图
自顶向下而看,蚂蚁集团 SLO 的分层架构包括 SLO、Trace system、Increase of SLO、Target 和 The unhealthy node。
其中,顶层组件主要面向各种指标数据, 如集群健康状态、pod 创建、删除、升级成功率、残留 pods 数量,不健康节点数量等指标。其中 Display Board 是指监控大盘,可能不会实时查看,为避免错过处理紧急事件的最佳时机,同时构建了 Alert 告警子系统,支持配置多种告警方式;Analysis System 通过分析指标历史数据以及采集到的节点 metrics 和 master 组件指标,给出更详细的集群运营报告;Weekly Report 子系统给出当前集群本周 pod 创建 / 删除 / 升级的数据统计,以及失败案例原因汇总;Terminating Pods Number 给出一段时间内集群内新增的无法通过 Kubernetes 机制删除的 Pods 列表和 Pods 残留原因;Unhealthy Nodes 则给出一个周期内集群所有节点的总可用时间占比,每个节点的可用时间、运维记录、以及不能自动恢复,需要人工介入恢复的节点列表。
为了支撑上述这些功能,蚂蚁集团还开发了 Trace System,用来分析展示单个 pod 创建 / 删除 / 升级失败的具体原因。其中包含日志和事件采集、数据分析、pod 生命周期展示三个模块。日志和事件采集模块采集各 master 组件以及节点组件的运行日志和 pod、node 事件,分别以 pod/node 为索引存储日志和事件;数据分析模块分析还原出 pod 生命周期中各阶段用时,判断 pod 失败原因,节点不可用原因。最后,由 Report 模块向终端用户暴露接口和 UI,向终端用户展示 pod 生命周期以及出错原因。
经验总结
目前蚂蚁集团的 SLO 实践不仅提高了集群 pod 的交付成功率,同时通过构建 tracing 系统,分析到集群内 pod 交付关键链路的耗时,整理失败原因,实现了数据分析 / 诊断平台。对于如何实现高 SLO,范康也给出了自己的五点经验。
在提升成功率的进程中, SLO 治理团队面临最大的问题是镜像下载。Pod 必须在规定时间内交付,而镜像下载通常需要非常多的时间。所以, 团队通过计算镜像下载时间,专门设置了一个 ImagePullCostTime 的错误,即镜像下载时间太长,导致 Pod 无法按时交付。另外,阿里镜像分发平台蜻蜓支持了 Image lazyload 技术,在 Kubelet 创建容器时,不用再下载镜像,大大加速了 Pod 的交付速度。
提升单个 Pod 成功率:随着成功率的提升,再提升的难度会越来越大,这是可以引入 workload 进行重试。蚂蚁集团内部的 PaaS 平台会不断重试,直到 Pod 成功交付或者超时。需要注意的是,重试时要先排除之前的失败节点。
检查关键 Daemonset:如果关键 Daemonset 缺失,把 Pod 调度上去是很容易出问题的,甚至影响到创建 / 删除链路,这样可能就接入故障机体系。
很多 Plugin 是需要向 Kubelet 注册的,如 CNI Plugin,可能存在节点上一切正常,但向 Kubelet 注册时失败的情况,那么这个节点同样无法提供 Pod 交付的服务,需要接入故障机体系。
由于集群中的用户数量非常多,所以隔离很重要。在权限隔离的基础上,还需要做到 QPS 隔离、容量隔离,防止一个用户的 Pod 把集群能力耗尽,影响其他用户的利益。
评论