Chaos Mesh —— 让应用跟混沌在 Kubernetes 上共舞

作者:殷成文

2019 年 12 月 31 日,我们在 GitHub 上正式开源了 Chaos Mesh。作为一个云原生的混沌测试平台,Chaos Mesh 提供在 Kubernetes 平台上进行混沌测试的能力。本篇文章将围绕 Chaos Mesh 起源及原理等方面进行介绍,并结合具体案例带领大家一起探索混沌测试的世界。

现实世界中,各类故障可能会随时随地的发生,其中有很多故障我们无法避免,例如磁盘突然写坏,或者机房突然断网断电等等。这些故障可能会给公司造成巨大损失,因此提升系统对于故障的容忍度成为很多工程师努力的目标。

为了更方便地验证系统对于各种故障的容忍能力,Netflix 创造了一只名为 Chaos 的猴子,并且将它放到 AWS 云上,用于向基础设施以及业务系统中注入各类故障类型。这只 “猴子” 就是混沌工程起源。

在 PingCAP 我们也面临同样的问题,所以在很早的时候就开始探索混沌工程,并逐渐在公司内部实践落地。

在最初的实践中我们为 TiDB 定制了一套自动化测试平台,在平台中我们可以自己定义测试场景,并支持模拟各类错误情况。但是由于 TiDB 生态的不断成熟,各类周边工具 TiDB BinlogTiDB Data MigrationTiDB Lightning 等的出现,测试需求也越来越多,逐渐出现了各个组件的的测试框架。但是混沌实验的需求是共有的,通用化的混沌工具就变的尤为重要。最终我们将混沌相关实现从自动化测试平台中抽离出来,成为了 Chaos Mesh 的最初原型,并经过重新设计和完善,最终于 Github 上开源,项目地址: https://github.com/pingcap/chaos-mesh

Chaos Mesh 能做些什么?

<center>使用 Chaos Mesh 注入 TiKV 节点宕机后发现 QPS 恢复时间异常问题</center>

这里以使用 Chaos Mesh 模拟在 TiKV 宕机的场景下观测业务 QPS 变化的实验为例。TiKV 是 TiDB 的分布式存储引擎。根据我们预期,大多数情况下 TiKV 节点宕机时, QPS 可能会出现瞬时的抖动,但是当 TiKV 节点恢复后 QPS 可以在很短的时候恢复到故障发生前的水位。从监控曲线上可以看出,前两次在 TiKV 节点恢复后,QPS 能够在短时间回到正常,但在最后一次实验中,在 TiKV 节点恢复后,业务的 QPS 并未在短时间内恢复到正常状态,这和预期不符。最后经过定位确认,当前版本(V3.0.1)的 TiDB 集群在处理 TiKV 宕机的情况下,的确存在问题,并且已经在新的版本里面修复,对应的 PR: tidb/11391, tidb/11344

上面描述的场景只是我们平时混沌实验中的一类,Chaos Mesh 还支持许多其他的错误注入:

  • pod-kill:模拟 Kubernetes Pod 被 kill。
  • pod-failure:模拟 Kubernetes Pod 持续不可用,可以用来模拟节点宕机不可用场景。
  • network-delay:模拟网络延迟。
  • network-loss:模拟网络丢包。
  • network-duplication: 模拟网络包重复。
  • network-corrupt: 模拟网络包损坏。
  • network-partition:模拟网络分区。
  • I/O delay : 模拟文件系统 I/O 延迟。
  • I/O errno:模拟文件系统 I/O 错误 。

背后的思考

从上面的介绍我们了解到,Chaos Mesh 的目标是要做一个通用的混沌测试工具,所以最开始我们就定下了几个原则。

易用性

  • 无特殊依赖,可以在 Kubernetes 集群上面直接部署,包括 Minikube
  • 无需修改应用的部署逻辑,理想的情况是可以在生产环境上进行混沌实验 。
  • 易于编排实验的错误注入行为,易于查看实验的状态和结果,并能够快速地对注入的故障进行回滚。
  • 隐藏底层的实现细节,用户更聚焦于编排自己需要的实验。

拓展性

  • 基于现有实现,易于扩展新的故障注入种类。
  • 方便集成到其他测试框架中。

作为一个通用的工具,易用性是必不可少的,一个工具不管功能如何多,如何强大,如果不够易用,那么这个工具最终也会失去用户,也就失去了工具的本身的价值。

另一方面在保证易用的前提下,拓展性也是必不可少。如今的分布式系统越来越复杂,各种新的问题层出不穷,Chaos Mesh 的目标的是当有新的需求的时候,我们可以方便去在 Chaos Mesh 中实现,而不是重新再造个轮子。

