运用Kubernetes进行分布式负载测试

本文为CSDN原创编译文章,禁止转载。

负载测试是开发后台基础架构的重要一环,它不但能够演示系统在真实需求面前的性能表现,还可以通过模拟用户与设备行为,在应用程序部署到生产环境前,找出并了解任何可能的系统瓶颈。

但是,专用的测试基础设施可能非常昂贵且难以维护,且此类设备一般是针对特定性能状况的一次性投资,初期投资后想要再对负载测试进行扩展就十分困难,还可能限制实验,从而导致开发团队的工作效率变低,应用在部署到生产环境前也无法得到充分有效的测试。

解决方案综述

分布式负载测试采用云计算手段,在各种测试场景中这种方案都很有吸引力。云平台使得基础设施平台的弹性得到高度扩展,想要通过大量模拟可产生流量的客户端进行应用和服务测试都十分容易。此外,云计算的定价模式与负载测试的弹性特质非常相符。

无需再运行完整的虚拟机实例了,容器提供的轻量级选择与虚拟客户端的快速扩展完美匹配。由于其轻量级、易于部署、快速可用并适合单一任务等特质,容器是取代运行测试客户端的优秀替代方案。

谷歌云平台是使用容器进行分布式负载测试的极优环境,该平台使用的谷歌容器引擎(Google Container Engine)以开源容器集群管理器Kubernetes为动力,将容器作为一级对象对其提供支持。使用容器引擎可以快速搭建容器基础设施,并可用来管理应用部署与资源。

该解决方案演示了使用容器引擎部署分布式负载测试框架的方式。此框架使用多个容器,搭建了一个应用于简易REST-based API的负载测试通讯。尽管这是用来测试简单Web应用的,但同样的模式可用于创建更为复杂的负载测试场景中,比如游戏或物联网应用中。该方案讨论了基于容器负载测试框架的通用架构。请至本文末尾查看教程,逐步学习样例框架的构建。

本方案着重通过容器引擎来创建负载测试通讯,被测系统是一个简单的Web应用,使用了REST的API。借助现有的负载测试框架,塑造出下文中详细描述到的API互动模型。并在完成被测系统的部署后,运用容器引擎来部署分布式负载测试任务。

被测系统

在软件测试术语中,被测系统(System Under Test)指的是该测试设计时所针对的待评估系统。在该方案中,被测系统是一个部署到Google App Engine的小型Web应用,该应用通过发布基本REST样式的端点来捕获接收的HTTP POST请求(接收数据并不连续)。在真实场景中,Web应用可能会很复杂,并包含大量的附加组件及服务,如caching、messaging和persistence,此方案不考虑这些复杂情况。更多在谷歌云平台上构建可扩展的Web应用相关信息,请查看the Building Scalable and Resilient Web Applications方案。

样例应用的源代码请见文末教程。

示例workload

许多物联网的部署中有类似示例应用模型中所使用的后端服务组件——设备首次注册服务后,开始报告指标或检测器读数,并定期重新进行服务的注册。

下图展示了一个常见的后端服务组件的交互。

该交互可以用Locust这种基于Python的分布式负载测试工具来建模,Locust可以向多个目标路径分发请求,比如向/login和/metrics目标路径分别发送请求;还有很多负载生成软件包也可根据项目需求选择使用,包括JMeter、Gatling和Tsung。

而workload将会取决于上面所说到的交互,在Locust会以一组task的模型出现。为了尽量模拟真正的客户端,比如同时有上千个客户端请求接入的情况,每个Locust task需经过加权。

基于容器的计算

从架构角度来看,部署该分布式负载测试方案有两个主要的组件:Locust容器image,还有容器编排及管理机制。

Locust的容器image是包含Locust软件的Docker image,Dockerfile可以在相关的Github库中找到(见教程),而Dockerfile使用了基于Python的image,并使用一些脚本文件来启动Locust服务,执行task。

该方案利用谷歌容器引擎用作容器编排与管理机制。容器引擎是基于开源框架Kubernetes,集合了谷歌多年在容器部署方面运行、编排与管理的经验。基于容器的计算允许开发人员专注于应用本身,无需将精力浪费在繁琐的托管环境部署与集成上。容器同时也使得负载测试更为轻便,通过容器整合后的应用可以在多个云环境中运行。容器引擎与Kubernetes引入了针对容器编排与管理的若干概念。

容器集群

一个容器集群包含一组云计算引擎(Compute Engine)实例,为整个应用提供基础。在容器引擎及Kubernetes的文档中,这些实例被称为节点。一个集群包含一个master节点和一到多个worker节点。master节点与worker节点都运行在Kubernetes上,因此容器集群有时也被称为Kubernetes集群。更多集群相关信息请查看容器引擎文档。

Pods

