面对大规模 K8s 集群,如何先于用户发现问题?

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
MSE Nacos/ZooKeeper 企业版试用,1600元额度,限量50份
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 怎样才能在复杂的大规模场景中,做到真正先于用户发现问题呢?下面我会带来我们在管理大规模 ASI 集群过程中对于快速发现问题的一些经验和实践,希望能对大家有所启发。

头图.png

作者 | 彭南光(光南)
来源 | 阿里巴巴云原生公众号

千里之堤,溃于蚁穴。

绪论

不知道大家是否经历过这样的情景:突然被用户告知系统出现问题,然后一脸懵地惶惶然排查修复;或是等到自己发现系统出现故障时,实际已经对用户造成了严重的恶劣影响。

所谓千里之堤,溃于蚁穴。用户信任的建立是长期而艰难的,然而要摧毁这种信任却很简单。一旦出现上述问题,不仅极大影响用户使用体验,同时会给用户留下一个这个产品/团队不可靠的印象,丧失用户对产品/团队长期好不容易积累下来的信用资本,未来再想建立这样的信任关系就很难了。

这也是为什么我们说快速发现问题的能力如此重要的原因,只有先做到快速发现问题,才能谈怎样排查问题、如何解决问题。

那么怎样才能在复杂的大规模场景中,做到真正先于用户发现问题呢?下面我会带来我们在管理大规模 ASI 集群过程中对于快速发现问题的一些经验和实践,希望能对大家有所启发。

注:ASI 是 Alibaba Serverless infrastructure 的缩写,是阿里巴巴针对云原生应用设计的统一基础设施。有兴趣可以阅读:《揭开阿里巴巴复杂任务资源混合调度技术面纱》

背景

1. 复杂的场景和曾面临的困境

我们所管理的大规模 ASI 集群场景非常复杂,这为我们的工作带来了极大挑战,任何一个场景处理不慎就有可能导致意料之外的伤害扩大化。

  • 从组件维度看,我们目前有几百个组件,每年有几万次的组件变更。频繁的组件变更如何在稳定性和效率之间取得权衡,怎样让变更时更稳定,怎样让灰度更确信,从而降低爆炸半径?
  • 从集群维度看,目前有上千个集群和海量节点,碰到的集群/节点问题较多,监控链路覆盖比较繁复,怎样让集群运行时更加可信?
  • 从二方用户和业务场景看,我们支持了大量的集团二方用户,同时业务场景也非常复杂,怎样保证各有特色的业务场景都能得到一致的细心关照?

1.png

2. 问题预判和解决思路

基于长期的集群管理经验,我们有如下预设:

  1. 数据监控作为正向链路,无法无死角覆盖所有场景。即使链路中各个节点的监控数据正常,也不能 100% 保证链路可用。

    • 集群状态每时每刻都在变化,各个组件也在不停地更新升级,同时链路上的每个系统也在不停的变更,监控数据的覆盖永远是正向的追赶,只能逼近 100% 全覆盖而无法完全达到。
    • 即使整个集群链路中所有组件/节点的监控数据都正常,也不能保证集群链路 100% 可用。就如同业务系统一样,看上去都是可用的,没有问题暴露。但只有通过全链路压测实际探测过整个链路后,才能得到实际可用的结论。
    • 你要正向证明一个东西可用,需要举证无数的例子。而如果要反向证明不可用,一个反例就够了。数据监控链路只能逼近全覆盖,而无法保证真正全覆盖。
  2. 大规模场景下,数据无法达到 100% 的完全一致性。

    • 当集群规模足够大时,数据的一致性问题将会愈加显现。比如全局风控组件是否全集群链路覆盖?相关流控配置是否全集群链路推平?pod 主容器时区是否与上层一致?集群客户端节点证书是否有即将过期?等等问题,一旦疏忽,将有可能酿成严重的故障。

只有弥补上述两类风险点,才能有底气真正做到先于用户发现问题。我们解决上述两类风险的思路分别是:

  1. 黑盒探测

    • 所谓黑盒探测,既模拟广义上的用户行为,探测链路是否正常。
  2. 定向巡检

    • 所谓巡检,既检查集群异常指标,找到已有或可能将存在的风险点。

基于以上思路,我们设计并实现了 KubeProbe 探测/巡检中心,用于弥补复杂系统的正向监控的不足,帮助我们更好、更快地发现系统风险和线上问题。

设计

黑盒探测和定向巡检

1)黑盒探测

不知道你是否也经历过一条链路上各个系统监控数据都正常,但是实际链路流程就是跑不通。或者因为系统变化快,监控覆盖不到 100% 的场景总是会有遗漏,导致影响到了用户却没有报警,对用户没有实质影响却报警频发从而疲于奔命。

如果一个系统开发者自己都不使用自己的系统,那么怎么可能先于用户发现系统问题呢?所以要先于用户发现系统问题,首先我们自己就得先成为用户,而且一定是使用最多,了解最深,无时无刻不在使用和感知系统状况的用户。