来点硬核的

为什么是 Kubernetes?

在容器圈,Kubernetes 可以说是绝对的主角,其增长速度远超大家预期,毫无争议地赢得了容器化管理和协调的战争。换一句话说目前 Kubernetes 更像是云上的操作系统。

TiDB 作为一个真 Cloud-Native 分布式开源数据库产品,一开始我们内部的自动化测试平台就是在 Kubernetes 上构建的,在 Kubernetes 上每天运行着数十上百的 TiDB 集群,进行着各类实验,有功能性测试,有性能测试,更有很大一部分是各种混沌测试,模拟各种现实中可能出现的情况。为了支持这些混沌实验,Chaos 和 Kubernetes 结合就成为了必然。

3.png

CRD 的设计

Chaos Mesh 中使用 CRD 来定义 chaos 对象,在 Kubernetes 生态中 CRD 是用来实现自定义资源的成熟方案,又有非常成熟的实现案例和工具集供我们使用,这样我们就可以借助于生态的力量,避免重复造轮子。并且可以更好的融合到 Kubernetes 生态中。

最初的想法是把所有的错误注入类型定义到统一的 CRD 对象中,但在实际设计的时候发现,这样的设计行不通,因为不同的错误注入类型差别太大,你没办法预料到后面可能会增加什么类型的错误注入,很难能有一个结构去很好的覆盖到所有场景。又或者最后这个结构变得异常复杂和庞大,很容易引入潜在的 bug。

所以在 Chaos Mesh 中 CRD 的定义可以自由发挥,根据不同的错误注入类型,定义单独的 CRD 对象。如果新添加的错误注入符合已有的 CRD 对象定义,就可以拓展这个 CRD 对象;如果是一个完全不同的错误注入类型,也可以自己重新增加一个 CRD 对象,这样的设计可以将不同的错误注入类型的定义以及逻辑实现从最顶层就抽离开,让代码结构看起来更加清晰,并且降低了耦合度,降低出错的几率。另一方面 controller-runtime 提供了很好的 controller 实现的封装,不用去对每一个 CRD 对象去自己实现一套 controller 的逻辑,避免了大量的重复劳动。

目前在 Chaos Mesh 中设计了三个 CRD 对象,分别是 PodChaos、NetworkChaos 以及 IOChaos,从命名上就可以很容易的区分这几个 CRD 对象分别对应的错误注入类型。

以 PodChaos 为例:

spec:
 action: pod-kill
 mode: one
 selector:
   namespaces:
     - tidb-cluster-demo
   labelSelectors:
     "app.kubernetes.io/component": "tikv"
 scheduler:
   cron: "@every 2m"

PodChaos 对象用来实现注入 Pod 自身相关的错误,action 定义了具体错误,比如 pod-kill 定义了随机 kill pod 的行为,在 Kubernetes 中 Pod 宕掉是非常常见的问题,很多原生的资源对象会自动处理这种错误,比如重新拉起一个新的 Pod,但是我们的应用真的可以很好应对这样的错误吗?又或者 Pod 拉不起来怎么办?

PodChaos 可以很好模拟这样的行为,通过 selector 选项划定想要注入混沌实验行为的范围,通过 scheduler 定义想要注入混沌实验的时间频率等。更多的细节介绍可以参考 Chaos-mesh 的使用文档 https://github.com/pingcap/chaos-mesh

接下来我们更深入一点,聊一下 Chaos Mesh 的工作原理。

原理解析

上图是 Chaos Mesh 的基本工作流原理图:

  • Controller-manager

    目前 controller-manager 可以分为两部分,一部分 controllers 用于调度和管理 CRD 对象实例,另一部分为 admission-webhooks 动态的给 Pod 注入 sidecar 容器。

  • Chaos-daemon

    Chaos-daemon 以 daemonset 的方式运行,并具有 Privileged 权限,Chaos-daemon 可以操作具体 Node 节点上网络设备以及 Cgroup 等。

  • Sidecar

    Sidecar contianer 是一类特殊的容器,由 admission-webhooks 动态的注入到目标 Pod 中,目前在 Chaos Mesh 中实现了 chaosfs sidecar 容器,chaosfs 容器内会运行 fuse-daemon,用来劫持应用容器的 I/O 操作。