Pod是一组应当被集中部署的紧密耦合容器,一些pod只包含单个容器,例如该案例中,每个Locust容器都运行在自己的pod中。但是通常情况下,pod会包含多个集中执行的容器,例如该案例中,Kubernetes使用了一个包含三个容器的pod提供DNS服务。

在一个容器中,SkyDNS提供DNS服务功能。SkyDNS依赖于一个名叫etcd的键值存储,而它又被封装在另一个容器中。在pod的第三个容器中,kube2sky担任了Kubernetes与SkyDNS之间的桥梁。

复制控制器

一个复制控制器确保特定数量的pod“副本”能够随时运行。如果数量过多,复制控制器会关掉其中一些;如果数量过少,复制控制器会启动一些新的。该方案有三个复制控制器:一个确保DNS server的单个pod存续;另一个维持Locust的单个master pod;第三个则保证同时正好有10个Locust的worker pod运行。

服务

特定pod可能会因为各种原因而消失,包括节点失效或因更新维护而主动进行的节点中断。也就是说,pod的IP地址没有为其提供可靠的接口。更为有效的办法是使用该接口的抽象表示,即使底层pod消失,新的pod产生,IP地址发生变化,该抽象表示不会改变。容器引擎服务通过定义一组逻辑pod及访问相关策略,提供这种类型的抽象接口。在该方案中,有一些代表pod或成组pod的服务。例如,一个服务代表DNS server,另一个代表Locust master pod,还有一个代表那10个worker pod。

下图展示了master节点与worker节点所包含的内容:

部署被测系统

该方案使用谷歌应用引擎来运行被测系统。部署被测系统需注册可用的谷歌云平台帐号,以安装运行谷歌云平台SDK,之后通过一个命令就可以部署这个样例Web应用了,所需的源代码在文末教程中可以找到。

部署负载测试任务

部署负载测试任务,首先需要部署负载测试master,然后是一组10个的负载测试worker。有了这些工作负载测试,就可以根据测试目的来创建大量通讯了,但需要铭记:与外部系统产生过多通讯与拒绝服务攻击相类似,请务必回顾谷歌云平台的服务条款和谷歌云平台的使用者协议。

负载测试master

部署的第一个组件就是Locust的master,它是执行负载测试任务的入口。部署时将Locust master部署为只含单个副本的复制控制器,因为我们只需要一个master。一个复制控制器甚至在部署单个pod时都是有效的,因为它能确保高可用性。

复制控制器的配置指定了几个元素,包括控制器的名字(locust-master)、标签(name: locust, role: master)、容器所需要发布的端口(Web接口用8089,与worker通讯用5051和5052)。 这些信息稍后会被用来配置Locust的worker控制器。下面的信息中包含端口的配置:

      ...
      ports:
        - name: locust-master-web
          containerPort: 8089
          protocol: TCP
        - name: locust-master-port-1
          containerPort: 5557
          protocol: TCP
        - name: locust-master-port-2
          containerPort: 5558
          protocol: TCP

下一步,我们会部署一个Service,以确保发布的端口可以通过hostname访问其它pod:集群中的端口以及通过描述性端口名称的referenceable。通过使用服务,即便在master失效,复制控制器又生成了新pod的情况下,我们也可以很容易地找到Locust的worker,并可与master通讯。Locust的master服务也包含在集群层面创建外部转发规则的指令,提供访问集群资源的外部通讯能力。注意:还需创建防火墙规则,以提供访问目标样例的完整入口。

在部署Locust master之后,就可以通过符合外部转发规则的公开IP地址来访问Web接口了。部署Locust worker之后,可开启模拟器并通过Locust Web接口来查看汇总统计。

负载测试worker

下一步部署的组件是Locust worker,用来执行负载压力测试。Locust worker是通过能生成10个pod的单个复制控制器来部署的。这些pod分布在Kubernetes的集群中。每个pod通过环境变量来控制重要的配置信息,像是被测系统的hostname和Locust master的hostname。worker的复制控制器配置方式请查看下面的教程。配置包含控制器的名称、locust-worker、标签(name: locust, role: worker),还有前面描述的环境变量。下面代码包含配置的名称、标签、副本数:

kind: ReplicationController apiVersion: v1 metadata: name: locust-worker
    labels: name: locust role: worker spec: replicas: 10 selector: name: locust
    role: worker ...

对于Locust worker来说就无需部署额外服务了,因为worker pod自身不需支持任何入站通讯——它们直接与Locust master pod相连。

下图展示了Locust master与Locust worker之间的关系。

在复制控制器部署Locust worker之后,就可以返回Locust master的Web接口来查看worker部署数量相应的slave数。

执行负载测试任务

开启负载测试

Locust的主Web接口允许执行针对被测系统的负载测试任务,见下图:

开启时指定模拟的用户数、用户应当产生的速率。下一步,点击Start开始模拟。随着时间流逝、用户产生,可以看到统计数据开始按模拟指数进行聚合,像是请求数、每秒请求数,如下图:

