行为驱动的混沌测试与 AWS 故障注入模拟器 架构博客

产品展示

23

使用 AWS 故障注入模拟器进行行为驱动混沌实验

作者:Richard Whitworth 和 Greg Willson日期:2024年1月29日发布平台: Amazon EC2 Customer Solutions永久链接

关键要点

组织面临的主要挑战之一是如何确保其工作负载的持续韧性。通过 AWS Fault Injection SimulatorFIS和可理解的语言构建混沌实验可以帮助解决这一问题。本文将介绍通过 Gherkin 语法定义混沌实验的范例,旨在增强非技术干系人对实验过程的理解。

在当今的数字化环境中,确保工作负载的持续韧性是每个组织都面临的重要挑战。现代混沌工程原理可以帮助克服这种挑战,但其复杂性常常使得非技术干系人难以理解输入和输出的定义本质。在本篇文章中,我们将探讨如何利用人类可读的语言、AWS 故障注入模拟器FIS以及开发人员和测试工程师所熟悉的框架来构建混沌实验。这种方法将帮助你以更具吸引力和可理解的方式产生可审计的证据,证明你的工作负载的持续韧性。

如果你对混沌工程、其过程和好处不太了解,可以先阅读 关于工作负载韧性的架构博客文章 以增进了解。

混沌实验属性

一个完整的混沌实验应具备以下属性:

属性描述定义的稳定状态明确描述混沌实验的起始状态假设提出该实验要验证的假设定义变量和实验动作明确实验中将会进行哪些操作假设验证验证假设是否成立

将 FIS 与 Behave 结合

FIS 使你能够创建上述混沌实验属性中列出的实验动作。使用 FIS 的动作可以模拟对工作负载的干扰,从而观察其结果并获取有价值的洞察。然而,在编写全面的混沌实验时,还应定义其他一些属性。

结合 Python 风格的 Behave 与 FIS,便能实现这一点其他行为驱动开发框架也适用于不同语言。通过这种方式进行混沌实验,你可以将所有实验属性如假设、稳定状态和假设验证以人类可读的 Gherkin 语法进行编码,然后在代码中自动化整个实验。

使用 Gherkin 语法使非技术干系人能够审查、验证并参与混沌实验,同时确保这些实验能够根据业务成果和角色进行驱动。如果你一切都以代码的形式定义,那么整个过程就可以嵌入 CI/CD 管道的适当阶段,以确保现有实验始终被运行,从而避免回归错误。你还可以在工作负载中启用新业务功能或意识到潜在的新干扰时,迭代地添加新的混沌实验。此外,使用 Behave 这样的行为驱动开发BDD框架,也让开发人员和测试工程师能够快速交付功能,因为他们已经对 BDD 和 Behave 熟悉。

接下来的部分将提供这个方法的具体示例,展示如何构建可以扩展的实验来满足自己的工作负载需求。文中使用的代码和资源可在 AWS Samples 的 awsfisbehaviourdrivenchaos 仓库中找到,该仓库提供了构建我们混沌实验目标工作负载的 CloudFormation 模板。

所构建的工作负载包括一个具有公共子网的 Amazon Virtual Private Cloud,一个EC2自动扩展组,以及运行 NGINX 的 EC2 实例。CloudFormation 模板还会创建一个 FIS 实验模板,包含标准 FIS Amazon Elastic Compute Cloud (Amazon EC2) 操作。对于您自己的实现,我们建议将 FIS 的 CloudFormation 与构建工作负载的 CloudFormation 分开,以便进行独立维护。为了简便起见,在本博客中,它们被放在同一代码库中。

注意: 仓库中的 Behave 代码结构是我们建议您为自己的代码库采用的方式。它将场景定义与步骤的 Python 特定实现分开,进而将步骤的大纲与步骤的辅助方法分开。这将使您能够构建可重用的步骤辅助方法,随时调用或嵌入任何 Behave 步骤中。这样有助于确保您的测试代码库保持 DRY 和高效,尤其在其规模增长时。这对于大型测试框架而言是非常具挑战性的。

接下来,我们将定义和启动混沌实验。

定义和启动混沌实验

