Het uitvoeren van JMeter-tests in OpenShift met behulp van Jenkins Pipeline

Hallo allemaal!

In dit artikel wil ik een van de manieren delen om prestatietests met JMeter uit te voeren in OpenShift met Jenkins als automatisering. Eerst zullen we alle benodigde stappen (zoals het aanmaken ImageStreams, BuildConfig, Job en dergelijke) handmatig doorlopen. Daarna schrijven we een Jenkins Pipeline.

Als uitgangspunt moeten we het volgende hebben:

  1. een werkcluster OpenShift (v3.11)
  2. een Jenkins-server met geconfigureerde inloggegevens voor OpenShift
  3. bestand apache-jmeter-5.2.tgz

De tests zullen eenvoudig zijn HTTP Request en een werkende opdracht krijgen. ya.ru in ƩƩn thread.

Een project aanmaken in OpenShift

Laten we beginnen met het aanmaken van een nieuwe omgeving. We creƫren perftest omgeving met het volgende commando:

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

We worden automatisch naar de zojuist gecreƫerde omgeving geleid perftest, laten we controleren of dat klopt:

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

Storage aanmaken

De testverslagen worden opgeslagen in een gedeelde map voor de webserver en jmeter-meter's plek — /jmeter/reports.

Het is beter om de storage nu aan te maken, omdat de POD's jmeter-web en jmeter-master.

Hier vindt u meer gedetailleerde informatie over de opslag in de officiƫle documentatie Persistent Storage.

Laten we yaml-bestanden aanmaken voor PV en 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

unit PV en PVC in de OpenShift-omgeving:

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

Controleer de status voor 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

Zo zal het eruitzien in de GUI:

Het uitvoeren van JMeter-tests in OpenShift met behulp van Jenkins Pipeline

Basisbeeld van JMeter aanmaken

Laten we overgaan tot het maken van ImageStream en BuildConfig.

Alle benodigde informatie kunt u vinden in de documentatie — Builds and Image Streams.

Als bouwstrategie voor afbeeldingen wordt gebruik gemaakt van Docker een lokale bron.

Laten we een basisbeeld aanmaken jmeter-base, dat de basis zal zijn voor 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

Laten we de objecten maken IS en BC:

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

Laten we het basisbeeld bouwen jmeter-base:

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

JMeter WEB

jmeter-web dit is een Apache-webserver. Zijn taak is het aanbieden van een directory met testresultaten voor weergave.

Voorbereid Dockerfile en configuratiebestand httpd.conf. Voor de directive DocumentRoot is ingesteld op /jmeter/reports, dat wil zeggen de directory waarin de testresultaten worden opgeslagen.

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

unit ImageStream en BuildConfig objecten:

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

We bouwen het beeld vanuit 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

Laten we de objecten maken Service en DeploymentConfig:

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

Jmeter-master

Laten we de deployment van de Apache-webserver aanpakken.

Dit is de Dockerfile jmeter-masterā€˜a, gebaseerd op jmeter-base, die tests zal uitvoeren en resultaten zal opslaan in de opslag.

Dockerfile

Dockerfile voor jmeter-master, gebaseerd op 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 dit is een script dat JMeter uitvoert en de resultaten opslaat in de directory files.

Bij elke uitvoering verwijdert het script de vorige tests, zodat je alleen met de laatste gegevens kunt werken. Maar dat is geen probleem, want het kan worden aangepast aan je behoeften.

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

unit IS en BC objecten:

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

Verzamelen jmeter-master beeld:

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

Job

Jobā€˜y worden gebruikt in OpenShiftā€˜e om ƩƩn of meerdere PODā€˜s te starten en hun succesvolle voltooiing na het uitvoeren van het commando/script te garanderen.

$ 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

Object aanmaken Job:

$ oc create -f job.yaml -n perftest

Laten we de status van de job controleren:

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

Om te verwijderen Job gebruiken we het commando:

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

Jenkins Pipeline

Nu automatisering. Laten we de stappen nog eens doornemen:

  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

Hieronder staat de pipeline waarin het klonen van de repository, het verwijderen en het aanmaken van OpenShift Jobā€˜s worden uitgevoerd.

#!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>START - Prestatie Tests</strong><br /><br />Project: Naam van Project<br />Omgeving: PerfTest<br />Buildnummer: ${env.BUILD_NUMBER}<br />Build URL:   ${env.BUILD_URL}"
                }
            }
        }

        fase('Git checkout') {
            stappen {
                ...
            }
        }

        fase('Prestatie Tests') {
            stappen {
                script {
                    sh '''
                        OC_CMD1="oc login -u=gebruikersnaam -p=WACHTWOORD -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 "GEFAILED - Prestatie Tests"
                mail(to: 'gebruikersnaam@srv.net', from: "jenkins@srv.net", subject: "GEFAILED - Prestatie Tests",mimeType: "text/html", body: "<strong>GEFAILED - Prestatie Tests</strong><br /><br />Project: Naam van Project<br />Omgeving: PerfTest<br />Buildnummer: ${env.BUILD_NUMBER}<br />Build URL: ${env.BUILD_URL}"
                }

            success {
                echo "SUCCESSED - Prestatie Tests"
                mail(to: 'gebruikersnaam@srv.net', from: "jenkins@srv.net", subject: "SUCCESSED - Prestatie Tests",mimeType: "text/html", body: "<strong>SUCCESSED - Prestatie Tests</strong><br /><br />Project: Naam van Project<br />Omgeving: PerfTest<br />Buildnummer: ${env.BUILD_NUMBER}<br />Build URL:   ${env.BUILD_URL}"
            }
        }

    }
}

Nadat de pipeline is uitgevoerd, ontvangen we een melding op ons e-mailadres 'username@srv.net van jenkins@srv.net.

Door de link te volgen http://jmeter-web.127.0.0.1.nip.io/ zien we de directory files, waar de testrapporten zijn opgeslagen:

Het uitvoeren van JMeter-tests in OpenShift met behulp van Jenkins Pipeline

De inhoud van het bestand 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

Conclusie

In dit artikel werd een van de manieren getoond om JMeter-tests uit te voeren in een OpenShift-omgeving. We hebben alle stappen handmatig doorlopen en vervolgens een Jenkins Pipeline gemaakt voor de automatisering van het teststartproces.

Bronnen en documentatie

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster