作者:于畅,王相
Chaos Mesh 曾经开源一周年了,目前是 CNCF 的 sanbox 我的项目,在国内外倒退良好,有了很多的 Contributor 和关注度。
然而目前 Chaos Mesh 依然存在一些须要持续建设的方面:
- 须要持续进步易用性。目前有些 Chaos 的性能较为简单,用户在创立 Chaos 试验后,可能还须要人工确认试验是否失效,须要改良 Metrics 以及与监控零碎的联动。
- 次要反对 K8s 环境。目前 Chaos Mesh 次要针对 K8s 环境设计的,而且每个 K8s 集群都须要部署一个 Chaos Mesh,无奈对立进行治理。另外,反对物理机的混沌试验工具 Chaosd 反对的性能无限,而且通过命令行注入试验的形式对用户不太敌对。
- 暂不反对插件。目前增加自定义 Chaos 只能通过批改源码,暂不反对插件以及 Go 以外的语言,不利于新 Chaos 性能的扩大。
- 没有原生反对编排。目前能够通过 Argo 来做编排,然而还不够易用。Chaos Mesh 打算是在 V2.0 版本反对原生编排,这样也能够闭环做一些回调操作。
总体来说,Chaos Mesh 间隔 Chaos Engineering as a Service 还须要持续建设,并且还有很大的设想空间。
混沌工程即服务(Chaos Engineering-As-a-Service)
文章 The benefits of chaos engineering-as-a-service 是这么定义的:
CAAS(ChaosEngineering-As-a-Service)意味着能够疾速的看到直观的图形化界面,开箱即用的集成所有须要进行试验的货色。
业界也有基于 CAAS 提供服务的厂商,比方 Germlin。
我的解读,Chaos Engineering as a Service 须要有一个对立的治理入口,能够便捷地通过界面操作,填写配置,创立 Chaos 试验;能够看到试验的状态和一些监控指标数据,比照工作周期的成果;能够做一些暂停、归档等操作治理试验;能够拖拽式编排 Chaos 试验。
目前曾经有一些公司基于本人实在的需要对 Chaos Mesh 进行了“魔改”,让它更像 Chaos Engineering as a Service,比方网易伏羲、FreeWheel。另外咱们也在 TiDB Hackathon 2020 的较量中做了一个相干的课题,大抵有了 Chaos Engineering as a Service 的雏形。
TiDB Hackathon 2020 的实际
架构革新
基于 Chaos Engineering as a Service 的理念,咱们对 Chaos Mesh 进行革新。Chaos Mesh 目前的架构比拟适宜单 K8s 集群应用,而且是只针对 K8s 环境设计的。架构图如下:
咱们对 Chaos Mesh 的架构进行了简略的调整,将 Dashboard 独立进去,不再与某个特定的 K8s 环境绑定。如果 Dashboard 部署在 K8s 集群外,则通过界面增加 K8s 集群;如果 Dashboard 部署在集群内,则能够通过环境变量主动获取集群信息。
能够通过 Dashboard 注册 Chaos Mesh(理论注册的是 K8s 配置),Chaos Mesh 的 Controller Manager 组件也能够通过配置被动向 Dashboard 被动注册。Dashboard 与 Controller Manager 的交互通过 CRD 来实现。Controller Manager 监听到有 chaos-mesh 的 CRD 事件后,会调用 Chaos Daemon 做相应的 chaos 试验操作,因而只有 Dashboard 能够操作 CRD,即可实现对 Chaos 试验的治理。
运行在物理机上的 Chaosd,本来是命令行的模式,而且性能比拟繁多。
咱们革新了 Chaosd,反对 RESTful API。将 Chaosd 的服务模式进行了加强,能够通过解析 CRD 格局的 JSON/YAML 来配置 Chaos 试验。
Chaosd 能够通过配置被动向 Dashboard 注册,减少 heartbeat 机制,在注册到 Dashboard 后,定期向 Dashboard 发送心跳,不便 Dashboard 保护 Chaosd 节点状态。同时,也能够应用 Dashboard 界面增加 Chaosd 节点。
咱们也给 Chaosd 减少了定时调度与试验生命周期治理,实现 K8s 环境所具备的性能,对立 K8s 环境与物理机环境。
革新之后的 Chaos Mesh 架构如下:
要解决的另外一个问题是如何判断 Chaos 试验是否失效。以负载试验为例,在注入了 StressChaos 之后,须要进入到试验选取的 Pod 中,查看是否有 stress-ng 的过程,再应用 top 等系统命令查看 CPU 和内存耗费,这样能力确定 Chaos 试验注入胜利了。
革新后,在 Chaos Daemon、Chaosd 中集成了 node_exporter,实现节点 Metrics 采集;K8s 集群内部署 kube-state-metrics,联合 cadvisor,实现 K8s Metrics 采集。配合 Prometheus + Grafana 即可实现对 Metrics 监控,基于 Metrics 监控能够便捷的查看试验后果状态。
一些不足之处
Metrics 次要是解决三个问题:
- 如何观测 Chaos 被胜利注入
- 如何观测 Chaos 注入当前对于服务的影响,并能做周期性的比照
- 异样 Chaos 事件的相应
综上,可能须要从三个方面动手,试验数据 Metrics、失常指标监控、试验 Event。也就是说,目前还欠缺:
- 试验数据 Metrics,例如注入网络提早的具体延迟时间、模仿负载的具体模仿值等等。
- 试验 Event,试验创立、删除、运行周期的 K8s Event。
能够参考 https://github.com/litmuschaos/chaos-exporter#example-metrics。
一些“可用的”工具及构想
编排
残缺的试验闭环,既须要有对 Chaos 的摸索,又须要对试验后果做相应的解决,并反馈给混沌工程零碎
目前开源的 Chaos 工具,大多都只做了无限的摸索,短少后续的反馈。基于可观测性组件,能够实时感知 Chaos 试验的后果,基于试验后果数据做比照与剖析。
反馈与闭环,另一个重要组件的就是试验的编排与治理。目前社区曾经有了相干的 WorkFlow 提案,以及基于提案的相应实现。基于 WorkFlow,能够很轻松的实现对 Chaos 试验的编排、回调,也能够很不便的和其余零碎进行联动。例如,能够在 CI/CD 阶段跑 Chaos;能够在执行灰度 / 金丝雀公布后跑 Chaos。
同时,最重要的是能够让 Chaos 试验实现闭环。比方对某个 Pod 进行网络提早测试,提早是 100ms。通过可观测性组件能够轻松观测到网络提早的变动,同时基于编排能够应用 PromQL 或者其余 DSL 查问到这个 Pod 的服务是否可用。假如服务服务不可用,就会失去一个论断,当提早大于等于 100ms 的时候,服务不可用。但这远远不够,因为 100ms 不是阈值,更须要一个绝对精确的阈值来保障服务的 SLO,而恰好能够通过编排批改 Chaos 试验的试验值来重复试验。同时,也须要晓得服务在不同网络提早下的体现,以及是否能达到预期。
通过编排再来看混沌工程
混沌工程和和故障测试相似。故障测试通过对事后构想到的能够毁坏零碎的点进行测试,然而并没能去探索上述这类更广大畛域里的、不可预知的、但很可能产生的事件。在测试中,要进行断言:即给定一个特定的条件,零碎会输入一个特定的后果。
故障测试一般来说只会产生二元的后果,验证一个后果是真还是假,从而断定测试是否通过。严格意义上来说,这个实际过程并不能发掘出零碎未知的或尚不明确的认知,它仅仅是对已知的零碎属性可能的取值进行测验。
试验能够产生新的认知,而且通常还能开拓出一个更广袤的对简单零碎的认知空间。故障注入则是对一个特定的条件、变量的验证办法。混沌工程是发现新信息的实际过程。
数据格式
CRD 其实很好的提供了一种对数据格式定义的形式。基于 chaos-mesh 的 CRD,转换成 JSON,即可实现在组件间通信。
站在数据格式的角度看 Chaosd,其实 Chaosd 只是对 CRD 数据 (JSON 格局) 的生产与注册。那么,是否有这样一种可能,只有实现对 CRD 数据的生产以及本身状态的注册,即可实现或笼罩不同场景的 Chaos 试验。
插件
Chaos Mesh 目前对插件反对比拟无限,只能通过扩大 CRD 的模式,具体可见官网文档。
但这样就会有两个问题:
- 开发者必须应用 Golang 来做扩大开发,对开发者还是有肯定要求的,尽管 Golang 是高级 PHP(PHP 是世界上最好的语言)。
- 扩大的代码须要合进我的项目,合进主代码又有可能引发额定的危险,毕竟没有 BPF 那种平安机制(是不是文章中蕴含 BPF 就能蹭一波热度)。
可能须要摸索一种魔 (ye) 幻(lu)的 (zi) 插件形式。基于 Go 的插件,HashiCorp 出过一个 go-plugin,但还是基于 Go。回归实质,Chaos Mesh 其实是基于 CRD 进行 Chaos 试验。也就是说,只有可能生成、监听解决、删除 CRD 就能够实现混沌试验。基于 client-go?开发 Controller、Operator 操作 CRD?不,还有其余好 (ye) 办(lu)法(zi)。
能够对立解决 CRD 事件,而后通过 HTTP 回调的模式实现对 CRD 的操作,能够不应用 Golang,有 HTTP API 即可。思路略向上文数据格式中提及的局部。开源实现的相干参考 Whitebox Controller。
只是 HTTP Hook 可能还够,还有更好的野路子,比方 Wasm。须要调用 Chaos 试验逻辑的时候调用 Wasm 程序就好啦。业界也基于 Wasm 做插件的例子能够参考,比方 Vector 的 WASM Transform。BTW,TiDB Hackathon 2020 上的 TiDB UDF 就是用 Wasm 实现的。
通过命令行、API、面板查看 Chaos 试验的状态太繁琐?试试 SQL?再次回归实质,Chaos Mesh 是基于 CRD 的,那么只有能读取、操作 CRD 即可。应用 SQL 操作 K8s 的开源计划还是有一些的,比方 Presto 的 connector,osquery 的扩大等等。
业界也有一些基于 SDK 的扩大形式,比方 Chaos Toolkit。
交融其余混沌工具
与现有的 Chaos 工具联合会让整体的生态更弱小,毕竟用户的 Chaos 场景可能很难穷尽。
例如,Litmus 的 K8s 实现是基于 PowerfulSeal 的,Litmus 的容器实现是基于 Pumba 的。
当然还有针对 Kubernetes 的 Kraken、针对 AWS 的 AWSSSMChaosRunner、针对 TCP 的 Toxiproxy 等等。也有比拟新潮的,例如基于 Envoy 的、基于 Istio 的。生态还是比拟丰盛的,暂不一一例举。可能须要一种通用的模式,来治理如此之前的场景。业界也有一些开源的参考,比方 Chaos Hub。
一些“实践经验”
其实是在 360 的野路子瞎搞。整体架构还是围绕 K8s 的,大部分性能基于 Chaos Mesh 魔改。
物理节点层面:
- 反对执行物理机执行自定义脚本。CRD 配置脚本门路,通过 Chaos Daemon 运行自定义 Shell 脚本,但须要特权模式运行容器,不是很敌对。
- 基于自定义 Shell 脚本模仿 reboot、shutdown、Kernel Panic。
- 基于自定义 Shell 脚本将节点网卡 down 掉(随机 down 调节点,可能会造成物理机启动失败)。Shell 脚本内实现 ifdown、ifup 即可。
- 应用 sysbench 制作上下文频繁切换。模仿“吵闹的街坊”。
- 基于 BPF 的 seccomp 实现对容器的零碎调用拦挡。传递 PID,基于 PID 过滤即可。
容器层面:
- 随机批改 Deployment 的正本数量,测试利用的流量是否有异样。
- 基于 CRD 对象嵌套,在 Chaos CRD 中填写 Ingress 对象,模仿接口限速。
- 基于 CRD 对象嵌套,在 Chaos CRD 中填写 Cilium Network Policy 对象,模仿网络时好时坏。
业务层面:
- 反对自定义 Job。目前 Chaos Mesh 次要是基于 Chaos Daemon 实现注入,不具备调度的公平性以及亲和性,通过 Controller Manager 针对不同的 CRD 类型,间接创立 Job 即可实现。
- 自定义 Job 跑 Newman,随机批改 HTTP 参数。实现 HTTP 接口层面的 Chaos 试验,模仿用户异样行为。
综上,是一些对 Chaos 的集体高见、对 Chaos Mesh 的痴心妄想、基于 Chaos Mesh 的野路子混沌工程零碎落地实际。全文仅供参考,不倡议在生产环境模拟应用,如造成混沌状态,纯属巧合。
“遗记你曾经学到的。”— Yoda
一些能够浏览的材料
- https://principlesofchaos.org/zh/
- https://netflixtechblog.com/the-netflix-simian-army-16e57fbab116
- https://medium.com/better-practices/chaos-d3ef238ec328
- Learning Chaos Engineering: Discovering and Overcoming System Weaknesses through Experimentation
- Chaos Engineering: System Resiliency in Practice
- Chaos Engineering Observability