Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Kustomisasi gambar kontainer
Muat gambar tester
Solusi ini menggunakan repositori image Amazon Elastic Container Registry (Amazon ECR) publik yang dikelola oleh AWS untuk menyimpan gambar yang digunakan untuk menjalankan pengujian yang dikonfigurasi. Jika Anda ingin menyesuaikan gambar kontainer, Anda dapat membangun kembali dan mendorong gambar ke dalam repositori gambar ECR di akun AWS Anda sendiri.
Jika Anda ingin menyesuaikan solusi ini, Anda dapat menggunakan gambar kontainer default atau, edit wadah ini agar sesuai dengan kebutuhan Anda. Jika Anda menyesuaikan solusinya, gunakan contoh kode berikut untuk mendeklarasikan variabel lingkungan sebelum membuat solusi khusus Anda.
#!/bin/bash export REGION=aws-region-code # the AWS region to launch the solution (e.g. us-east-1) export BUCKET_PREFIX=my-bucket-name # prefix of the bucket name without the region code export BUCKET_NAME=$BUCKET_PREFIX-$REGION # full bucket name where the code will reside export SOLUTION_NAME=my-solution-name export VERSION=my-version # version number for the customized code export PUBLIC_ECR_REGISTRY=public.ecr.aws/awssolutions/distributed-load-testing-on-aws-load-tester # replace with the container registry and image if you want to use a different container image export PUBLIC_ECR_TAG=v3.1.0 # replace with the container image tag if you want to use a different container image
Jika Anda memilih untuk menyesuaikan gambar kontainer, Anda dapat menghostingnya di repositori gambar pribadi, atau repositori gambar publik di akun AWS Anda. Sumber daya gambar ada di deployment/ecr/distributed-load-testing-on-aws-load-tester direktori, terletak di basis kode.
Anda dapat membangun dan mendorong gambar ke tujuan host.
-
Untuk repositori dan gambar Amazon ECR pribadi, lihat repositori pribadi Amazon ECR dan gambar pribadi di Panduan Pengguna Amazon ECR.
-
Untuk repositori dan gambar ECR Amazon publik, lihat repositori publik Amazon ECR dan gambar publik di Panduan Pengguna Publik Amazon ECR.
Setelah Anda membuat gambar Anda sendiri, Anda dapat mendeklarasikan variabel lingkungan berikut sebelum membangun solusi khusus Anda.
#!/bin/bash export PUBLIC_ECR_REGISTRY=YOUR_ECR_REGISTRY_URI # e.g. YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/YOUR_IMAGE_NAME export PUBLIC_ECR_TAG=YOUR_ECR_TAG # e.g. latest, v3.4.0
Contoh berikut menunjukkan file kontainer.
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal RUN dnf update -y && \ dnf install -y python3.11 python3.11-pip java-21-amazon-corretto bc procps jq findutils unzip && \ dnf clean all ENV PIP_INSTALL="pip3.11 install --no-cache-dir" # install bzt RUN $PIP_INSTALL --upgrade bzt awscli setuptools==78.1.1 h11 urllib3==2.2.2 && \ $PIP_INSTALL --upgrade bzt COPY ./.bzt-rc /root/.bzt-rc RUN chmod 755 /root/.bzt-rc # install bzt tools RUN bzt -install-tools -o modules.install-checker.exclude=selenium,gatling,tsung,siege,ab,k6,external-results-loader,locust,junit,testng,rspec,mocha,nunit,xunit,wdio,robot,newman RUN rm -rf /root/.bzt/selenium-taurus RUN mkdir /bzt-configs /tmp/artifacts ADD ./load-test.sh /bzt-configs/ ADD ./*.jar /bzt-configs/ ADD ./*.py /bzt-configs/ RUN chmod 755 /bzt-configs/load-test.sh RUN chmod 755 /bzt-configs/ecslistener.py RUN chmod 755 /bzt-configs/ecscontroller.py RUN chmod 755 /bzt-configs/jar_updater.py RUN python3.11 /bzt-configs/jar_updater.py # Remove jar files from /tmp RUN rm -rf /tmp/jmeter-plugins-manager-1* && \ rm -rf /usr/local/lib/python3.11/site-packages/setuptools-65.5.0.dist-info && \ rm -rf /usr/local/lib/python3.11/site-packages/urllib3-1.26.17.dist-info # Add settings file to capture the output logs from bzt cli RUN mkdir -p /etc/bzt.d && echo '{"settings": {"artifacts-dir": "/tmp/artifacts"}}' > /etc/bzt.d/90-artifacts-dir.json WORKDIR /bzt-configs ENTRYPOINT ["./load-test.sh"]
Selain file kontainer, direktori berisi skrip bash berikut yang mengunduh konfigurasi pengujian dari Amazon S3 sebelum menjalankan Taurus/Blazemeter program.
#!/bin/bash # set a uuid for the results xml file name in S3 UUID=$(cat /proc/sys/kernel/random/uuid) pypid=0 echo "S3_BUCKET:: ${S3_BUCKET}" echo "TEST_ID:: ${TEST_ID}" echo "TEST_TYPE:: ${TEST_TYPE}" echo "FILE_TYPE:: ${FILE_TYPE}" echo "PREFIX:: ${PREFIX}" echo "UUID:: ${UUID}" echo "LIVE_DATA_ENABLED:: ${LIVE_DATA_ENABLED}" echo "MAIN_STACK_REGION:: ${MAIN_STACK_REGION}" cat /proc/self/cgroup TASK_ID=$(grep -oE '[a-f0-9]{32}' /proc/self/cgroup | head -n 1) echo $TASK_ID sigterm_handler() { if [ $pypid -ne 0 ]; then echo "container received SIGTERM." kill -15 $pypid wait $pypid exit 143 #128 + 15 fi } trap 'sigterm_handler' SIGTERM echo "Download test scenario" aws s3 cp s3://$S3_BUCKET/test-scenarios/$TEST_ID-$AWS_REGION.json test.json --region $MAIN_STACK_REGION # Set the default log file values to jmeter LOG_FILE="jmeter.log" OUT_FILE="jmeter.out" ERR_FILE="jmeter.err" KPI_EXT="jtl" # download JMeter jmx file if [ "$TEST_TYPE" != "simple" ]; then # setting the log file values to the test type LOG_FILE="${TEST_TYPE}.log" OUT_FILE="${TEST_TYPE}.out" ERR_FILE="${TEST_TYPE}.err" # set variables based on TEST_TYPE if [ "$TEST_TYPE" == "jmeter" ]; then EXT="jmx" TYPE_NAME="JMeter" # Copy *.jar to JMeter library path. See the Taurus JMeter path: https://gettaurus.org/docs/JMeter/ JMETER_LIB_PATH=`find ~/.bzt/jmeter-taurus -type d -name "lib"` echo "cp $PWD/*.jar $JMETER_LIB_PATH" cp $PWD/*.jar $JMETER_LIB_PATH elif [ "$TEST_TYPE" == "k6" ]; then curl --output /tmp/artifacts/k6.rpm https://dl.k6.io/rpm/x86_64/k6-v0.58.0-amd64.rpm rpm -ivh /tmp/artifacts/k6.rpm dnf install -y k6 rm -rf /tmp/artifacts/k6.rpm EXT="js" KPI_EXT="csv" TYPE_NAME="K6" elif [ "$TEST_TYPE" == "locust" ]; then EXT="py" TYPE_NAME="Locust" fi if [ "$FILE_TYPE" != "zip" ]; then aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.$EXT ./ --region $MAIN_STACK_REGION else aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.zip ./ --region $MAIN_STACK_REGION unzip $TEST_ID.zip echo "UNZIPPED" ls -l # If zip and locust, make sure to pick locustfile if [ "$TEST_TYPE" != "locust" ]; then TEST_SCRIPT=$(find . -name "*.${EXT}" | head -n 1) else TEST_SCRIPT=$(find . -name "locustfile.py" | head -n 1) fi # only looks for the first test script file. TEST_SCRIPT=`find . -name "*.${EXT}" | head -n 1` echo $TEST_SCRIPT if [ -z "$TEST_SCRIPT" ]; then echo "There is no test script (.${EXT}) in the zip file." exit 1 fi sed -i -e "s|$TEST_ID.$EXT|$TEST_SCRIPT|g" test.json # copy bundled plugin jars to jmeter extension folder to make them available to jmeter BUNDLED_PLUGIN_DIR=`find $PWD -type d -name "plugins" | head -n 1` # attempt to copy only if a /plugins folder is present in upload if [ -z "$BUNDLED_PLUGIN_DIR" ]; then echo "skipping plugin installation (no /plugins folder in upload)" else # ensure the jmeter extensions folder exists JMETER_EXT_PATH=`find ~/.bzt/jmeter-taurus -type d -name "ext"` if [ -z "$JMETER_EXT_PATH" ]; then # fail fast - if plugins bundled they will be needed for the tests echo "jmeter extension path (~/.bzt/jmeter-taurus/**/ext) not found - cannot install bundled plugins" exit 1 fi cp -v $BUNDLED_PLUGIN_DIR/*.jar $JMETER_EXT_PATH fi fi fi #Download python script if [ -z "$IPNETWORK" ]; then python3.11 -u $SCRIPT $TIMEOUT & pypid=$! wait $pypid pypid=0 else aws s3 cp s3://$S3_BUCKET/Container_IPs/${TEST_ID}_IPHOSTS_${AWS_REGION}.txt ./ --region $MAIN_STACK_REGION export IPHOSTS=$(cat ${TEST_ID}_IPHOSTS_${AWS_REGION}.txt) python3.11 -u $SCRIPT $IPNETWORK $IPHOSTS fi echo "Running test" stdbuf -i0 -o0 -e0 bzt test.json -o modules.console.disable=true | stdbuf -i0 -o0 -e0 tee -a result.tmp | sed -u -e "s|^|$TEST_ID $LIVE_DATA_ENABLED |" CALCULATED_DURATION=`cat result.tmp | grep -m1 "Test duration" | awk -F ' ' '{ print $5 }' | awk -F ':' '{ print ($1 * 3600) + ($2 * 60) + $3 }'` # upload custom results to S3 if any # every file goes under $TEST_ID/$PREFIX/$UUID to distinguish the result correctly if [ "$TEST_TYPE" != "simple" ]; then if [ "$FILE_TYPE" != "zip" ]; then cat $TEST_ID.$EXT | grep filename > results.txt else cat $TEST_SCRIPT | grep filename > results.txt fi if [ -f results.txt ]; then sed -i -e 's/<stringProp name="filename">//g' results.txt sed -i -e 's/<\/stringProp>//g' results.txt sed -i -e 's/ //g' results.txt echo "Files to upload as results" cat results.txt files=(`cat results.txt`) extensions=() for f in "${files[@]}"; do ext="${f##*.}" if [[ ! " ${extensions[@]} " =~ " ${ext} " ]]; then extensions+=("$ext") fi done # Find all files in the current folder with the same extensions all_files=() for ext in "${extensions[@]}"; do for f in *."$ext"; do all_files+=("$f") done done for f in "${all_files[@]}"; do p="s3://$S3_BUCKET/results/$TEST_ID/${TYPE_NAME}_Result/$PREFIX/$UUID/$f" if [[ $f = /* ]]; then p="s3://$S3_BUCKET/results/$TEST_ID/${TYPE_NAME}_Result/$PREFIX/$UUID$f" fi echo "Uploading $p" aws s3 cp $f $p --region $MAIN_STACK_REGION done fi fi if [ -f /tmp/artifacts/results.xml ]; then # Insert the Task ID at the same level as <FinalStatus> curl -s $ECS_CONTAINER_METADATA_URI_V4/task Task_CPU=$(curl -s $ECS_CONTAINER_METADATA_URI_V4/task | jq '.Limits.CPU') Task_Memory=$(curl -s $ECS_CONTAINER_METADATA_URI_V4/task | jq '.Limits.Memory') START_TIME=$(curl -s "$ECS_CONTAINER_METADATA_URI_V4/task" | jq -r '.Containers[0].StartedAt') # Convert start time to seconds since epoch START_TIME_EPOCH=$(date -d "$START_TIME" +%s) # Calculate elapsed time in seconds CURRENT_TIME_EPOCH=$(date +%s) ECS_DURATION=$((CURRENT_TIME_EPOCH - START_TIME_EPOCH)) sed -i.bak 's/<\/FinalStatus>/<TaskId>'"$TASK_ID"'<\/TaskId><\/FinalStatus>/' /tmp/artifacts/results.xml sed -i 's/<\/FinalStatus>/<TaskCPU>'"$Task_CPU"'<\/TaskCPU><\/FinalStatus>/' /tmp/artifacts/results.xml sed -i 's/<\/FinalStatus>/<TaskMemory>'"$Task_Memory"'<\/TaskMemory><\/FinalStatus>/' /tmp/artifacts/results.xml sed -i 's/<\/FinalStatus>/<ECSDuration>'"$ECS_DURATION"'<\/ECSDuration><\/FinalStatus>/' /tmp/artifacts/results.xml echo "Validating Test Duration" TEST_DURATION=$(grep -E '<TestDuration>[0-9]+.[0-9]+</TestDuration>' /tmp/artifacts/results.xml | sed -e 's/<TestDuration>//' | sed -e 's/<\/TestDuration>//') if (( $(echo "$TEST_DURATION > $CALCULATED_DURATION" | bc -l) )); then echo "Updating test duration: $CALCULATED_DURATION s" sed -i.bak.td 's/<TestDuration>[0-9]*\.[0-9]*<\/TestDuration>/<TestDuration>'"$CALCULATED_DURATION"'<\/TestDuration>/' /tmp/artifacts/results.xml fi if [ "$TEST_TYPE" == "simple" ]; then TEST_TYPE="jmeter" fi echo "Uploading results, bzt log, and JMeter log, out, and err files" aws s3 cp /tmp/artifacts/results.xml s3://$S3_BUCKET/results/${TEST_ID}/${PREFIX}-${UUID}-${AWS_REGION}.xml --region $MAIN_STACK_REGION aws s3 cp /tmp/artifacts/bzt.log s3://$S3_BUCKET/results/${TEST_ID}/bzt-${PREFIX}-${UUID}-${AWS_REGION}.log --region $MAIN_STACK_REGION aws s3 cp /tmp/artifacts/$LOG_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.log --region $MAIN_STACK_REGION aws s3 cp /tmp/artifacts/$OUT_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.out --region $MAIN_STACK_REGION aws s3 cp /tmp/artifacts/$ERR_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.err --region $MAIN_STACK_REGION aws s3 cp /tmp/artifacts/kpi.${KPI_EXT} s3://$S3_BUCKET/results/${TEST_ID}/kpi-${PREFIX}-${UUID}-${AWS_REGION}.${KPI_EXT} --region $MAIN_STACK_REGION else echo "An error occurred while the test was running." fi
Selain Dockerfileecslistener.py skrip, sedangkan tugas pemimpin akan menjalankan ecscontroller.py skrip. ecslistener.pyScript membuat soket pada port 50000 dan menunggu pesan. ecscontroller.pySkrip terhubung ke soket dan mengirimkan pesan uji awal ke tugas pekerja, yang memungkinkan mereka untuk memulai secara bersamaan.
Gambar konsol web (hanya template ALB+ECS Fargate)
Template ALB+ECS Fargate menjalankan konsol web sebagai wadah di ECS Fargate. Secara default, solusinya menarik image konsol web dari repositori ECR Amazon publik yang dikelola oleh AWS.
Di lingkungan di mana akses ke pendaftar kontainer publik dibatasi (misalnya, VPC tanpa akses internet atau akun dengan kebijakan akses publik ECR), Anda harus mencerminkan citra publik ke repositori Amazon ECR pribadi dan menyediakan URI gambar pribadi dalam parameter URI Gambar Konsol Web. CloudFormation Anda juga dapat menggunakan pendekatan ini untuk menyesuaikan gambar konsol web agar sesuai dengan kebutuhan Anda.
Cerminkan citra publik ke repositori ECR pribadi
Untuk mencerminkan gambar konsol web ke repositori ECR pribadi:
-
Otentikasi ke registri ECR publik:
$ aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws -
Tarik gambar konsol web publik:
$ docker pull public.ecr.aws/aws-solutions/distributed-load-testing-on-aws-web-console:<version> -
Buat repositori ECR pribadi di akun Anda (jika belum ada):
$ aws ecr create-repository --repository-name <your-repo-name> --region <region> 2>/dev/null || true -
Otentikasi ke registri ECR pribadi Anda:
$ aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account-id>.dkr.ecr.<region>.amazonaws.com -
Tandai dan dorong gambar ke repositori pribadi Anda:
$ docker tag public.ecr.aws/aws-solutions/distributed-load-testing-on-aws-web-console:<version> \ <account-id>.dkr.ecr.<region>.amazonaws.com/<your-repo-name>:<version> $ docker push <account-id>.dkr.ecr.<region>.amazonaws.com/<your-repo-name>:<version> -
Saat meluncurkan tumpukan ALB+ECS Fargate, masukkan URI gambar pribadi di parameter URI Gambar Konsol Web:
<account-id>.dkr.ecr.<region>.amazonaws.com/<your-repo-name>:<version>
Sesuaikan gambar konsol web
Anda juga dapat menyesuaikan gambar konsol web. Sumber daya gambar ada di deployment/ecr/distributed-load-testing-on-aws-web-console direktori, yang terletak di GitHub repositori
Kontainer konsol web menggunakan Nginx untuk melayani aplikasi web statis. Saat startup, skrip entrypoint mengunduh aset konsol web dari Amazon S3 dan mengekstraknya ke root dokumen Nginx.
Contoh berikut menunjukkan file kontainer.
FROM public.ecr.aws/nginx/nginx:alpine # Install AWS CLI for S3 operations RUN apk upgrade --no-cache zlib libpng && \ apk add --no-cache aws-cli # Copy nginx configuration COPY nginx.conf /etc/nginx/nginx.conf # Copy entrypoint script COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh EXPOSE 80 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
Skrip entrypoint mengunduh aset konsol web dari S3 dan memulai Nginx.
#!/bin/sh set -e S3_URI="s3://${S3_BUCKET}/${S3_KEY}" echo "[$(date -Iseconds)] Downloading from $S3_URI" # AWS CLI has built-in retry with exponential backoff (standard mode) AWS_MAX_ATTEMPTS=5 aws s3 cp "$S3_URI" /tmp/web-app.zip echo "[$(date -Iseconds)] Download successful" # Extract and cleanup unzip -o /tmp/web-app.zip -d /usr/share/nginx/html/ rm -f /tmp/web-app.zip # Start Nginx exec nginx -g 'daemon off;'
Konfigurasi Nginx melayani aplikasi satu halaman (SPA) dengan dukungan pemeriksaan kesehatan untuk ALB, kompresi gzip, caching aset statis, dan header keamanan.
events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; server { listen 80; root /usr/share/nginx/html; index index.html; # Health check endpoint for ALB location /healthz { return 200 'OK'; } # SPA routing location / { try_files $uri $uri/ /index.html; } # Cache static assets for 1 year location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } # No cache for index.html (SPA entry point) location = /index.html { add_header Cache-Control "no-cache, no-store, must-revalidate"; } # No cache for runtime config location = /aws-exports.json { add_header Cache-Control "no-store, no-cache, must-revalidate"; } # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; } }
Untuk informasi selengkapnya, lihat Mendorong gambar Docker ke repositori pribadi Amazon ECR di Panduan Pengguna Amazon ECR.