所谓黑盒探测,就是让自己成为自己的用户,模拟广义"用户"的行为去对集群/组件/链路等待待测对象做探测。注意,这里的"用户"并不仅仅是狭义上使用系统的同学,而是广义用户。比如,etcd 的"用户"是 APIServer,而 ASI 的"用户"可能是某个通过 APIServer 操作集群的同学,也可能是 Normandy 发起的发布/扩容/缩容操作。

2.png

我们希望 KubeProbe 能在 变更时(监听到集群状态发生变化/组件变更/组件发布/系统升级等等事件)/运行时(周期,高频)/故障恢复时(手动),通过周期/事件触发/手动触发,执行各种不同类型的黑盒探测,第一时间感知组件/集群/链路的可用性。

以 etcd 集群的可用性来举例,我们可以实现一个探测用例,逻辑是对 etcd 做 create/get/delete/txn 等等操作,并记录每个操作的成功率/消耗时间,当成功率低于 100% 或消耗时间超过容忍阈值后,触发报警。我们将周期高频运行这个 etcd 的探测用例,同时对于 etcd 集群的任何变更都会发出一个事件 event 触发这个 etcd 探测立即运行,这样就能尽量确保第一时间发现 etcd 可用性故障了。同时,当 etcd 集群因为某些原因不可用了,我们也可以通过手动触发等其他方式做探活,也能第一时间得到是否恢复的信息。

2)定向巡检

在大规模集集群/系统场景下,数据一致性是一定会面临的难题。数据不一致,将导致一些隐患,可能会在未来引发某些确定性的故障。

相比于黑盒探测面对的未知故障场景,定向巡检的目标是对集群的已知风险点做扫描。

3.png

我们希望 KubeProbe 能够定期对整个集群/链路做定向的巡检,找出这些数据不一致的点,判断数据不一致是否可能引发风险,从而能够防患于未然,治未病。

比如 etcd 冷热备多集群覆盖不全,可能导致集群遇到故障无法快速恢复。那么我们就定期对 etcd 的冷热备覆盖情况做定向巡检,找出没有覆盖推平的集群,并告警。比如 集群风控系统没有全集群链路覆盖,限流配置没有全集群链路推平,可能导致某些故障场景引发集群全面崩溃,我们定期对风控配置全网扫描,判断是否可能导致故障,找出这些隐藏的已知风险点并告警。

实现

1. 架构

1)基本架构

KubeProbe 的基本实现架构大致如下图,KubeProbe 中心端配置集群/集群组与巡检/探测用例/用例集之间的关联关系,负责对集群做具体某次探测实例下发。某个具体的巡检/探测用例下发到具体某个集群将使用用例的镜像创建一个 pod,这个 pod 里会执行若干巡检/探测逻辑,当执行完成后会回调中心端回写本次巡检/探测结果。其具体结果在中心端统一展示/告警,并提供给其他消费者消费(如支持 ASIOps 平台的发布阻断)。

4.png

2)高频架构

除了上述的基本架构之外,我们对于高频探测用例(既探测周期短,触发频率需要非常频繁,甚至保持无缝探测的场景)设计了一套集群内的分布式常驻探测架构,该架构通过集群内的 ProbeOperator 组件 watch 自定义对象 probeConfig 的变化,在集群内创建一个常驻的探测 pod,将持续无间断的运行探测逻辑,实现接近无缝的持续探测,并将结果通过去噪/令牌桶限流等处理后,上报中心端,共给其他消费者消费。

5.png

2. KubeProbe 探测/巡检用例管理

所有的探测/巡检用例都使用统一的 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 中心管控端解耦,可以灵活而又简便的让更多的二方用户接入自己的特殊巡检/探测逻辑。

目前已经使用的探测/巡检用例包括:

  • 通用探测:模拟 pod / deployment / statefulset 生命周期探测集群整条管控链路。
  • etcd 黑盒探测:模拟 etcd 的基本操作,探测元集群中各 etcd 状态。
  • 金丝雀探测(感谢质量技术同学的大力支持):模拟用户使用 ASI 的部署场景,实现金丝雀应用的全链路模拟发布/扩容/缩容。
  • Virtual cluster 探测:探测 vc 虚拟集群的管控链路状态。
  • 联邦链路探测:探测联邦控制器相关链路的状态。
  • 节点通用探测:在集群每个节点上模拟调度一个探测 pod,探测节点侧链路状态。
  • ASI 客户端/服务端证书巡检:检查客户端/服务端证书有效性以及到期时间是否已超过告警阈值。
  • 全局风控限流巡检:检查各 ASI 集群是否已经推平并开启 KubeDefender 全局限流风控配置。
  • ······

3. KubeProbe 中心端管控

编写完成探测/巡检用例,并打包上传好镜像后,就需要在 KubeProbe 中心端注册这个用例模版,即将镜像注册进 KubeProbe 中心端的数据库中。

我们可以通过"渲染配置"参数传入一些指定的 env 环境变量到巡检/探测 pod 中,用于执行不同的业务逻辑,实现同一个用例模版生成多个用例。

最后通过统一的配置管控将用例和集群做绑定,配置对应的参数,执行各种下发逻辑。