整体工作流如下:

  1. 用户通过 YAML 文件或是 Kubernetes 客户端往 Kubernetes API Server 创建或更新 Chaos 对象。
  2. Chaos-mesh 通过 watch API Server 中的 Chaos 对象创建更新或删除事件,维护具体 Chaos 实验的运行以及生命周期,在这个过程中 controller-manager、chaos-daemon 以及 sidecar 容器协同工作,共同提供错误注入的能力。
  3. Admission-webhooks 是用来接收准入请求的 HTTP 回调服务,当收到 Pod 创建请求,会动态修改待创建的 Pod 对象,例如注入 sidecar 容器到 Pod 中。第 3 步也可以发生在第 2 步之前,在应用创建的时候运行。

说点实际的

上面部分介绍了 Chaos Mesh 的工作原理,这一部分聊点实际的,介绍一下 Chaos Mesh 具体该如何使用。

Chaos-mesh 需要运行在 Kubernetes v1.12 及以上版本。Chaos Mesh 的部署和管理是通过 Kubernetes 平台上的包管理工具 Helm 实现的。运行 Chaos Mesh 前请确保 Helm 已经正确安装在 Kubernetes 集群里。

如果没有 Kubernetes 集群,可以通过 Chaos Mesh 提供的脚本快速在本地启动一个多节点的 Kubernetes 集群:

// 安装 kind 
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.1/kind-$(uname)-amd64
chmod +x ./kind
mv ./kind /some-dir-in-your-PATH/kind 

// 获取脚本
git clone https://github.com/pingcap/chaos-mesh
cd chaos-mesh
// 启动集群
hack/kind-cluster-build.sh
本地启动的 Kubernetes 集群,网络相关的错误注入的功能会受到影响

等 Kubernetes 集群准备好,就可以通过 HelmKubectl 安装部署 Chaos Mesh 了。

git clone https://github.com/pingcap/chaos-mesh.git
cd chaos-mesh
// 创建 CRD 资源
kubectl apply -f manifests/
// 安装 Chaos-mesh
helm install helm/chaos-mesh --name=chaos-mesh --namespace=chaos-testing
// 检查 Chaos-mesh 状态
kubectl get pods --namespace chaos-testing -l app.kubernetes.io/instance=chaos-mesh

等 Chaos Mesh 所有组件准备就绪后,就可以尽情的玩耍了!

目前支持两种方式来使用 Chaos-mesh。

定义 Chaos YAML 文件

通过 YAML 文件方式定义自己的混沌实验,YAML 文件方式非常方便在用户的应用已经部署好前提下,以最快的速度进行混沌实验。

例如我们已经部署一个叫做 chaos-demo-1 的 TiDB 集群(TiDB 可以使用 TiDB Operator 来部署),如果用户想模拟 TiKV Pod 被频繁删除的场景,可以编写如下定义:

apiVersion: pingcap.com/v1alpha1
kind: PodChaos
metadata:
  name: pod-kill-chaos-demo
  namespace: chaos-testing
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - chaos-demo-1
    labelSelectors:
      "app.kubernetes.io/component": "tikv"
  scheduler:
    cron: "@every 1m"

创建包含上述内容的 YAML 文件 kill-tikv.yaml 后,执行 kubectl apply -f kill-tikv.yaml , 对应的错误就会被注入到 chaos-demo-1 集群中。

上图 demo 中 sysbench 程序一直在对 TiDB 集群进行测试,当将错误注入到集群后,sysbench QPS 出现明显抖动,观察 Pod 发现,某一个 TiKV Pod 已经被删除,并且 Kubernetes 为了 TiDB 集群重新创建了一个新的 TiKV Pod。

更多的 YAML 文件示例参考:https://github.com/pingcap/ch...

使用 Kubernetes API

Chaos Mesh 使用 CRD 来定义 chaos 对象,因此我们可以直接通过 Kubernetes API 操作我们的 CRD 对象。通过这种方式,可以非常方便将我们的 Chaos Mesh 应用到我们自己的程序中,去定制各类测试场景,让混沌实验自动化并持续运行。

例如在 test-infra 项目中我们使用 Chaos Mesh 来模拟 ETCD 集群在 Kubernetes 环境中可能出现的异常情况,比如模拟节点重启、模拟网络故障、模拟文件系统故障等等。

Kubernetes API 使用示例:

import (
    "context"
    
    "github.com/pingcap/chaos-mesh/api/v1alpha1"
    "sigs.k8s.io/controller-runtime/pkg/client"
)

func main() {
    ...
    delay := &chaosv1alpha1.NetworkChaos{
        Spec: chaosv1alpha1.NetworkChaosSpec{...},
    }
    k8sClient := client.New(conf, client.Options{ Scheme: scheme.Scheme })
    k8sClient.Create(context.TODO(), delay)
    k8sClient.Delete(context.TODO(), delay)
}

聊聊未来

除了上面介绍的几种 infrastructure 层的 Chaos 外,我们还可以注入更宽和更细粒度层面的故障类型。

借助 eBPF 以及其他工具,我们可以在系统调用以及内核层面注入特定的错误,也能更方便地模拟物理机掉电的场景。

通过整合 failpoint,我们甚至可以注入特定的错误类型到应用函数以及语句层面,这将极大的覆盖常规的注入方式难以覆盖到的场景。而最吸引人的是这些故障注入都可以通过一致的接口注入到应用和系统层面。

另外我们将支持和完善 Chaos Mesh Dashboard,将故障注入对业务影响更好地进行可视化,以及提供易用的故障编排界面,帮助业务更容易地实施故障注入,理解应用对不同类型错误的容忍和故障自恢复的能力。

除了验证应用的容错能力,我们还希望量化业务在故障注入后的恢复时长,并且将 Chaos 能力搬到各地云平台上。这些需求将会衍生出 Chaos Mesh Verifier,Chaos Mesh Cloud 等等其他紧绕 Chaos 能力的各种组件,以对分布式系统实施更全面的检验。

Come on! Join us!!

说了这么多,最后也是最重要的,Chaos Mesh 项目才刚刚开始,开源只是一个起点,需要大家共同参与,一起让我们的应用与混沌在 Kubernetes 上共舞吧!

大家在使用过程发现 bug 或缺失什么功能,都可以直接在 GitHub 上面提 issue 或 PR,一起参与讨论。

Github 地址: https://github.com/pingcap/chaos-mesh

Image placeholder
spolarbear
未设置
  21人点赞

没有讨论,发表一下自己的看法吧

推荐文章
Kubernetes 基础信息:什么是 Kubernetes?

简介 Kubernetes(常简称为K8s,在希腊语意为“舵手”或“驾驶员”)是用于自动部署、扩展和管理容器化(containerized)应用程序的开源系统。 由JoeBeda、BrendanBur

Twitter 宣布抛弃 Mesos,全面转向 Kubernetes

作者|阿里云智能高级技术专家张磊划重点Twitter的基础设施从Mesos全面转向Kubernetes阿里云容器平台团队即将开源 Kubernetes高级作业管理集合美国西部时间5月2日下午7点,Tw

当Kubernetes成为云操作系统的标准应用,AWS也亮出了“杀手锏”!

作为云计算领域的排头兵,AWS一直是“老大哥”形象,他的一举一动都牵动着无数人的神经。AWS不仅在云计算领域投入时间早、运行时间长、客户多,在无服务器、容器以及现代化应用工具开发方面,也是当之无愧的引

一小时快速搭建基于阿里云容器服务-Kubernetes的Web应用

本文面向的读者如果您是一个Kubernetes的初学者,本文可以帮助你快速在云上搭建一个可实际使用的集群环境,并发布自己的第一个应用。你无须提前准备任何的硬件资源或者下载任何的软件包。 如果您已经有一

为什么说谷歌Anthos是kubernetes的翻版?

在本周纽约的一次会议活动中,谷歌谈到了Anthos。那么,Anthos到底是什么?有哪些新功能?本文将逐一解答!什么是Anthos?从官方资料来看,Anthos是谷歌的混合云平台,主要作用是保护客户的

【Kubernetes系列】第5篇 Ingress controller – traefik组件介绍

1.概述为了能够让Ingress资源能够工作,在Kubernetes集群中必须至少有一个运行中的ingresscontroller组件。也就是说如果在kubernetes集群中没有一个ingressc

披荆斩棘:论百万级服务器反入侵场景的混沌工程实践

在繁杂的业务和网络环境下,在公司百万级服务器面前,要做到入侵发生时的及时检测,那么反入侵系统的有效性,即系统质量,是至关重要的。洋葱系统是腾讯公司级的主机反入侵安全检测系统,它是实现了前端主机agen

云端的生存之道,第 1 单元:将 Spring Boot 部署到 Kubernetes

初始化Kubernetes集群 第一步是初始化IBMCloud上的Kubernetes集群。IBMCloud可能需要几分钟时间来启动新的Kubernetes集群;因此,通过先执行初始化操作,可以在后台

我如何将博客迁移到 Kubernetes(上)

最近Kubernetes的发展,以及在我司的大量应用,自己也迫不及待想要尝尝鲜,虽然我的博客是基于Hexo的纯静态站点,但这并不能阻挡我把它迁移上Kubernetes!毕竟...相比于GitHubPa

