在k8s中上线gatling镜像并在内网发送流量

后续更新,我不一定会记得更新过来。

在k8s中上线gatling镜像并在内网发送流量

很多时候我们会面临一个问题,即外网的带宽是有限的,虽然未来有扩容的可能,但是短时间内也不能直接扩容,而测试本身是无限的。因此,如果不能够在内网下直接发包进行测试,那由于带宽限制打不到较大的压力,对于一些容器的测试很可能就达不到效果。

因此我们需要在内网有一个能够配置的压力测试容器,目前选定了gatling,因为其功能比较强大,而且安装很方便。

镜像构造

初始镜像构造

虽然之前已经做了ubuntu的镜像,并且可以使用apt-get install来安装gatling,但是这种方式安装后有些不太会用,似乎更多是作为一个插件存在而不是独立存在的软件。

我还是选择了自己最熟悉的方式,直接从官网上下载了开源版本的standalone gatling.zip,解压后将目录重命名为gatling,Dockerfile如下:

FROM ubuntu:18.04
MAINTAINER wtysos11 "wtysos11@gmail.com"

COPY sources.list ./
ADD gatling ./gatling

RUN rm /etc/apt/sources.list\
  && mv sources.list /etc/apt/sources.list\
  && apt-get update \ 
  && apt-get install -y openjdk-8-jdk scala 
  #&& apt-get install -y gatling

CMD ["/bin/bash"]

sources.list为清华的apt镜像,为了加速;gatling可以在java8下运行,必须要安装scala(其实我个人觉得只安装scala就够了,保险起见)

操作完之后执行docker build . -t ubuntu-wtynettest:0.0.2构造镜像,然后执行docker run --name test -d ubuntu-wtynettest:0.0.2 sleep infinity。再使用docker exec -it test bash

经过测试,gatling软件能够正常运行并且访问外界指定端口。如果我没有记错,k8s中的pod暴露端口主要是为了转发流量,那容器自己往外发流量应该是不用暴露端口的,因此直接上k8s是没有问题的。

进阶流量压力测试镜像构造

下面的任务为:

  1. 在镜像文件中配置环境变量,该变量最好是能够在docker build的时候修改而不是要手动改写Docerfile,这样后续写bash脚本之类的会比较方便。(如果能够实时传入就更好了,不过这要将gatling作为插件实现,改写太多了,计划放在第三步)
  2. 删除原有系统中的脚本文件,并上传指定的脚本文件test.scala。这个脚本文件要能够读取环境变量来替换指定的值。
  3. 命令直接设为指定的发包命令。

环境变量配置

我看了一下,使用docker build加参数的方式似乎并不常见,而且其他方式也挺麻烦的。

因此我直接使用了ENV Key=value的形式(如果value中间有空格,两边要加上双引号)

脚本读取环境变量

scala脚本是可以读取到环境变量的,方法挺多的。目前选择的是直接使用sys.env["EnvVar"],此时需要环境中能够读取到$EnvVar,不需要引入任何库。

这个方法的缺点是如果环境中没有设置环境变量会报错,不过这也不是什么大问题,毕竟在docker内部。

接下来就很简单了,将这个值作为方法的参数进行传递,然后把脚本送到指定的位置。

命令配置

由于standalone版本的gatling是使用gatling.sh进行执行的,因此我预先写了一个输入文件进行重定向(其实就是一个只有1+回车的文件)。如此,容器的命令配置完毕。

最终的Dockerfile:

FROM ubuntu:18.04
MAINTAINER wtysos11 "wtysos11@gmail.com"

ENV Test="http://192.168.0.173:19001"

COPY sources.list ./
COPY nettest.scala ./
COPY command.txt ./
ADD gatling ./gatling

RUN rm /etc/apt/sources.list\
  && mv sources.list /etc/apt/sources.list\
  && rm /gatling/user-files/simulations/computerdatabase/ -R \
  && mv nettest.scala /gatling/user-files/simulations/nettest.scala \
  && apt-get update \ 
  && apt-get install -y openjdk-8-jdk 
  #&& apt-get install gatling

CMD ["/gatling/bin/gatling.sh < command.txt"]

其中移除gatling内系统自带脚本的目的是为了让用户脚本一定排在第一位。由于版本不同,系统自带脚本可能有所区别,需要注意。

下面的文件:

  • command.txt,内含1+空格,表示输入给gatling.sh的内容
  • nettest.scala,一个可以读取$Test作为目标地址的gatling脚本
  • gatling,解压官方包gatling.zip后的文件夹

执行测试部分命令:

  • docker build . -t ubuntu-wtynettest:0.0.3
  • docker run --name test -d ubuntu-wtynettest:0.0.3 sleep infinity
  • docker exec -it test bash

测试完毕之后就直接挂载在kubernetes上了,还是挺不错的。 有一个问题,我发现如果使用这个DockerFile的CMD命令会导致gatling报错,错误原因是输入了一个空值给description,也就是command.txt可能是有问题的……但我进去执行又是正常的。因为我赶时间,所以是选择使用sleep infinity代替了原来的镜像,手动进入这个容器内去执行代码,从而实现在k8s集群中发送流量的操作。之后看有没有时间继续完善。

动态挂载

上面的实现方案还是有一个问题,即没有办法灵活控制gatling,只能够每次生成一个实例在挂载到k8s上,非常麻烦。而且如果不小心生成了两个实例,那就是双倍的流量,可能会造成一些问题。

我在思考有没有一种方式,能够将一个gatling程序传到k8s集群中,只需要通过网络端口向其上传配置文件、发送命令就可以调用指定的压力测试脚本。

我的实现思路需要用scala做一个简易的服务器,而网上的思路似乎有些不太一样。

不过有没有必要作出这个项目也是一个问题,毕竟gatling中仍然存在一些问题没有弄清楚,比如atOnceUser和constantUser等测试方式之间的选择等。

0%