¡Hola a todos!
En este artículo quiero compartir uno de los métodos para ejecutar pruebas de rendimiento de JMeter en OpenShift utilizando Jenkins como herramienta de automatización. Primero realizaremos todas las acciones necesarias (creación ImageStreams, BuildConfig, Job y otros) manualmente. Después escribiremos el Jenkins Pipeline.
Como punto de partida debemos tener:
- un clúster de OpenShift (v3.11) en funcionamiento
- servidor de Jenkins con credenciales configuradas para trabajar en OpenShift
- archivo
apache-jmeter-5.2.tgz
Como prueba utilizaremos una simple Solicitud HTTP en ya.ru en un solo hilo.
Creación de un proyecto en OpenShift
Comencemos creando un nuevo entorno. Crearemos perftest entorno con el comando:
$ oc new-project perftest --display-name="Pruebas de rendimiento" --description="Pruebas de rendimiento - JMeter"Seremos redirigidos automáticamente al nuevo entorno creado perftest, verifiquemos que es así:
$ oc project
Usando el proyecto "perftest" en el servidor "https://127.0.0.1:8443".Creación de Storage
Los informes de las pruebas se almacenarán en un espacio compartido para el servidor web y jmeter-metersu lugar — /jmeter/reports.
Es mejor crear el Storage ahora, porque los PODs dependerán de él jmeter-web y jmeter-master.
Encontrarás información más detallada sobre los storages en la documentación oficial .
Crearemos archivos yaml para PV y PVC.
pv.yaml
$ tee pv.yaml<<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
name: jmeter-reports
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
glusterfs:
endpoints: glusterfs-cluster
path: /jmeter/reports
readOnly: false
persistentVolumeReclaimPolicy: Retain
EOFpvc.yaml
$ tee pvc.yaml<<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jmeter-reports
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
EOFCrearemos PV y PVC en el entorno de OpenShift:
$ oc create -f pv.yaml -n perftest
$ oc create -f pvc.yaml -n perftestVerificamos el estado de PVC:
$ oc get pvc -n perftest
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jmeter-reports Bound pvc-b0e5f152-db4b-11ea-a497-566f75280024 10Gi RWX glusterfs-storage 8mAsí es como se verá en la GUI:

