作者 | 彭南光(光南)
起源 | 阿里巴巴云原生公众号
千里之堤,溃于蚁穴。
绪论
不晓得大家是否经验过这样的情景:忽然被用户告知零碎呈现问题,而后一脸懵地惶惶然排查修复;或是等到本人发现零碎呈现故障时,理论曾经对用户造成了重大的恶劣影响。
所谓千里之堤,溃于蚁穴。用户信赖的建设是长期而艰巨的,然而要捣毁这种信赖却很简略。一旦呈现上述问题,不仅极大影响用户应用体验,同时会给用户留下一个这个产品 / 团队不牢靠的印象,丢失用户对产品 / 团队长期好不容易积攒下来的信用资本,将来再想建设这样的信赖关系就很难了。
这也是为什么咱们说疾速发现问题的能力如此重要的起因,只有先做到疾速发现问题,能力谈怎么排查问题、如何解决问题。
那么怎样才能在简单的大规模场景中,做到真正先于用户发现问题呢?上面我会带来咱们在治理大规模 ASI 集群过程中对于疾速发现问题的一些教训和实际,心愿能对大家有所启发。
注:ASI 是 Alibaba Serverless infrastructure 的缩写,是阿里巴巴针对云原生利用设计的对立基础设施。有趣味能够浏览:《揭开阿里巴巴简单工作资源混合调度技术面纱》。
背景
1. 简单的场景和曾面临的窘境
咱们所治理的大规模 ASI 集群场景非常复杂,这为咱们的工作带来了极大挑战,任何一个场景解决不慎就有可能导致意料之外的挫伤扩大化。
- 从组件维度看,咱们目前有几百个组件,每年有几万次的组件变更。频繁的组件变更如何在稳定性和效率之间获得衡量,怎么让变更时更稳固,怎么让灰度更确信,从而升高爆炸半径?
- 从集群维度看,目前有上千个集群和海量节点,碰到的集群 / 节点问题较多,监控链路笼罩比拟简约,怎么让集群运行时更加可信?
- 从二方用户和业务场景看,咱们反对了大量的团体二方用户,同时业务场景也非常复杂,怎么保障各有特色的业务场景都能失去统一的仔细关照?
2. 问题预判和解决思路
基于长期的集群治理教训,咱们有如下预设:
-
数据监控作为正向链路,无奈无死角笼罩所有场景。即便链路中各个节点的监控数据失常,也不能 100% 保障链路可用。
- 集群状态每时每刻都在变动,各个组件也在不停地更新降级,同时链路上的每个零碎也在不停的变更,监控数据的笼罩永远是正向的追赶,只能迫近 100% 全笼罩而无奈齐全达到。
- 即便整个集群链路中所有组件 / 节点的监控数据都失常,也不能保障集群链路 100% 可用。就如同业务零碎一样,看上去都是可用的,没有问题裸露。但只有通过全链路压测理论探测过整个链路后,能力失去理论可用的论断。
- 你要正向证实一个货色可用,须要举证有数的例子。而如果要反向证实不可用,一个反例就够了。数据监控链路只能迫近全笼罩,而无奈保障真正全笼罩。
-
大规模场景下,数据无奈达到 100% 的齐全一致性。
- 当集群规模足够大时,数据的一致性问题将会更加浮现。比方全局风控组件是否全集群链路笼罩?相干流控配置是否全集群链路推平?pod 主容器时区是否与下层统一?集群客户端节点证书是否有行将过期?等等问题,一旦忽略,将有可能酿成重大的故障。
只有补救上述两类危险点,能力有底气真正做到先于用户发现问题。咱们解决上述两类危险的思路别离是:
-
黑盒探测
- 所谓黑盒探测,既模仿狭义上的用户行为,探测链路是否失常。
-
定向巡检
- 所谓巡检,既查看集群异样指标,找到已有或可能将存在的危险点。
基于以上思路,咱们设计并实现了 KubeProbe 探测 / 巡检核心,用于补救简单零碎的正向监控的有余,帮忙咱们更好、更快地发现零碎危险和线上问题。
设计
黑盒探测和定向巡检
1)黑盒探测
不晓得你是否也经验过一条链路上各个系统监控数据都失常,然而理论链路流程就是跑不通。或者因为零碎变动快,监控笼罩不到 100% 的场景总是会有脱漏,导致影响到了用户却没有报警,对用户没有本质影响却报警频发从而疲于奔命。
如果一个零碎开发者本人都不应用本人的零碎,那么怎么可能先于用户发现零碎问题呢?所以要先于用户发现零碎问题,首先咱们本人就得先成为用户,而且肯定是应用最多,理解最深,无时无刻不在应用和感知零碎情况的用户。
所谓黑盒探测,就是让本人成为本人的用户,模仿狭义 ” 用户 ” 的行为去对集群 / 组件 / 链路期待待测对象做探测。留神,这里的 ” 用户 ” 并不仅仅是广义上应用零碎的同学,而是狭义用户。比方,etcd 的 ” 用户 ” 是 APIServer,而 ASI 的 ” 用户 ” 可能是某个通过 APIServer 操作集群的同学,也可能是 Normandy 发动的公布 / 扩容 / 缩容操作。
咱们心愿 KubeProbe 能在 变更时(监听到集群状态发生变化 / 组件变更 / 组件公布 / 系统升级等等事件)/ 运行时(周期,高频)/ 故障复原时(手动),通过周期 / 事件触发 / 手动触发,执行各种不同类型的黑盒探测,第一工夫感知组件 / 集群 / 链路的可用性。
以 etcd 集群的可用性来举例,咱们能够实现一个探测用例,逻辑是对 etcd 做 create/get/delete/txn 等等操作,并记录每个操作的成功率 / 耗费工夫,当成功率低于 100% 或耗费工夫超过容忍阈值后,触发报警。咱们将周期高频运行这个 etcd 的探测用例,同时对于 etcd 集群的任何变更都会收回一个事件 event 触发这个 etcd 探测立刻运行,这样就能尽量确保第一工夫发现 etcd 可用性故障了。同时,当 etcd 集群因为某些起因不可用了,咱们也能够通过手动触发等其余形式做探活,也能第一工夫失去是否复原的信息。
2)定向巡检
在大规模集集群 / 零碎场景下,数据一致性是肯定会面临的难题。数据不统一,将导致一些隐患,可能会在将来引发某些确定性的故障。
相比于黑盒探测面对的未知故障场景,定向巡检的指标是对集群的已知危险点做扫描。
咱们心愿 KubeProbe 可能定期对整个集群 / 链路做定向的巡检,找出这些数据不统一的点,判断数据不统一是否可能引发危险,从而可能防患于未然,治未病。
比方 etcd 冷热备多集群笼罩不全,可能导致集群遇到故障无奈疾速复原。那么咱们就定期对 etcd 的冷热备笼罩状况做定向巡检,找出没有笼罩推平的集群,并告警。比方 集群风控系统没有全集群链路笼罩,限流配置没有全集群链路推平,可能导致某些故障场景引发集群全面解体,咱们定期对风控配置全网扫描,判断是否可能导致故障,找出这些暗藏的已知危险点并告警。
实现
1. 架构
1)根本架构
KubeProbe 的根本实现架构大抵如下图,KubeProbe 核心端配置集群 / 集群组与巡检 / 探测用例 / 用例集之间的关联关系,负责对集群做具体某次探测实例下发。某个具体的巡检 / 探测用例下发到具体某个集群将应用用例的镜像创立一个 pod,这个 pod 里会执行若干巡检 / 探测逻辑,当执行实现后会回调核心端回写本次巡检 / 探测后果。其具体后果在核心端对立展现 / 告警,并提供给其余消费者生产(如反对 ASIOps 平台的公布阻断)。
2)高频架构
除了上述的根本架构之外,咱们对于高频探测用例(既探测周期短,触发频率须要十分频繁,甚至放弃无缝探测的场景)设计了一套集群内的分布式常驻探测架构,该架构通过集群内的 ProbeOperator 组件 watch 自定义对象 probeConfig 的变动,在集群内创立一个常驻的探测 pod,将继续无间断的运行探测逻辑,实现靠近无缝的继续探测,并将后果通过去噪 / 令牌桶限流等解决后,上报核心端,共给其余消费者生产。
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 中,用于执行不同的业务逻辑,实现同一个用例模版生成多个用例。
最初通过对立的配置管控将用例和集群做绑定,配置对应的参数,执行各种下发逻辑。
同时,咱们还在 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 的问题修复。
发现问题之后
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 自闭环的根因定位系统,将问题排查的专家教训下沉进零碎中,实现了疾速和主动的问题定位性能,一个简略的定位规定如下:
咱们会通过一般的根因分析树以及对失败巡检探测事件 / 日志的机器学习分类算法(继续开发投入中),为每一个 KubeProbe 的探测失败 Case 做根因定位,并通过 KubeProbe 内对立实现的问题严重性评估零碎(目前这里的规定仍比较简单),为告警的严重性做评估,从而判断应该如何做后续的解决合适,比方是否自愈,是否电话告警等等。
3. Oncall 和 ChatOps
有了下面提到的根因定位以及告警严重性评估零碎,咱们应用了 nlp 告警机器人,实现了一套自动化的 Oncall 零碎以及 ChatOps,展现一些应用的 case 如下,通过 ChatOps 和 Oncall 机器人,极大的升高了问题解决的复杂度,尽量用技术的伎俩解决反复的问题。
咱们仍在路上
以上是咱们在治理大规模 Kubernetes 集群中的一点教训,也解决了一些常见的问题,心愿能对大家有所帮忙。同时,这些工作在阿里云海量规模的场景下还须要继续打磨,咱们仍在路上,并且将继续在路上。