在 Ali Kubernetes 系统中,咱们这样实践混沌工程

在传统的软件测试中,咱们一般经过一个给定的条件来判断系统的反馈,经过断言来判断是否符合预期,测试条件和结果一般比较明确和固定。而混沌工程,是经过注入一些“不肯定”因素,象放进了一群淘气的猴子,在系统资源、可用性、安全性、延迟、压力等方面进行捣乱,而此过程当中,要求系统能够毫无影响的提供服务,用户无感知。node

这其实对系统的自愈能力,健壮性都有很高的要求。故障注入通常是指比较受控的一些实验条件,经过注入一些相对极端的异常场景,为系统提供可靠性测试的过程。 总体来讲,混沌是一种故障注入规则,强调了一些不肯定性、随机性,比较常见的"猴子"有 Netflix 的"猴子军团",能够用来随机关闭系统实例,注入延时,回收资源,检查安全漏洞等等。git

开源工具介绍

除了通常系统的 monkey,基于 Kubernetes 已经有一些"猴子"工具能够测试系统的健壮性。接下来,介绍一下比较常见的三种 Kubernetes monkey:github

kube-monkey

https://github.com/asobti/kube-monkeyjson

  • 运行方式:kube-monkey 经过 label 设置受害者 pod,建立了一个单独的 kube-monkey pod 对受害者 pod 施加影响;
  • 注入类型:目前支持的故障注入类型仅有杀容器;
  • 配置项:能够经过配置文件设置运行周期和频率,在必定时间内随机的杀死打标范围内的 pod。

powerfulseal

https://github.com/bloomberg/powerfulseal小程序

  • 注入类型:powerfulseal 的故障注入类型包括杀 pod 和启停 node。
  • 运行方式:包括交互模式,自动模式、打标模式和示例模式。交互模式经过界面交互查询node/namespace/pod,启停 node 或杀死 pod 操做;自动模式经过读取配置文件肯定注入范围,注入频率;打标模式经过给 pod 打标肯定注入的靶向 pod 及注入频率;示例模式能够反映根据使用资源状况进行故障注入的过程。

Chaos Toolkit-kubernetes

https://github.com/chaostoolkit/chaostoolkit-kubernetes
/>
是 chaos 工具包中的一个,经过 chaos run experiment.json 设置 json 文件来指定 namespace,正则匹配名字等等来随机杀一个 pod。
以上三种"猴子",主要是基于杀 pod 场景来注入故障,虽然是最有力的场面可是比较有局限性,对于商业化系统面临的复杂场景,是值得参考可是不够的。
api

结合 Ali Kubernetes 故障场景分析

Ali Kubernetes 做为一个管理大规模集群的商业调度系统,须要应对的不只包括一些基本的 Kubernetes 中 pod 误删误停的故障现象,也包含一些底层 OS、内核、网络、误配置等灾难场景。同时因为其支撑业务生态的复杂性,全链路综合异常流也须要特殊的验证。安全

为更系统的进行演练,在过程当中主要进行了如下几部分工做:网络

FMEA 分析就是失效模式和效果分析,旨在对系统范围内潜在的失效模式加以分析,以便按照严重程度加以分类,或者肯定失效对于该系统的影响。
从故障场景上,分析得出较为符合 Ali Kubernetes 的三大类场景:架构

  • 通用故障场景:包括网络相关故障(网络 iohang ,断网,网络延迟等),宿主机相关故障(机器重启,机器 load 高等)
  • Ali Kubernetes 业务场景故障:包括 Kubernetes 相关的故障(pod 删除,pod patch等),pod 迁移,混部、etcd 等业务相关场景;
  • chaos 故障:较为随机的故障注入,能够为以上任何故障的组合

从影响面上,须要 case by case 肯定影响范围为无任何影响,仅影响部分功能,影响核心功能等等;从验证恢复手段上,也能够分为自动恢复、手动恢复,同时须要关注监控状况及恢复时间。app

在分析过程当中,咱们发现,已有的开源工具没法彻底知足 Ali Kubernetes 的故障场景。下面举 2 个典型故障场景:

pod 被误删

这个场景并非简单的 pod 随机删除,而是在 kubelet 连错 apiserver 配置等异常状况下,重启 ali-kubelet 后,al 自行判断了容器在当前集群内不存在,本身作了删除操做。
要引入这个故障须要修改 kubelet 组件的配置,重启 kubelet,才算是真正引入了故障,而当前的不管是 kube-monkey 仍是 powerfulseal 场景都没法知足。