Creación de la imagen base de JMeter
Pasemos a la creación de ImageStream y BuildConfig.
Toda la información necesaria se puede encontrar en la documentación — .
La estrategia de creación de imágenes utiliza Docker de una fuente local.
Crearemos una imagen base jmeter-base, que será la base para jmeter-master.
Dockerfile
FROM openjdk:8u212-jdk
ARG JMETER_VER="5.2"
ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VER
ENV PATH $JMETER_HOME/bin:$PATH
RUN mkdir -p /jmeter/results
&& mkdir /jmeter/tests
WORKDIR /jmeter
COPY apache-jmeter-$JMETER_VER.tgz .
RUN tar -xzf $JMETER_HOME.tgz
&& rm $JMETER_HOME.tgz
&& ls -la
RUN sed -i s/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/ $JMETER_HOME/bin/jmeter.properties
EXPOSE 60000is.yaml
$ tee is.yaml<<EOF
apiVersion: v1
kind: ImageStream
metadata:
labels:
build: jmeter-base
name: jmeter-base
EOFbc.yaml
$ tee bc.yaml<<EOF
apiVersion: v1
kind: BuildConfig
metadata:
name: jmeter-base
spec:
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: 5
EOFCrearemos los objetos IS y BC:
$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftestAhora construiremos la imagen base jmeter-base:
$ oc start-build jmeter-base -n perftest --from-dir=. --followJMeter WEB
jmeter-web es un servidor Apache. Su función es proporcionar un directorio con los resultados de las pruebas para su visualización.
Preparado Dockerfile y el archivo de configuración httpd.conf. Para la directiva DocumentRoot se establece en /jmeter/reports, es decir, el directorio donde se almacenan los resultados de las pruebas.
Dockerfile
$ tee Dockerfile<<EOF
FROM httpd:2.4
COPY httpd.conf /usr/local/apache2/conf/httpd.conf
RUN chmod -R 777 /usr/local/apache2/logs
EXPOSE 8080
CMD ["httpd", "-D", "FOREGROUND"]
EOFis.yaml
$ tee is.yaml<<EOF
apiVersion: v1
kind: ImageStream
metadata:
generation: 1
labels:
build: jmeter-web
name: jmeter-web
EOFbc.yaml
$ tee bc.yaml<<EOF
apiVersion: v1
kind: BuildConfig
metadata:
name: jmeter-web
spec:
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: 5
EOFCrearemos ImageStream y BuildConfig objetos:
$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftestConstruimos la imagen de Dockerfile:
$ oc start-build jmeter-web -n perftest --from-dir=. --followdc.yaml
$ tee dc.yaml<<EOF
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: jmeter-web
spec:
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-reports
EOFsc.yaml
$ tee sc.yaml<<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: jmeter-web
name: jmeter-web
spec:
ports:
- name: 8080-tcp
port: 8080
protocol: TCP
targetPort: 8080
selector:
deploymentconfig: jmeter-web
sessionAffinity: None
type: ClusterIP
EOFCrearemos los objetos Servicio y DeploymentConfig:
$ oc create -f sc.yaml -n perftest
$ oc create -f dc.yaml -n perftestJmeter-master
Nos ocuparemos del despliegue del servidor web Apache.
Este es el Dockerfile jmeter-master‘a, basado en jmeter-base, que ejecutará pruebas y almacenará resultados en el almacenamiento.
Dockerfile
Dockerfile para jmeter-master, basado en jmeter-base.
FROM jmeter-base
ARG JMETER_VER="5.2"
ENV JMETER_HOME /jmeter/apache-jmeter-$JMETER_VER
ENV PATH $JMETER_HOME/bin:$PATH
WORKDIR /jmeter
COPY run.sh /jmeter/
COPY tests/*.jmx /jmeter/tests/
RUN chmod +x /jmeter/run.sh
ENTRYPOINT ["/bin/bash"]
CMD ["/jmeter/run.sh"]run.sh
run.sh es un script que ejecuta JMeter y almacena los resultados en el directorio files.
En cada ejecución, el script elimina las pruebas anteriores, por lo que solo se puede trabajar con los datos más recientes. Pero esto no es un problema, ya que se puede modificar según tus necesidades.
#!/bin/bash
set -e
if [ -d "/jmeter/reports/files" ]
then
echo "Directory /jmeter/reports/files exist - OK"
else
echo "Creating /jmeter/reports/files directory"
mkdir /jmeter/reports/files
fi
if [ -d "/jmeter/reports/dashboards" ]
then
echo "Directory /jmeter/reports/dashboards exist"
else
echo "Creating /jmeter/reports/dashboards directory"
mkdir /jmeter/reports/dashboards
fi
echo "*** 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}-dash
doneis.yaml
$ tee is.yaml<<EOF
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
generation: 1
labels:
build: jmeter-master
name: jmeter-master
EOFbc.yaml
$ tee bc.yaml<<EOF
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: jmeter-master
spec:
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: 5
EOFCrearemos IS y BC objetos:
$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftestRecopilando jmeter-master imagen:
$ oc start-build jmeter-master -n perftest --from-dir=. --followJob
Jobse utilizan en OpenShiftpara ejecutar uno o varios PODy garantizar su finalización exitosa después de ejecutar el comando/script.
$ tee job.yaml<<EOF
apiVersion: batch/v1
kind: Job
metadata:
name: jmeter-master
labels:
jobName: jmeter-master
spec:
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: 30
EOFCreando el objeto Job:
$ oc create -f job.yaml -n perftestComprobemos el estado del trabajo:
$ oc get jobs -n perftest
NAME DESIRED SUCCESSFUL AGE
jmeter-master 1 1 5mPara eliminar Job usaremos el comando:
$ oc delete jobs/jmeter-master -n perftest --ignore-not-found=trueJenkins Pipeline
Ahora, automatización. Repasemos los pasos:
git cloneoc whoami -toc start-build ...oc delete jobs/jmeter-masteroc create -f job.yaml -n perftest
A continuación, se presenta el pipeline, donde se realiza la clonación del repositorio, eliminación y creación de OpenShift Jobjobs.
#!groovy
pipeline {
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>INICIO - Pruebas de Rendimiento</strong><br /><br />Proyecto: Nombre del Proyecto<br />Entorno: PerfTest<br />Número de compilación: ${env.BUILD_NUMBER}<br />URL de compilación: ${env.BUILD_URL}"
}
}
}
etapa('Git checkout') {
pasos {
...
}
}
etapa('Pruebas de Rendimiento') {
pasos {
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 "FALLIDA - Pruebas de Rendimiento"
mail(to: 'username@srv.net', from: "jenkins@srv.net", subject: "FALLIDA - Pruebas de Rendimiento",mimeType: "text/html", body: "<strong>FALLIDA - Pruebas de Rendimiento</strong><br /><br />Proyecto: Nombre del Proyecto<br />Entorno: PerfTest<br />Número de compilación: ${env.BUILD_NUMBER}<br />URL de compilación: ${env.BUILD_URL}"
}
success {
echo "EXITOSA - Pruebas de Rendimiento"
mail(to: 'username@srv.net', from: "jenkins@srv.net", subject: "EXITOSA - Pruebas de Rendimiento",mimeType: "text/html", body: "<strong>EXITOSA - Pruebas de Rendimiento</strong><br /><br />Proyecto: Nombre del Proyecto<br />Entorno: PerfTest<br />Número de compilación: ${env.BUILD_NUMBER}<br />URL de compilación: ${env.BUILD_URL}"
}
}
}
}Después de que el Pipeline se ejecute, recibirás una notificación en tu correo electrónico 'username@srv.net desde jenkins@srv.net.
Al seguir el enlace veremos el directorio files, donde se almacenan los informes de pruebas:

El contenido del archivo ya.HTTP.Request.jmx-report.jtk:
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
1597311456443,569,Yandex - HTTP Request,200,Ok,Thread Group 1-1,text,true,,59449,220,1,1,https://ya.ru/,145,0,57
1597311456443,147,Yandex - HTTP Request-0,302,Found,Thread Group 1-1,,true,,478,110,1,1,http://ya.ru/,145,0,57
1597311456592,420,Yandex - HTTP Request-1,200,Ok,Thread Group 1-1,text,true,,58971,110,1,1,https://ya.ru/,370,0,259Conclusión
En este artículo se demostró una de las maneras de ejecutar pruebas de JMeter en un entorno de OpenShift. Se realizaron todos los pasos manualmente, después de lo cual se creó un Jenkins Pipeline para automatizar el proceso de ejecución de las pruebas.
Fuentes y documentación
- openshift
Fuente: habr.com
