做者 | 彭南光(光南)
来源 | 阿里巴巴云原生公众号git
千里之堤,溃于蚁穴。web
不知道你们是否经历过这样的情景:忽然被用户告知系统出现问题,而后一脸懵地惶惶然排查修复;或是等到本身发现系统出现故障时,实际已经对用户形成了严重的恶劣影响。算法
所谓千里之堤,溃于蚁穴。用户信任的创建是长期而艰难的,然而要摧毁这种信任却很简单。一旦出现上述问题,不只极大影响用户使用体验,同时会给用户留下一个这个产品/团队不可靠的印象,丧失用户对产品/团队长期好不容易积累下来的信用资本,将来再想创建这样的信任关系就很难了。数据库
这也是为何咱们说快速发现问题的能力如此重要的缘由,只有先作到快速发现问题,才能谈怎样排查问题、如何解决问题。api
那么怎样才能在复杂的大规模场景中,作到真正先于用户发现问题呢?下面我会带来咱们在管理大规模 ASI 集群过程当中对于快速发现问题的一些经验和实践,但愿能对你们有所启发。安全
注:ASI 是 Alibaba Serverless infrastructure 的缩写,是阿里巴巴针对云原生应用设计的统一基础设施。有兴趣能够阅读:《揭开阿里巴巴复杂任务资源混合调度技术面纱》。架构
咱们所管理的大规模 ASI 集群场景很是复杂,这为咱们的工做带来了极大挑战,任何一个场景处理不慎就有可能致使意料以外的伤害扩大化。less
从组件维度看,咱们目前有几百个组件,每一年有几万次的组件变动。频繁的组件变动如何在稳定性和效率之间取得权衡,怎样让变动时更稳定,怎样让灰度更确信,从而下降爆炸半径?机器学习
从集群维度看,目前有上千个集群和海量节点,碰到的集群/节点问题较多,监控链路覆盖比较繁复,怎样让集群运行时更加可信?分布式
基于长期的集群管理经验,咱们有以下预设:
数据监控做为正向链路,没法无死角覆盖全部场景。即便链路中各个节点的监控数据正常,也不能 100% 保证链路可用。
只有弥补上述两类风险点,才能有底气真正作到先于用户发现问题。咱们解决上述两类风险的思路分别是:
基于以上思路,咱们设计并实现了 KubeProbe 探测/巡检中心,用于弥补复杂系统的正向监控的不足,帮助咱们更好、更快地发现系统风险和线上问题。
不知道你是否也经历过一条链路上各个系统监控数据都正常,可是实际链路流程就是跑不通。或者由于系统变化快,监控覆盖不到 100% 的场景老是会有遗漏,致使影响到了用户却没有报警,对用户没有实质影响却报警频发从而疲于奔命。
若是一个系统开发者本身都不使用本身的系统,那么怎么可能先于用户发现系统问题呢?因此要先于用户发现系统问题,首先咱们本身就得先成为用户,并且必定是使用最多,了解最深,无时无刻不在使用和感知系统情况的用户。
所谓黑盒探测,就是让本身成为本身的用户,模拟广义"用户"的行为去对集群/组件/链路等待待测对象作探测。注意,这里的"用户"并不只仅是狭义上使用系统的同窗,而是广义用户。好比,etcd 的"用户"是 APIServer,而 ASI 的"用户"多是某个经过 APIServer 操做集群的同窗,也多是 Normandy 发起的发布/扩容/缩容操做。
咱们但愿 KubeProbe 能在 变动时(监听到集群状态发生变化/组件变动/组件发布/系统升级等等事件)/运行时(周期,高频)/故障恢复时(手动),经过周期/事件触发/手动触发,执行各类不一样类型的黑盒探测,第一时间感知组件/集群/链路的可用性。
以 etcd 集群的可用性来举例,咱们能够实现一个探测用例,逻辑是对 etcd 作 create/get/delete/txn 等等操做,并记录每一个操做的成功率/消耗时间,当成功率低于 100% 或消耗时间超过容忍阈值后,触发报警。咱们将周期高频运行这个 etcd 的探测用例,同时对于 etcd 集群的任何变动都会发出一个事件 event 触发这个 etcd 探测当即运行,这样就能尽可能确保第一时间发现 etcd 可用性故障了。同时,当 etcd 集群由于某些缘由不可用了,咱们也能够经过手动触发等其余方式作探活,也能第一时间获得是否恢复的信息。
在大规模集集群/系统场景下,数据一致性是必定会面临的难题。数据不一致,将致使一些隐患,可能会在将来引起某些肯定性的故障。
相比于黑盒探测面对的未知故障场景,定向巡检的目标是对集群的已知风险点作扫描。
咱们但愿 KubeProbe 可以按期对整个集群/链路作定向的巡检,找出这些数据不一致的点,判断数据不一致是否可能引起风险,从而可以防患于未然,治未病。
好比 etcd 冷热备多集群覆盖不全,可能致使集群遇到故障没法快速恢复。那么咱们就按期对 etcd 的冷热备覆盖状况作定向巡检,找出没有覆盖推平的集群,并告警。好比 集群风控系统没有全集群链路覆盖,限流配置没有全集群链路推平,可能致使某些故障场景引起集群全面崩溃,咱们按期对风控配置全网扫描,判断是否可能致使故障,找出这些隐藏的已知风险点并告警。
KubeProbe 的基本实现架构大体以下图,KubeProbe 中心端配置集群/集群组与巡检/探测用例/用例集之间的关联关系,负责对集群作具体某次探测实例下发。某个具体的巡检/探测用例下发到具体某个集群将使用用例的镜像建立一个 pod,这个 pod 里会执行若干巡检/探测逻辑,当执行完成后会回调中心端回写本次巡检/探测结果。其具体结果在中心端统一展现/告警,并提供给其余消费者消费(如支持 ASIOps 平台的发布阻断)。
除了上述的基本架构以外,咱们对于高频探测用例(既探测周期短,触发频率须要很是频繁,甚至保持无缝探测的场景)设计了一套集群内的分布式常驻探测架构,该架构经过集群内的 ProbeOperator 组件 watch 自定义对象 probeConfig 的变化,在集群内建立一个常驻的探测 pod,将持续无间断的运行探测逻辑,实现接近无缝的持续探测,并将结果经过去噪/令牌桶限流等处理后,上报中心端,共给其余消费者消费。
全部的探测/巡检用例都使用统一的 git 仓库管理,由咱们提供一个统一的 client 库,client 库最核心提供的方法主要有两个。
KPclient "gitlab.alibaba-inc.com/{sigma-inf}/{kubeProbe}/client" // 报告成功 // 此方法会向KubeProbe报告本次巡检结果为成功 KPclient.ReportSuccess() os.Exit(0) // 报告失败 // 报告方法会向KubeProbe报告本次巡检结果为失败,而且失败信息为 `我失败啦` KPclient.ReportFailure([]string{"我失败啦!"}) os.Exit(1)
咱们能够经过提供好的 Makefile 将这个用例打包成镜像,录入 KubeProbe 中心端就能够对集群作配置和下发了。将具体巡检/探测逻辑和 KubeProbe 中心管控端解耦,能够灵活而又简便的让更多的二方用户接入本身的特殊巡检/探测逻辑。
目前已经使用的探测/巡检用例包括:
编写完成探测/巡检用例,并打包上传好镜像后,就须要在 KubeProbe 中心端注册这个用例模版,即将镜像注册进 KubeProbe 中心端的数据库中。
咱们能够经过"渲染配置"参数传入一些指定的 env 环境变量到巡检/探测 pod 中,用于执行不一样的业务逻辑,实现同一个用例模版生成多个用例。
最后经过统一的配置管控将用例和集群作绑定,配置对应的参数,执行各类下发逻辑。
同时,咱们还在 KubeProbe 中心端作了大量权限安全管控,脏数据资源清理以及提效增速的工做(好比采用彻底以 ownerreferences 的巡检/探测用例资源自动清理能力等等),这里再也不赘述。
咱们打通了 KubeProbe 探测与发布变动的关联,当对应集群中有任何变动发生时(如某组件在作发布),咱们会自动经过相应的事件触发此集群绑定的全部巡检/探测用例,检查集群状态是否正常。若是探测失败,则会将变动阻断,下降爆炸半径,提高集群变动时稳定性。
社区有一个 Operator 叫 Kuberhealthy 也能够作相似的事情,咱们曾经也考虑采用,而且深度使用过 Kuberhealthy 和参与 kuberhealthy 的社区贡献,最终得出不适合的结论,主要缘由是对大规模集群的支持较弱,同时高频调用时主流程卡死问题比较严重,不支持事件/手动单次触发特性,不支持统一上报数据中心等等,最终选择了自研自建的方式,目前来看是一个比较正确的选择。
KubeProbe 上线以来,实现探测/巡检用例几十个,在集团数百个 ASI 集群中运行千万余次,主动发现集群故障和问题百余次,其中某些小故障一旦没有发觉颇有可能升级成为大故障,有效下降了系统风险。同时打通了变动/发布系统,提高了变动稳定性。而且在特殊故障时,屡次先于业务方提早发现问题,更早地推进解决问题,客观下降了故障损失。
下面是一个具体例子:
KubeProbe 所面对的场景和数据监控不一样,更多偏向于链路探测。
好比,监控告警通常的告警可能以下:
这些告警,每每内容中就包含了具体的故障点,而 KubeProbe 的链路探测告警就有不少不同,好比:
这些 KubeProbe 的告警每每比较难从字面看出到底此次巡检/探测是为何失败了,咱们每每须要根据相关的用例返回日志,巡检/探测 pod 日志,KubeProbe 相关集群事件综合排查,定位失败缘由。
咱们以比较混沌的 KubeProbe 探测失败告警做为线索,构建了一套 KubeProbe 自闭环的根因定位系统,将问题排查的专家经验下沉进系统中,实现了快速和自动的问题定位功能,一个简单的定位规则以下:
咱们会经过普通的根因分析树以及对失败巡检探测事件/日志的机器学习分类算法(持续开发投入中),为每个 KubeProbe 的探测失败 Case 作根因定位,并经过 KubeProbe 内统一实现的问题严重性评估系统(目前这里的规则仍比较简单),为告警的严重性作评估,从而判断应该如何作后续的处理适宜,好比是否自愈,是否电话告警等等。
有了上面提到的根因定位以及告警严重性评估系统,咱们使用了 nlp 告警机器人,实现了一套自动化的 Oncall 系统以及 ChatOps,展现一些使用的 case 以下,经过 ChatOps 和 Oncall 机器人,极大的下降了问题处理的复杂度,尽可能用技术的手段解决重复的问题。
以上是咱们在管理大规模 Kubernetes 集群中的一点经验,也解决了一些常见的问题,但愿能对你们有所帮助。同时,这些工做在阿里云海量规模的场景下还须要持续打磨,咱们仍在路上,而且将持续在路上。