master 组件断网

有的人可能会说,直接指定 master 组件的机器引入断网操做,是否是就能够了呢?然鹅现实是比较骨感的,咱们也许只知道这个 master 所在集群的 kubeconfig,组件的机器其实也能够随着每次升级变更的。在仅仅已知 kubeconfig 的状况下咱们只能先查一下 master 组件的机器信息,再在机器上引入断网的操做,才算是一个总体的故障引入。而目前全部的开源工具也没有此类稍微复杂一些的场景,只是经过指定 pod namespace 来随机的删除一些 pod。
因此综上所述,其实咱们须要对此进行扩展开发,除了简单的杀 pod,咱们亟需一套能够自由开发的小程序,把这个步骤拼接起来,进行更为复杂的故障注入。

套件实现

为了知足此类复杂的故障注入,咱们使用了目前集团内正在开发的一套故障注入系统 monkeyking,并在它的基础上扩展了一些 kubernetes 相关的套件,来达到既能够注入 kubernetes 相关的故障,又能够注入一些通用故障,同时又能够相对自由的扩展故障集合的目的。

这个故障注入的演练流程以下图所示:

它的每个步骤均可以是咱们自由扩展的一个或者多个小程序,各个小程序之间的执行顺序也能够自由的定义。考虑到 Ali Kubernetes 的场景,咱们在其中扩展了四大类小程序套件。

通用故障小程序

在这一部分主要实现了一些比较通用的 os 故障,网络故障,好比最基本的指定一个宿主机断网,指定宿主机重启这类。

Kubernetes 套件小程序

这一部分主要实现了一些通用的 Kubernetes 命令,经过指定这些命令和入参,咱们能够执行好比 create delete apply patch 这些操做,来间接的达到注入一些 Kubernetes 相关故障的目的。
实现原理以下:

要点说明以下:

  • 下载集群证书的地址及证书的 md5 码都做为小程序的输入,在执行实际的 kubectl 生效命令前进行下载校验;
  • 底层 toolkit 中已经加入了 kubectl 命令行工具,无需本身找环境进行配置和下载;
  • 目前已经支持了 apply,create,delete,patch,get 操做,支持指定 label,namespace,-o json 的操做

举个例子,上文中 master 组件故障的场景中,咱们就能够利用以上的两类小程序来完成故障注入的操做:

开源工具小程序

目前咱们和集团安全生产的 MonkeyKing 团队合做,联合在故障注入平台 monkeyking 中集成了开源工具 kube-monkey,实现过程借助了上文的 kubernetes 套件执行,能够经过打标的方式标记受害者,让 kube-monkey 随机的杀受害者 pod。步骤以下:

环境准备

  • 锁演练环境
  • 在当前集群中初始化kube-monkey: 使用kubernetes套件的apply功能提交km-config.yaml文件,部署 kube-monkey deployment

给应用标记受害者 label

  • 使用 Kubernetes 套件的 patch 功能,标记受害者

验证步骤

  • 自定义组件校验应用服务是否可用

故障恢复

  • 使用 Kubernetes 套件的 patch 功能,给受害者去标
  • 使用 Kubernetes 套件的 delete 功能,删除 kube-monkey deployment
  • 解锁演练环境

其余业务相关小程序

这一部分比较自由,主要根据 Ali Kubernetes 的业务需求,接入了一些经常使用的小程序。

好比故障演练过程当中,环境须要独占,不容许其余测试执行,在这里实现了一个小程序用来对环境进行加解锁操做;好比校验阶段须要验证服务是否可用,这里实现了一个经过 curl 命令校验返回值的方式验证服务是否可用的小程序;好比故障注入过程可能影响vip挂载,这里也实现了一个调用 vip 服务校验 vip 下 ip 数量及是否可用的小程序。

总结

在 Ali Kubernetes 中,咱们将故障以场景化的方式进行沉淀,将底层 os,内核、网络、误配置等故障联合 Kubernetes 相关故障,引入混沌工程的理念进行注入,有效的发现了不少系统稳定性问题,驱动开发人员更多关注系统健壮性。

后续咱们会在 Ali Kubernetes  演进过程当中持续发力,基于架构和业务场景输入更多 Kubernetes 相关的故障场景,为系统的高可用保驾护航。

原文连接

相关文章
相关标签/搜索