停止模拟只需点击Stop,测试就会终止。完整结果可以下载表格查看。

扩展客户端

按比例增加模拟用户会导致Locust worker pod数随之增长。在Locust的worker控制器中有详细说明,复制控制器部署10个Locust的worker pod。通过复制控制器增加pod的数量,Kubernetes提供了不需重新部署即可调整控制器大小的能力。例如,通过kubectl命令行工具可以调整worker pod的数量。下面的命令可以将Locust的worker pod数量增加到20:

$ kubectl scale --replicas=20 replicationcontrollers locust-worker

在发出扩容命令后,等待几分钟,所有pod在此时间段内完成部署并启动。所有pod启动后,回到Locust master的Web接口,重启负载测试。

资源与成本

这个解决方案使用了四个容器引擎节点,每个都受云计算引擎VM标准n1-standard-1类型的支持。你可以使用谷歌云平台的定价计算器估算运行容器集群的月开销。上文提到过,可以按需定制容器集群的大小。定价计算器可以协助你自定义集群特点,借此评估开销的增减。

下一步

现在可以查看如何使用容器引擎来创建简单Web应用的负载测试框架了。容器引擎允许你指定建立负载测试框架容器所需的节点数量。容器引擎还允许你将负载测试工作节点合并到pod中,并制定容器引擎运行时想要保持的pod数量。

使用同样的模式来创建不同环境变量与应用的负载测试框架。例如,使用该模式创建信息系统、数据流管理系统与数据库系统的负载测试框架。创建新的Locust任务,甚至是不同的负载测试框架。

扩展框架的另一办法是自定义收集到的指数。例如,你可能想要测量每秒的请求数,或者监听负载增加后的响应延迟情况,或是查看响应失败率与错误类型。有多种可选的监控方式,包括谷歌云监控(Google Cloud Monitoring)。

教程

完整教程包含使用说明与源代码,请点击附件下载查看。

附件

原文发布于微信公众号 - CSDN技术头条(CSDN_Tech)

原文发表时间:2015-07-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏容器云生态

Mesos+Marathon+Docker构建docker集群化管理

由Docker引领的容器技术最近一年在生产环境叫嚣的比较厉害,由于Docker本身拥有的一些特性,使得越来越多的人愿意并且想尝试在生产环境构建Docker,有关...

2835
来自专栏云计算D1net

为什么需要PaaS?对Deis,Heroku,Flynn的一些观察

为什么需要PaaS?一句话,现在的应用程序从源代码到运行阶段太复杂,没有标准的,通用的方式。 整个过程及产出如下: 开发阶段:源代码构建阶段:发布包/可执行程序...

3046
来自专栏美团技术团队

【美团技术博客】Docker系列之二:基于容器的自动构建

自动构建系统是从美团的自动部署系统发展出来的一个新功能。每当开发人员提交代码到仓库后,系统会自动根据开发人员定制的构建配置,启动新的Docker容器,在其中对源...

40010
来自专栏Debian社区

Ubuntu Server自18.04 LTS开始不再提供32位镜像

2016年6月份Canonical公司在社区公布的草案,明确自Ubuntu 16.10开始逐步放弃32位支持,并在Ubuntu 18.10中彻底移除对32位架构...

1304
来自专栏编程坑太多

『中级篇』overlay网络和etcd实现多机的容器通信(31)

PS:本次通过第三方工具etcd分布式的方式完成2台机器,2个容器组件网络,实现相互的访问,这里只是通过ping的方式,如果按照上次说的 flask-redis...

922
来自专栏程序人生 阅读快乐

自建DNS服务器

不晓得为撒,用网上的一些公共DNS服务的时候,总是莫名其妙的有些网站无法解析,有时候114能解析,阿里DNS不行或者腾讯DNS不行,导致总是来回切换DNS,很是...

1.1K2
来自专栏R语言___生物信息

Anaconda安装使用

Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管理与环境管理的功能,可以很方便地解决多版本p...

5767
来自专栏PHP技术大全

使用PHP结合Ffmpeg快速搭建流媒体服务实践

笔者想将自己收藏的一些电影放到网站上可以用来随时播放,不过遇到了一个问题,便是如果直接将MP4文件放放到网站目录当中,手机端必须下载整个视频才可以播放,而如果跨...

4854
来自专栏数据和云

安全警报:Oracle 2018一月号安全补丁修复由来已久安全漏洞

在美西时间2018一月16日,北京时间今天凌晨,Oracle公司发布了 2018 年第一个安全补丁,这被称为 - Oracle Critical Patch U...

3135
来自专栏大魏分享(微信公众号:david-share)

Openshift3.9高可用部署考虑点1

一个典型的OCP高可用架构是:master至少应为三个,且为奇数个(上面有etcd);

2794

扫码关注云+社区

领取腾讯云代金券