我们首先使用 Gherkin 语法定义我们的混沌实验,并利用 Gherkin 的 场景 来阐明实验的假设,如下:

gherkin场景:我的网站能抵抗基础设施故障

假设 我的网站在线,能够处理每秒10个交易并且 我有一个包含至少3个正在运行的EC2实例的自动扩展组并且 我有一个在至少3个可用区分布的EC2自动扩展组当 一个EC2实例丢失然后 我仍然可以继续处理每秒10个交易并且 我网站90的交易成功

我们的初始 假设、以及 步骤验证了启动 场景所需的条件和环境是适合的即稳定状态。因此,如果在我们开始之前环境已经超出范围例如:网站未运行,测试将无效,我们不想产生假阳性结果。由于步骤是通过 Behave 以代码格式表述的,因此测试报告会展示导致实验失败的实际原因,并能识别出是环境问题假阳性还是我们在混沌实验中对工作负载响应的真实预期没有实现的正性失败。

上述的 假设、以及 步骤使用 步骤 中的示例来执行。步骤调用相应的 步骤助手 函数。请注意,场景中的短语在 stepimpl 函数的装饰器中得到了体现;这就是将可读语言与 Python 代码连接起来,启动测试逻辑的方式。

python@step(我的网站在线,能够处理 {number} 个交易每秒)def stepimpl(context number) target = fhttp//{contextconfiguserdata[websitehostname]} loggerinfo(f正在向目标网站 {target} 发送流量,请等待60秒) sendtraffictowebsite(target 60 beforechaos int(number)) assert verifylocustrun(int(number) beforechaos) is True

一旦 假设、以及 步骤成功启动,我们就验证了实验条件的适当性。接下来,通过 当 步骤启动混沌动作。在这里,我们使用 boto3 交互 FIS,启动先前使用 CloudFormation 创建的实验模板。以下代码片段展示了如何启动这一步骤:

python@step(一个 EC2 实例丢失)def stepimpl(context) if fis not in contextclients createclient(fis context)

state = startexperiment(    contextclients[fis] contextconfiguserdata[fisexperimentid])[experiment][state][status]loggerinfo(fFIS 实验状态 {state})assert state in [running initiating]

行为驱动的混沌测试与 AWS 故障注入模拟器 架构博客

此处使用的实验模板故意是一个非常简单的单步骤实验,作为本博客的示例。FIS 允许您创建非常复杂的多步骤实验,详见 AWS FIS 操作参考。

现在实验正在进行中!我们启动了 然后、和 的步骤来验证在 场景 中表达的假设。接下来,我们查询网站端点,查看是否有请求失败:

python@step(我仍然可以继续处理 {number} 个交易每秒)def stepimpl(context number) target = fhttp//{contextconfiguserdata[websitehostname]} loggerinfo(f正在向目标网站 {target} 发送流量,请等待60秒) sendtraffictowebsite(target 60 afterchaos int(number)) assert verifylocustrun(int(number) afterchaos) is True

@step({percentage} 百分比的交易成功到我的网站)def stepimpl(context percentage) assert successpercent(int(percentage) afterchaos) is True

你可以根据需要添加更多的 假设、当、然后 步骤来验证你的场景实验假设;例如,你可以使用额外的 FIS 行动来验证网络故障是否妨碍了子网的流量传输。你也可以使用 AWS Systems Manager 进行自定义 动作 或自己选择的 boto3 调用。

在我们的实验中,结果验证了我们的假设,如图2所示。

使用 Behave 时,可以通过不同格式化方式呈现结果,使其更容易导入到 报告 中;Allure 是一个不错的例子。

如需跟随实践,实施细节部分的步骤将帮助你在 CLI 中启动混沌实验。如前所述,如果你想在开发生命周期中使用这种方法,你应该将其整合进 CI/CD 管道中,而不是在本地启动。

实施细节

前提条件

要部署混沌实验和测试应用程序,你需要:

一个 AWS 账户访问 AWS CloudShell 或安装了 AWS CLI 并配置 个人资料及相应的 AWS 访问密钥。请确保你使用的是最新且可用的 Python 版本v39 或更高。

