Ausführen von JMeter-Tests in OpenShift mit Jenkins Pipeline

Hallo an alle!

In diesem Artikel möchte ich eine der Möglichkeiten vorstellen, JMeter-Leistungstests in OpenShift mit Jenkins als Automatisierung auszuführen. Zuerst werden wir alle notwendigen Schritte durchführen (Erstellen ImageStreams, BuildConfig, Job usw.) im manuellen Modus. Danach schreiben wir Jenkins Pipeline.

Als Ausgangspunkt sollten wir haben:

  1. Ausführen des OpenShift (v3.11)-Clusters
  2. Jenkins-Server mit konfigurierten Anmeldeinformationen für die Arbeit in OpenShift
  3. Datei apache-jmeter-5.2.tgz

Als Tests wird es einfach sein HTTP Request auf ya.ru in einem Stream.

Erstellen eines Projekts in OpenShift

Beginnen wir mit der Erstellung einer neuen Umgebung. Lasst uns kreieren perftest umgeben von einem Team:

$ oc new-project perftest --display-name="Performance Tests" --description="Performance Tests - JMeter"

Wir werden automatisch in die neu erstellte Umgebung weitergeleitet perftest, überprüfen wir, ob das so ist:

$ oc project
Using project "perftest" on server "https://127.0.0.1:8443".

Erstellung von Speicher

Testberichte werden gemeinsam mit dem Webserver und gespeichert jmeter-meter'ein Ort - /jmeter/reports.

Es ist besser, Storajs jetzt zu erstellen, da PODs damit verknüpft werden jmeter-web и jmeter-master.

Genauere Informationen zur Speicherung finden Sie in der offiziellen Dokumentation Dauerspeicher.

Lassen Sie uns Yaml-Dateien erstellen für PV и 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
EOF

pvc.yaml

$ tee pvc.yaml<<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jmeter-reports
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
EOF

Lasst uns kreieren PV и PVC umgeben von OpenShift:

$ oc create -f pv.yaml -n perftest
$ oc create -f pvc.yaml -n perftest

Überprüfen des Status für 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   8m

So wird es in der GUI aussehen:

Ausführen von JMeter-Tests in OpenShift mit Jenkins Pipeline

Erstellen eines JMeter-Basisimages

Kommen wir zum Erstellen ImageStream и BuildConfig.

Alle notwendigen Informationen finden Sie in der Dokumentation - Builds und Image-Streams.

Die Image-Build-Strategie ist Docker aus einer lokalen Quelle.

Lassen Sie uns ein Basisbild erstellen jmeter-base, was die Grundlage dafür sein wird 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 60000

is.yaml

$ tee is.yaml<<EOF
apiVersion: v1
kind: ImageStream
metadata:
  labels:
    build: jmeter-base
  name: jmeter-base
EOF

bc.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
EOF

Lassen Sie uns Objekte erstellen IS и BC:

$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftest

Lassen Sie uns nun das Basisbild zusammenstellen jmeter-base:

$ oc start-build jmeter-base -n perftest --from-dir=. --follow

JMeter WEB

jmeter-web Dies ist ein Apache-Webserver. Seine Aufgabe besteht darin, ein Verzeichnis mit Testergebnissen zur Ansicht bereitzustellen.

Vorbereitet Dockerfile und Konfigurationsdatei httpd.conf. Für Direktive DocumentRoot Wert gesetzt /jmeter/reports, d.h. das Verzeichnis, in dem die Testergebnisse gespeichert werden.

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"]
EOF

is.yaml

$ tee is.yaml<<EOF
apiVersion: v1
kind: ImageStream
metadata:
  generation: 1
  labels:
    build: jmeter-web
  name: jmeter-web
EOF

bc.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
EOF

Lasst uns kreieren ImageStream и BuildConfig Objekte:

$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftest

Ein Bild sammeln von Dockerfile:

$ oc start-build jmeter-web -n perftest --from-dir=. --follow

dc.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
EOF

sc.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
EOF

Lassen Sie uns Objekte erstellen Service и DeploymentConfig:

$ oc create -f sc.yaml -n perftest
$ oc create -f dc.yaml -n perftest

Jmeter-Meister

Beginnen wir mit der Bereitstellung des Apache-Webservers.

Dies ist die Docker-Datei jmeter-master'a, basierend auf jmeter-base, das Tests durchführt und die Ergebnisse im Speicher speichert.

Dockerfile

Dockerfile für jmeter-master, bezogen auf 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 Dies ist ein Skript, das JMeter ausführt und die Ergebnisse in einem Verzeichnis speichert files.

Bei jedem Start des Skripts werden vorherige Tests gelöscht, sodass Sie nur mit den neuesten Daten arbeiten können. Dies ist jedoch kein Problem, da Sie es an Ihre Bedürfnisse anpassen können.

#!/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
done

is.yaml

$ tee is.yaml<<EOF
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  generation: 1
  labels:
    build: jmeter-master
  name: jmeter-master
EOF

bc.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
EOF

Lasst uns kreieren IS и BC Objekte:

$ oc create -f is.yaml -n perftest
$ oc create -f bc.yaml -n perftest

Wir sammeln jmeter-master Bild:

$ oc start-build jmeter-master -n perftest --from-dir=. --follow

Job

Jobwerden in verwendet OpenShift'e, um einen oder mehrere auszuführen POD's und garantieren deren erfolgreichen Abschluss nach der Ausführung des Befehls/Skripts.

$ 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
EOF

Erstellen Sie ein Objekt Job:

$ oc create -f job.yaml -n perftest

Lassen Sie uns den Status des Jobs überprüfen:

$ oc get jobs -n perftest
NAME            DESIRED   SUCCESSFUL   AGE
jmeter-master   1         1            5m

Löschen Job verwenden wir den Befehl:

$ oc delete jobs/jmeter-master -n perftest --ignore-not-found=true

Jenkins-Pipeline

Jetzt Automatisierung. Gehen wir die Schritte noch einmal durch:

  1. git clone
  2. oc whoami -t
  3. oc start-build ...
  4. oc delete jobs/jmeter-master
  5. oc create -f job.yaml -n perftest

Nachfolgend finden Sie eine Pipeline, in der das Klonen, Löschen und Erstellen von OpenShift-Repositorys durchgeführt wird Job'S.

#!groovy

pipeline {

    agent any

    stages {

        stage('Start Notifications') {
            steps {
                echo "Sending Email Notification"
            }
            post {
                always {
                    echo "STARTED - Performance Tests"
                    mail(to: '[email protected]', from: "[email protected]", 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: '[email protected]', from: "[email protected]", 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: '[email protected]', from: "[email protected]", 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}"
            }
        }

    }
}

Nachdem Pipeline seinen Betrieb abgeschlossen hat, erhalten wir eine Benachrichtigung per E-Mail '[email protected] aus [email protected].

Durch Klicken auf den Link http://jmeter-web.127.0.0.1.nip.io/ Wir werden das Verzeichnis sehen files, das Testberichte speichert:

Ausführen von JMeter-Tests in OpenShift mit Jenkins Pipeline

Dateiinhalte 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,259

Abschluss

In diesem Artikel wurde eine der Optionen zum Ausführen von JMeter-Tests in der OpenShift-Umgebung vorgestellt. Wir haben alle Schritte manuell ausgeführt und anschließend die Jenkins-Pipeline erstellt, um den Prozess der Testausführung zu automatisieren.

Quellen und Dokumentation

Source: habr.com

Kommentar hinzufügen