我如何将博客迁移到 Kubernetes(下)

前面的部分介绍了如何为我的博客打包Docker镜像,接下来就是重头戏——部署到Kubernetes。 GoogleKubernetesEngine 没错,我现在自用的Kubernetes集群就是

使用 Kubernetes 来部署你的 Laravel 程序

说明 Laravel是开发PHP应用程序的优秀框架。无论您是需要构建新想法的原型,开发MVP(最小可行产品)还是发布成熟的企业系统,Laravel都可以促进所有开发任务和工作流程。 如何处理部署应用

为什么说Kubernetes的崛起预示着云原生时代到来?

现在,云原生、Kubernetes已经成为企业IT领域的时髦概念,几乎所有的企业都在关注;如果不提这些概念,好像企业就会在云市场竞争中失去绝对话语权。那么,云原生和Kubernetes是怎样一种关系?

美团点评Kubernetes集群管理实践

背景作为国内领先的生活服务平台,美团点评很多业务都具有非常显著、规律的“高峰”和“低谷”特征。尤其遇到节假日或促销活动,流量还会在短时间内出现爆发式的增长。这对集群中心的资源弹性和可用性有非常高的要求

如何应对Kubernetes中的存储管理挑战?

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。对于那些工作负载多样化、不断变化的企业来说,使用Kubernetes是非常有利的。与容器一样,

Kubernetes监控在小米的落地

本文介绍了高可用、持久存储、可动态调整的Kubernetes监控方案的实现过程。小米的弹性调度平台(Ocean)以及容器平台主要基于开源容器自动化管理平台kubernetes(简称k8s)来提供服务,

K8s有多热?传统银行转型拥抱Kubernetes案例

Kubernetes已经成为标准的基础设施API,像RedHat、Mesosphere(现在的D2IQ)和Pivotal等供应商都无法避免。如果您希望使企业能够合理构建应用程序,那么Kubernete

Spark in action on Kubernetes – 存储篇

作者|阿里云智能事业群技术专家莫源前言在上篇文章中,SparkinactiononKubernetes–SparkOperator的原理解析我们分析了SparkOperator内部的机制,今天我们会讨

如何在生产环境中部署Kubernetes集群?

如果把kubernetes集群应用于生产环境中,需要做哪些准备?我们先要弄清楚一个词,什么是“生产就绪”?生产就绪,是我们经常听到的一个专业术语,大概意思是已经准备好并已处于即将生产的状态。但是,到底

Kubernetes 未来一年会有哪些变化?

试图预测历史上发展最快的开源项目的未来几乎是徒劳的,从谷歌到社区其他成员的“传承”已经发展成为编排的实际标准,从来没有一个项目以这种方式获得了整个企业社区的集体支持。从CNCF成员的长名单就可以看出,

Kubernetes1.14 版发布,增强了云原生平台的Windows节点支持

Kubernetes1.14GA版本,是开源云原生平台Kubernetes在2019年的一次重大更新。自3月25日开始,这一版本正式推出,供开发者全面使用。  Kubernetes,由云原生计算基金会

白话 Kubernetes 基础概念

Kubernetes简介微服务框架的流行,使得服务越来越精细化,服务也变的越来越多,对于发布和管理而言产生了巨大的挑战,而Docker的诞生,给与微服务的资源治理和控制提供了很好的基础。容器化可以解决

理解Kubernetes网络:pods篇

这篇文章将试图揭开在kubernetes集群中运行的网络的多层神秘感。Kubernetes是一个功能强大的平台,其中包含许多智能的设计选择,但讨论交互的方式可能会造成混淆:Pod网络,服务网络,集群I

pymysql fetchone () , fetchall () , fetchmany ()

最近在用python操作mysql数据库时,碰到了下面这两个函数,标记一下: 1.定义 1.1fetchone(): 返回单个的元组,也就是一条记录(row),如果没有结果则返回None 1.2fet

笨办法学 Linux Bash:Shell、`.profile`、`.bashrc`、`.bash_history`

Bash:Shell、.profile、.bashrc、.bash_history。 当使用CLI(命令行界面)来使用Linux时,你正在与一个名为shell的程序进行交互。所有你输入的都传递给she

解读 KubeCon EU 2019 应用管理领域的新看点

作者 |阿里云智能事业群技术专家邓宏超划重点阿里云容器平台技术专家、原CoreOS公司工程师、K8sOperator项目的核心作者之一邓洪超,精彩解读KubeConEU2019“应用管理“领域精华内容