注意: 代码中启动的网站可用性测试是从 CLI 发起的。如果您遇到繁忙的公司代理或不稳定的网络连接,则可能导致实验失败。

此外,为了使前提条件尽可能简化且自给自足,我们在本博客中使用了 Locust 作为 Python 库,它的实现并不复杂。通过 Behave 步骤实现,我们在本地启动 Locust 流量生成器,以在执行混沌操作之前和之后向目标网站发送流量。对于更强大的实现,你可以构建一个 REST API 后面的 Locust 实现或者使用已经存在 REST API 的负载测试套件,如 Blazemeter,这可以从 Behave 步骤中调用,持续运行整个实验期间。

本次发布的 CloudFormation 将创建一些公开访问的 EC2 实例。请利用以下说明将访问权限限制为仅允许您的公共 IP 地址。你可以在 https//checkipamazonawscom/ 找到你的 IP 地址。请使用以 /32 结尾的 IP 地址,例如 1234/32

环境准备

通过以下命令克隆包含本博客资源的 git 仓库 awsfisbehaviourdrivenchaos:

bashgit clone https//githubcom/awssamples/awsfisbehaviourdrivenchaosgit

我们建议创建一个新的干净的 Python 虚拟环境并激活它:

bashpython3 m venv behavefisvenvsource behavefisvenv/bin/activate

部署步骤

从博客代码库的根目录执行:

将 Python 依赖项安装到你的环境中: bash pip install r requirementstxt

创建测试堆栈并等待完成确保将 AllowedCidr 参数的值替换为你的公共 IP 地址: bash aws cloudformation createstack stackname mychaosstack templatebody file//cloudformation/infrastructureyaml region=euwest1 parameters ParameterKey=AllowedCidrParameterValue=1234/32 capabilities CAPABILITYIAM aws cloudformation wait stackcreatecomplete stackname mychaosstack region=euwest1

一旦部署完成,检索堆栈输出: bash aws cloudformation describestacks stackname mychaosstack region=euwest1

越南节点的加速器

将堆栈输出中的 OutputValue 复制到 behave/userconfigjson 文件,替换 websitehostname 和 fisexperimentid 的占位符值。

若在步骤 2 中更改堆栈构建区域,请在 behave/userconfigjson 文件中替换 region 的值。

切换目录到 behave/: bash cd behave/

启动 behave: bash behave 一旦完成,Locust 结果将出现在 behave 文件夹中图3是一个示例。

清理

如果你使用了本博客提供的 CloudFormation 模板创建 AWS 资源,请立即删除它们,以避免未来的费用。

删除堆栈的命令为:

bashaws cloudformation deletestack stackname mychaosstack region=euwest1 ampampaws cloudformation wait stackdeletecomplete stackname mychaosstack region=euwest1

结论

本文为你提供了可用和可操作的见解,展示如何将 FIS 操作及实验模板封装在一种使用便捷的语言中,全面定义并自动化混沌实验,使其不仅对测试工程团队的干系人可及。你可以在此基础上扩展,使用你自己的方法和指标测试自己的工作负载,通过强大的混沌实验套件建立对工作负载持续韧性的信心,并向更广泛的组织提供这样的证据。

Richard Whitworth

Richard Whitworth 是 AWS 的高级解决方案架构师,位于英国曼彻斯特。他目前与新接触 AWS 的企业客户合作,并拥有金融服务领域的背景,在云端和本地架构设计多个高价值工作负载。Richard 专注于系统的韧性。

Greg Willson

Greg Willson 是 AWS 全球金融服务团队的高级解决方案架构师。他特别关注帮助客户构建良好架构和高度韧性的云解决方案。在业余时间,他喜欢跑步和开放水域游泳。

强化基于亚马逊 Bedrock 的 RAG 聊天机器人架构:安全设计与防范模式的蓝图关键要点本文展示了如何使用 亚马逊 Bedrock 部署一个安全且负责任的聊天机器人应用程序,并提供详细的安全计划。我们识别了在将大型语言模型LLM集成到应用程序中时可能出现的常见安全风险和反模式。亚马逊 Bedro...