Всем привет!
В этой статье хочу поделиться одним из способов запуска тестов
производительности JMeter в OpenShift'e с использованием Jenkins'a
в качестве автоматизации. Сначала мы проделаем все необходимые
действия (создание ImageStreams
,
BuildConfig
, Job
и проч) в ручном режиме.
После этого напишим Jenkins Pipeline.
В качестве отправной точки у нас должно быть:
- работающий OpenShift (v3.11) кластер
- Jenkins server с настроенными учетными данными для работы в OpenShift
- файл
apache-jmeter-5.2.tgz
В качестве тестов будет простой HTTP Request
на
ya.ru
в один поток.
Создание проекта в OpenShift
Начнем с создания нового окружения. Создадим
perftest
окружение командой:
$ oc new-project perftest --display-name="Performance Tests" --description="Performance Tests - JMeter"
Нас автоматически перекинет в только что созданное окружение
perftest
, проверим, что это так:
$ oc projectUsing project "perftest" on server "https://127.0.0.1:8443".
Создание Storage'a
Отчеты тестов будут храниться в общем для веб-сервера и
jmeter-meter
'a месте /jmeter/reports
.
Стораджи создать лучше сейчас, потому что на них будут завязаны
POD'ы jmeter-web
и jmeter-master
.
Более детальную информацию по стораджам вы найдете в официальной документации Persistent Storage.
Создадим yaml-файлы для PV
и PVC
.
pv.yaml
$ tee pv.yaml<<EOFapiVersion: v1kind: PersistentVolumemetadata: name: jmeter-reportsspec: capacity: storage: 10Gi accessModes: - ReadWriteMany glusterfs: endpoints: glusterfs-cluster path: /jmeter/reports readOnly: false persistentVolumeReclaimPolicy: RetainEOF
pvc.yaml
$ tee pvc.yaml<<EOFapiVersion: v1kind: PersistentVolumeClaimmetadata: name: jmeter-reportsspec: accessModes: - ReadWriteMany resources: requests: storage: 10GiEOF
Создадим PV
и PVC
в окружении
OpenShift'a:
$ oc create -f pv.yaml -n perftest$ oc create -f pvc.yaml -n perftest
Проверяем статус для PVC
:
$ oc get pvc -n perftestNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEjmeter-reports Bound pvc-b0e5f152-db4b-11ea-a497-566f75280024 10Gi RWX glusterfs-storage 8m
Вот, как будет выглядеть в GUI:
Создание базового образа JMeter
Перейдем к созданию ImageStream
и
BuildConfig
.
Всю необходимую информацию сможете найти в документации Builds and Image Streams.
В качестве стратегии сборки образов используется
Docker
из локального источника.
Создадим базовый образ jmeter-base
, который будет
основой для jmeter-master
.
Dockerfile
FROM openjdk:8u212-jdkARG JMETER_VER="5.2"ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VERENV PATH $JMETER_HOME/bin:$PATHRUN mkdir -p /jmeter/results \ && mkdir /jmeter/testsWORKDIR /jmeterCOPY apache-jmeter-$JMETER_VER.tgz .RUN tar -xzf $JMETER_HOME.tgz \ && rm $JMETER_HOME.tgz \ && ls -laRUN sed -i s/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/ $JMETER_HOME/bin/jmeter.propertiesEXPOSE 60000
is.yaml
$ tee is.yaml<<EOFapiVersion: v1kind: ImageStreammetadata: labels: build: jmeter-base name: jmeter-baseEOF
bc.yaml
$ tee bc.yaml<<EOFapiVersion: v1kind: BuildConfigmetadata: name: jmeter-basespec: failedBuildsHistoryLimit: 5 nodeSelector: null output: to: kind: ImageStreamTag name: 'jmeter-base:latest' postCommit: {} resources: {} runPolicy: Serial source: binary: {} type: Binary strategy: dockerStrategy: from: kind: ImageStreamTag name: 'openjdk:8u212-jdk' type: Docker successfulBuildsHistoryLimit: 5EOF
Создадим объекты IS
и BC
:
$ oc create -f is.yaml -n perftest$ oc create -f bc.yaml -n perftest
Теперь соберем базовый образ jmeter-base
:
$ oc start-build jmeter-base -n perftest --from-dir=. --follow
JMeter WEB
jmeter-web
это веб-сервер Apache. В его задачу
входит предоставление директории с результатами тестирования для
просмотра.
Подготовлен Dockerfile
и файл конфигурации
httpd.conf
. Для директивы DocumentRoot
выставлено значение /jmeter/reports
, т.е. директория в
которую сохраняются результаты тестирования.
Dockerfile
$ tee Dockerfile<<EOFFROM httpd:2.4COPY httpd.conf /usr/local/apache2/conf/httpd.confRUN chmod -R 777 /usr/local/apache2/logsEXPOSE 8080CMD ["httpd", "-D", "FOREGROUND"]EOF
is.yaml
$ tee is.yaml<<EOFapiVersion: v1kind: ImageStreammetadata: generation: 1 labels: build: jmeter-web name: jmeter-webEOF
bc.yaml
$ tee bc.yaml<<EOFapiVersion: v1kind: BuildConfigmetadata: name: jmeter-webspec: failedBuildsHistoryLimit: 5 nodeSelector: null output: to: kind: ImageStreamTag name: 'jmeter-web:latest' runPolicy: Serial source: binary: {} type: Binary strategy: dockerStrategy: from: kind: ImageStreamTag name: 'httpd:2.4' type: Docker successfulBuildsHistoryLimit: 5EOF
Создадим ImageStream
и BuildConfig
объекты:
$ oc create -f is.yaml -n perftest$ oc create -f bc.yaml -n perftest
Собираем образ из Dockerfile
:
$ oc start-build jmeter-web -n perftest --from-dir=. --follow
dc.yaml
$ tee dc.yaml<<EOFapiVersion: apps.openshift.io/v1kind: DeploymentConfigmetadata: name: jmeter-webspec: replicas: 1 template: metadata: labels: name: jmeter-web spec: containers: - image: 172.30.1.1:5000/perftest/jmeter-web name: jmeter-web volumeMounts: - mountPath: /jmeter/reports name: jmeter-reports ports: - containerPort: 80 protocol: TCP - containerPort: 8080 protocol: TCP volumes: - name: jmeter-reports persistentVolumeClaim: claimName: jmeter-reportsEOF
sc.yaml
$ tee sc.yaml<<EOFapiVersion: v1kind: Servicemetadata: labels: app: jmeter-web name: jmeter-webspec: ports: - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 selector: deploymentconfig: jmeter-web sessionAffinity: None type: ClusterIPEOF
Создадим объекты Service
и
DeploymentConfig
:
$ oc create -f sc.yaml -n perftest$ oc create -f dc.yaml -n perftest
Jmeter-master
Займемся деплойментом веб-сервера Apache.
Это Dockerfile jmeter-master
'a, основанный на
jmeter-base
, который будет запускать тесты и сохранять
результаты в сторадж.
Dockerfile
Dockerfile
для jmeter-master
,
основанный на jmeter-base
.
FROM jmeter-baseARG JMETER_VER="5.2"ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VERENV PATH $JMETER_HOME/bin:$PATHWORKDIR /jmeterCOPY run.sh /jmeter/COPY tests/*.jmx /jmeter/tests/RUN chmod +x /jmeter/run.shENTRYPOINT ["/bin/bash"]CMD ["/jmeter/run.sh"]
run.sh
run.sh
это скрипт, который выполняет запуск
JMeter'a и сохраняет результаты в директорию
files
.
При каждом запуске скрипт удаляет предыдущие тесты, так что работать можно только с последними данными. Но это не проблема, потому что его можно изменить под свои нужды.
#!/bin/bashset -eif [ -d "/jmeter/reports/files" ]then echo "Directory /jmeter/reports/files exist - OK"else echo "Creating /jmeter/reports/files directory" mkdir /jmeter/reports/filesfiif [ -d "/jmeter/reports/dashboards" ]then echo "Directory /jmeter/reports/dashboards exist"else echo "Creating /jmeter/reports/dashboards directory" mkdir /jmeter/reports/dashboardsfiecho "*** JMeter START Tests ***"for item in $(ls -1 /jmeter/tests | grep jmx)do echo "*** Removing dashboard directory for $item" rm -rdf /jmeter/reports/dashboards/${item}* echo "*** Removing tests directory for $item" rm -rdf /jmeter/reports/files/${item}* echo "*** Testing a $item file ***" jmeter -n -t /jmeter/tests/${item} -l /jmeter/reports/files/${item}-report.jtl -e -o /jmeter/reports/dashboards/${item}-dashdone
is.yaml
$ tee is.yaml<<EOFapiVersion: image.openshift.io/v1kind: ImageStreammetadata: generation: 1 labels: build: jmeter-master name: jmeter-masterEOF
bc.yaml
$ tee bc.yaml<<EOFapiVersion: build.openshift.io/v1kind: BuildConfigmetadata: name: jmeter-masterspec: failedBuildsHistoryLimit: 5 nodeSelector: null output: to: kind: ImageStreamTag name: 'jmeter-master:latest' runPolicy: Serial source: binary: {} type: Binary strategy: dockerStrategy: from: kind: ImageStreamTag name: 'jmeter-base:latest' type: Docker successfulBuildsHistoryLimit: 5EOF
Создадим IS
и BC
объекты:
$ oc create -f is.yaml -n perftest$ oc create -f bc.yaml -n perftest
Собираем jmeter-master
образ:
$ oc start-build jmeter-master -n perftest --from-dir=. --follow
Job
Job
'ы используются в OpenShift
'e для
того, чтобы запускать один или несколько POD
'ов и
гарантировать их успешное завершение после выполнения
команды/сценария .
$ tee job.yaml<<EOFapiVersion: batch/v1kind: Jobmetadata: name: jmeter-master labels: jobName: jmeter-masterspec: completions: 1 parallelism: 1 template: metadata: name: jmeter-master labels: jobName: jmeter-master spec: containers: - name: jmeter-master image: 172.30.1.1:5000/perftest/jmeter-master:latest volumeMounts: - mountPath: /jmeter/reports name: jmeter-reports imagePullPolicy: Always volumes: - name: jmeter-reports persistentVolumeClaim: claimName: jmeter-reports restartPolicy: Never terminationGracePeriodSeconds: 30EOF
Создаем объект Job
:
$ oc create -f job.yaml -n perftest
Проверим статус джобы:
$ oc get jobs -n perftestNAME DESIRED SUCCESSFUL AGEjmeter-master 1 1 5m
Чтобы удалить Job
воспользуемся командой:
$ oc delete jobs/jmeter-master -n perftest --ignore-not-found=true
Jenkins Pipeline
Теперь автоматизация. Еще раз проговорим шаги:
git clone
oc whoami -t
oc start-build ...
oc delete jobs/jmeter-master
oc create -f job.yaml -n perftest
Ниже представлен пайплайн, в котором выполняются клонирование
репозитория, удаление и создание OpenShift Job
'ы.
#!groovypipeline { agent any stages { stage('Start Notifications') { steps { echo "Sending Email Notification" } post { always { echo "STARTED - Performance Tests" mail(to: 'username@srv.net', from: "jenkins@srv.net", subject: "START - Performance Tests",mimeType: "text/html", body: "<strong>START - Performance Tests</strong><br /><br />Project: Name of Project<br />Environment: PerfTest<br />Build number: ${env.BUILD_NUMBER}<br />Build URL: ${env.BUILD_URL}" } } } stage('Git checkout') { steps { ... } } stage('Perf Tests') { steps { script { sh ''' OC_CMD1="oc login -u=username -p=PASS -n=perftest \ --server=https://...:8443" $OC_CMD1 OC_TOKEN=`oc whoami -t` OC_CMD2="oc --token=$OC_TOKEN --server=https://...:8443 \ start-build jmeter-master -n=perftest --from-dir=./master \ --follow=true" OC_CMD3="oc --token=$OC_TOKEN --server=https://...:8443 \ delete jobs/jmeter-master -n=perftest --ignore-not-found=true" OC_CMD4="oc--token=$OC_TOKEN --server=https://...:8443 \ create -f ./master/job.yaml -n=perftest" $OC_CMD2 $OC_CMD3 $OC_CMD4 ''' } } } post { failure { echo "FAILED - Performance Tests" mail(to: 'username@srv.net', from: "jenkins@srv.net", subject: "FAILED - Performance Tests",mimeType: "text/html", body: "<strong>FAILED - Performance Tests</strong><br /><br />Project: Name of Project<br />Environment: PerfTest<br />Build number: ${env.BUILD_NUMBER}<br />Build URL: ${env.BUILD_URL}" } success { echo "SUCCESSED - Performance Tests" mail(to: 'username@srv.net', from: "jenkins@srv.net", subject: "SUCCESSED - Performance Tests",mimeType: "text/html", body: "<strong>SUCCESSED - Performance Tests</strong><br /><br />Project: Name of Project<br />Environment: PerfTest<br />Build number: ${env.BUILD_NUMBER}<br />Build URL: ${env.BUILD_URL}" } } }}
После того, как Pipeline отработал, мы получим уведомление на
электронную почту 'username@srv.net
от
jenkins@srv.net
.
Перейдя по ссылке http://jmeter-web.127.0.0.1.nip.io/
увидим директорию files
, в которой хранятся отчеты
тестов:
Содержимое файла
ya.HTTP.Request.jmx-report.jtk
:
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect1597311456443,569,Yandex - HTTP Request,200,Ok,Thread Group 1-1,text,true,,59449,220,1,1,https://ya.ru/,145,0,571597311456443,147,Yandex - HTTP Request-0,302,Found,Thread Group 1-1,,true,,478,110,1,1,http://ya.ru/,145,0,571597311456592,420,Yandex - HTTP Request-1,200,Ok,Thread Group 1-1,text,true,,58971,110,1,1,https://ya.ru/,370,0,259
Заключение
В этой статье был продемонстрирован один из вариантов запуска тестов JMeter в OpenShift окружении. Сделали все шаги в ручном режиме, после чего создали Jenkins Pipeline для автоматизации процесса запуска тестов.