6.png

同时,我们还在 KubeProbe 中心端做了大量权限安全管控,脏数据资源清理以及提效增速的工作(比如采用完全以 ownerreferences 的巡检/探测用例资源自动清理能力等等),这里不再赘述。

4. 打通发布 / 变更阻断

我们打通了 KubeProbe 探测与发布变更的关联,当对应集群中有任何变更发生时(如某组件在做发布),我们会自动通过相应的事件触发此集群绑定的所有巡检/探测用例,检查集群状态是否正常。如果探测失败,则会将变更阻断,降低爆炸半径,提升集群变更时稳定性。

5. 为什么不使用 Kuberhealthy

社区有一个 Operator 叫 Kuberhealthy 也可以做类似的事情,我们曾经也考虑采用,并且深度使用过 Kuberhealthy 和参与 kuberhealthy 的社区贡献,最终得出不适合的结论,主要原因是对大规模集群的支持较弱,同时高频调用时主流程卡死问题比较严重,不支持事件/手动单次触发特性,不支持统一上报数据中心等等,最终选择了自研自建的方式,目前来看是一个比较正确的选择。

一点小结果

KubeProbe 上线以来,实现探测/巡检用例几十个,在集团数百个 ASI 集群中运行千万余次,主动发现集群故障和问题百余次,其中某些小故障一旦没有发觉很有可能升级成为大故障,有效降低了系统风险。同时打通了变更/发布系统,提升了变更稳定性。并且在特殊故障时,多次先于业务方提前发现问题,更早地推动解决问题,客观降低了故障损失。

下面是一个具体例子:

  • 我们会接收到每个集群中各个组件的发布事件,由发布事件触发我们会在对应集群中运行相关的巡检/探测,比如调度一个定向的 pod 到某个节点组件发布的节点上去。我们发现 kube-proxy 的发布会导致节点的短暂不可用,调度上去的 pod 无法创建成功,从简单的返回/日志/集群事件上看不出具体的问题,并且持续复现。经过深入排查,得知是 kube-proxy 的问题,存在 netns 泄露。运行久了会泄露,当 kube-proxy 重启的时候,内核要清理 netns,会卡一段时间来清理,导致节点一段时间链路不通,pod 可以调度上去但是运行不起来,从而后续推进了 kube-proxy 的问题修复。

7.png

8.png

发现问题之后

1. KubeProbe 和数据监控的告警区别

KubeProbe 所面对的场景和数据监控不同,更多偏向于链路探测。

比如,监控告警一般的告警可能如下:

  • xx容器内存使用率 99%
  • webhook 双副本全部挂掉了
  • apiserver 三副本全部宕机了

这些告警,往往内容中就包含了具体的故障点,而 KubeProbe 的链路探测告警就有很多不一样,比如:

  • Statefulset 链路探测失败,Failed to create pod sandbox: rpc error: code = Unknown
  • etcd 全流程黑盒探测失败,context deadline exceeded
  • CloneSet 扩容失败,connect: connection refused

这些 KubeProbe 的告警往往比较难从字面看出到底这次巡检/探测是为什么失败了,我们往往需要根据相关的用例返回日志,巡检/探测 pod 日志,KubeProbe 相关集群事件综合排查,定位失败原因。

2. 根因定位

我们以比较混沌的 KubeProbe 探测失败告警作为线索,构建了一套 KubeProbe 自闭环的根因定位系统,将问题排查的专家经验下沉进系统中,实现了快速和自动的问题定位功能,一个简单的定位规则如下:

9.png

我们会通过普通的根因分析树以及对失败巡检探测事件/日志的机器学习分类算法(持续开发投入中),为每一个 KubeProbe 的探测失败 Case 做根因定位,并通过 KubeProbe 内统一实现的问题严重性评估系统(目前这里的规则仍比较简单),为告警的严重性做评估,从而判断应该如何做后续的处理适宜,比如是否自愈,是否电话告警等等。

3. Oncall 和 ChatOps

有了上面提到的根因定位以及告警严重性评估系统,我们使用了 nlp 告警机器人,实现了一套自动化的 Oncall 系统以及 ChatOps,展示一些使用的 case 如下,通过 ChatOps 和 Oncall 机器人,极大的降低了问题处理的复杂度,尽量用技术的手段解决重复的问题。

10.png

11.png

12.png

我们仍在路上

以上是我们在管理大规模 Kubernetes 集群中的一点经验,也解决了一些常见的问题,希望能对大家有所帮助。同时,这些工作在阿里云海量规模的场景下还需要持续打磨,我们仍在路上,并且将持续在路上。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
2月前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
249 1
|
2月前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
228 89
|
7月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
277 9
|
7月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
9月前
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
837 33
|
9月前
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
485 19
|
9月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
9月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
299 0
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
|
11月前
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。
|
10月前
|
运维 分布式计算 Kubernetes
ACK One多集群Service帮助大批量应用跨集群无缝迁移
ACK One多集群Service可以帮助您,在无需关注服务间的依赖,和最小化迁移风险的前提下,完成跨集群无缝迁移大批量应用。

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多