From aaa7f46911418c06090cfb5d78ed7263ad954f9f Mon Sep 17 00:00:00 2001 From: feczo Date: Tue, 4 Oct 2016 16:14:37 +0200 Subject: [PATCH 01/13] gcloud app is not in preview anymore eg.: WARNING: The `gcloud preview app` command group is deprecated; please use the `gcloud app` commands instead. Google Cloud SDK 128.0.0 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be207fa..18e9669 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This tutorial demonstrates how to conduct distributed load testing using [Kubern **Note:** when installing the Google Cloud SDK you will need to enable the following additional components: -* `App Engine Command Line Interface (Preview)` +* `App Engine Command Line Interface` * `App Engine SDK for Python and PHP` * `Compute Engine Command Line Interface` * `Developer Preview gcloud Commands` @@ -24,9 +24,9 @@ Before continuing, you can also set your preferred zone and project: ## Deploy Web Application -The `sample-webapp` folder contains a simple Google App Engine Python application as the "system under test". To deploy the application to your project use the `gcloud preview app deploy` command. +The `sample-webapp` folder contains a simple Google App Engine Python application as the "system under test". To deploy the application to your project use the `gcloud app deploy` command. - $ gcloud preview app deploy sample-webapp/app.yaml --project=PROJECT-ID --set-default + $ gcloud app deploy sample-webapp/app.yaml --project=PROJECT-ID **Note:** you will need the URL of the deployed sample web application when deploying the `locust-master` and `locust-worker` controllers. @@ -155,4 +155,4 @@ To delete the sample web application, visit the [Google Cloud Console](https://c ## License -This code is Apache 2.0 licensed and more information can be found in `LICENSE`. For information on licenses for third party software and libraries, refer to the `docker-image/licenses` directory. \ No newline at end of file +This code is Apache 2.0 licensed and more information can be found in `LICENSE`. For information on licenses for third party software and libraries, refer to the `docker-image/licenses` directory. From 0fe91911bcc609b3764445b1ac307f7f048becd6 Mon Sep 17 00:00:00 2001 From: Eric Tune Date: Tue, 27 Jun 2017 15:50:04 -0700 Subject: [PATCH 02/13] Remove incorrect key from "env" spec There is no "key" in an "env". Just "name". Reference docs: https://kubernetes.io/docs/api-reference/v1.6/#envvar-v1-core Verified using kubectl 1.5.4 / server 1.6.4. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index be207fa..794f23b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ The `sample-webapp` folder contains a simple Google App Engine Python applicatio Before deploying the `locust-master` and `locust-worker` controllers, update each to point to the location of your deployed sample web application. Set the `TARGET_HOST` environment variable found in the `spec.template.spec.containers.env` field to your sample web application URL. - name: TARGET_HOST - key: TARGET_HOST value: http://PROJECT-ID.appspot.com ### Update Controller Docker Image (Optional) @@ -155,4 +154,4 @@ To delete the sample web application, visit the [Google Cloud Console](https://c ## License -This code is Apache 2.0 licensed and more information can be found in `LICENSE`. For information on licenses for third party software and libraries, refer to the `docker-image/licenses` directory. \ No newline at end of file +This code is Apache 2.0 licensed and more information can be found in `LICENSE`. For information on licenses for third party software and libraries, refer to the `docker-image/licenses` directory. From 5acb1e6d1177d6f733227b5bef2ad0c577de2375 Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Fri, 4 May 2018 10:28:57 -0700 Subject: [PATCH 03/13] Remove key from env listing --- kubernetes-config/locust-master-controller.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/kubernetes-config/locust-master-controller.yaml b/kubernetes-config/locust-master-controller.yaml index fa4468c..231e730 100644 --- a/kubernetes-config/locust-master-controller.yaml +++ b/kubernetes-config/locust-master-controller.yaml @@ -36,10 +36,8 @@ spec: image: gcr.io/cloud-solutions-images/locust-tasks:latest env: - name: LOCUST_MODE - key: LOCUST_MODE value: master - name: TARGET_HOST - key: TARGET_HOST value: http://workload-simulation-webapp.appspot.com ports: - name: loc-master-web From fffcc301040145fee3c3053bde703f3f45d1f54a Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Fri, 4 May 2018 10:29:39 -0700 Subject: [PATCH 04/13] Remove key from env listing --- kubernetes-config/locust-worker-controller.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/kubernetes-config/locust-worker-controller.yaml b/kubernetes-config/locust-worker-controller.yaml index 883c450..236eae5 100644 --- a/kubernetes-config/locust-worker-controller.yaml +++ b/kubernetes-config/locust-worker-controller.yaml @@ -36,11 +36,8 @@ spec: image: gcr.io/cloud-solutions-images/locust-tasks:latest env: - name: LOCUST_MODE - key: LOCUST_MODE value: worker - name: LOCUST_MASTER - key: LOCUST_MASTER value: locust-master - name: TARGET_HOST - key: TARGET_HOST value: http://workload-simulation-webapp.appspot.com From 303650d55f37262b5eb6d9d93b1a0ddd3e7536b3 Mon Sep 17 00:00:00 2001 From: Vic Iglesias Date: Fri, 4 May 2018 11:02:56 -0700 Subject: [PATCH 05/13] Update README.md --- README.md | 52 +++++++--------------------------------------------- 1 file changed, 7 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 3a757d6..c4d38d7 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,6 @@ This tutorial demonstrates how to conduct distributed load testing using [Kubern * `App Engine Command Line Interface` * `App Engine SDK for Python and PHP` * `Compute Engine Command Line Interface` -* `Developer Preview gcloud Commands` -* `gcloud Alpha Commands` * `gcloud app Python Extensions` * `kubectl` @@ -43,9 +41,7 @@ The `locust-master` and `locust-worker` controllers are set to use the pre-built First, [install Docker](https://docs.docker.com/installation/#installation) on your platform. Once Docker is installed and you've made changes to the `Dockerfile`, you can build, tag, and upload the image using the following steps: - $ docker build -t USERNAME/locust-tasks . - $ docker tag USERNAME/locust-tasks gcr.io/PROJECT-ID/locust-tasks - $ gcloud preview docker --project PROJECT-ID push gcr.io/PROJECT-ID/locust-tasks + $ gcloud container builds submit --tag gcr.io/PROJECT-ID/locust-tasks:latest . **Note:** you are not required to use the Google Container Registry. If you'd like to publish your images to the [Docker Hub](https://hub.docker.com) please refer to the steps in [Working with Docker Hub](https://docs.docker.com/userguide/dockerrepos/). @@ -63,17 +59,9 @@ If you uploaded your Docker image to the Docker Hub: ### Deploy Kubernetes Cluster -First create the [Google Container Engine](http://cloud.google.com/container-engine) cluster using the `gcloud` command as shown below. +First create the [Google Kubernetes Engine](http://cloud.google.com/kubernetes-engine) cluster using the `gcloud` command as shown below. -**Note:** This command defaults to creating a three node Kubernetes cluster (not counting the master) using the `n1-standard-1` machine type. Refer to the [`gcloud alpha container clusters create`](https://cloud.google.com/sdk/gcloud/reference/alpha/container/clusters/create) documentation information on specifying a different cluster configuration. - - $ gcloud alpha container clusters create CLUSTER-NAME - -After a few minutes, you'll have a working Kubernetes cluster with three nodes (not counting the Kubernetes master). Next, configure your system to use the `kubectl` command: - - $ kubectl config use-context gke_PROJECT-ID_ZONE_CLUSTER-NAME - -**Note:** the output from the previous `gcloud` cluster create command will contain the specific `kubectl config` command to execute for your platform/project. + $ gcloud container clusters create CLUSTER-NAME ### Deploy locust-master @@ -90,9 +78,9 @@ Next, deploy the `locust-master-service`: $ kubectl create -f locust-master-service.yaml -This step will expose the Pod with an internal DNS name (`locust-master`) and ports `8089`, `5557`, and `5558`. As part of this step, the `type: LoadBalancer` directive in `locust-master-service.yaml` will tell Google Container Engine to create a Google Compute Engine forwarding-rule from a publicly avaialble IP address to the `locust-master` Pod. To view the newly created forwarding-rule, execute the following: +This step will expose the Pod with an internal DNS name (`locust-master`) and ports `8089`, `5557`, and `5558`. As part of this step, the `type: LoadBalancer` directive in `locust-master-service.yaml` will tell Google Kubernetes Engine to create a Google Compute Engine forwarding-rule from a publicly avaialble IP address to the `locust-master` Pod. To view the newly created forwarding-rule, execute the following: - $ gcloud compute forwarding-rules list + $ kubectl get svc locust-master ### Deploy locust-worker @@ -114,41 +102,15 @@ To confirm that the Pods have launched and are ready, get the list of `locust-wo **Note:** depending on the desired number of `locust-worker` Pods, the Kubernetes cluster may need to be launched with more than 3 compute engine nodes and may also need a machine type more powerful than n1-standard-1. Refer to the [`gcloud alpha container clusters create`](https://cloud.google.com/sdk/gcloud/reference/alpha/container/clusters/create) documentation for more information. -### Setup Firewall Rules - -The final step in deploying these controllers and services is to allow traffic from your publicly accessible forwarding-rule IP address to the appropriate Container Engine instances. - -The only traffic we need to allow externally is to the Locust web interface, running on the `locust-master` Pod at port `8089`. First, get the target tags for the nodes in your Kubernetes cluster using the output from `kubectl get nodes`: - - $ kubectl get nodes - NAME LABELS STATUS - gke-ws-0e365264-node-4pdw kubernetes.io/hostname=gke-ws-0e365264-node-4pdw Ready - gke-ws-0e365264-node-jdcz kubernetes.io/hostname=gke-ws-0e365264-node-jdcz Ready - gke-ws-0e365264-node-kp3d kubernetes.io/hostname=gke-ws-0e365264-node-kp3d Ready - -The target tag is the node name prefix up to `-node` and is formatted as `gke-CLUSTER-NAME-[...]-node`. For example, if your node name is `gke-mycluster-12345678-node-abcd`, the target tag would be `gke-mycluster-12345678-node`. - -Now to create the firewall rule, execute the following: - - $ gcloud compute firewall-rules create FIREWALL-RULE-NAME --allow=tcp:8089 --target-tags gke-CLUSTER-NAME-[...]-node - ## Execute Tests -To execute the Locust tests, navigate to the IP address of your forwarding-rule (see above) and port `8089` and enter the number of clients to spawn and the client hatch rate then start the simulation. +To execute the Locust tests, navigate to the IP address of your service (see above) and port `8089` and enter the number of clients to spawn and the client hatch rate then start the simulation. ## Deployment Cleanup To teardown the workload simulation cluster, use the following steps. First, delete the Kubernetes cluster: - $ gcloud alpha container clusters delete CLUSTER-NAME - -Next, delete the forwarding rule that forwards traffic into the cluster. - - $ gcloud compute forwarding-rules delete FORWARDING-RULE-NAME - -Finally, delete the firewall rule that allows incoming traffic to the cluster. - - $ gcloud compute firewall-rules delete FIREWALL-RULE-NAME + $ gcloud container clusters delete CLUSTER-NAME To delete the sample web application, visit the [Google Cloud Console](https://console.developers.google.com). From 3d811f1ceac4900320c68bbe3d3d725e78d8b208 Mon Sep 17 00:00:00 2001 From: Prakhar Date: Fri, 22 Mar 2019 14:21:16 +0530 Subject: [PATCH 06/13] change read me --- README.md | 158 +++++++++++++++++++++++++++++------------------------- 1 file changed, 86 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index c4d38d7..dd9fbd6 100644 --- a/README.md +++ b/README.md @@ -1,119 +1,133 @@ -## Distributed Load Testing Using Kubernetes +## Distribute Load Testing Using GKE -This tutorial demonstrates how to conduct distributed load testing using [Kubernetes](http://kubernetes.io) and includes a sample web application, Docker image, and Kubernetes controllers/services. For more background refer to the [Distributed Load Testing Using Kubernetes](http://cloud.google.com/solutions/distributed-load-testing-using-kubernetes) solution paper. +## Introduction -## Prerequisites +Load testing is key to the development of any backend infrastructure because load tests demonstrate how well the system functions when faced with real-world demands. An important aspect of load testing is the proper simulation of user and device behavior to identify and understand any possible system bottlenecks, well in advance of deploying applications to production. -* Google Cloud Platform account -* Install and setup [Google Cloud SDK](https://cloud.google.com/sdk/) +However, dedicated test infrastructure can be expensive and difficult to maintain because it is not needed on a continuous basis. Moreover, dedicated test infrastructure is often a one-time capital expense with a fixed capacity, which makes it difficult to scale load testing beyond the initial investment and can limit experimentation. This can lead to slowdowns in productivity for development teams and lead to applications that are not properly tested before production deployments. -**Note:** when installing the Google Cloud SDK you will need to enable the following additional components: +## Before you begin -* `App Engine Command Line Interface` -* `App Engine SDK for Python and PHP` -* `Compute Engine Command Line Interface` -* `gcloud app Python Extensions` -* `kubectl` +Open Cloud Shell to execute the commands listed in this tutorial. -Before continuing, you can also set your preferred zone and project: +Define environment variables for the project id, region and zone you want to use for this tutorial. - $ gcloud config set compute/zone ZONE - $ gcloud config set project PROJECT-ID + $ PROJECT=$(gcloud config get-value project) + $ REGION=us-central1 + $ ZONE=${REGION}-b + $ CLUSTER=gke-load-test + $ TARGET=${PROJECT}.appspot.com + $ gcloud config set compute/region $REGION + $ gcloud config set compute/zone $ZONE -## Deploy Web Application +**Note:** Following services should be enabled in your project: +Cloud Build +Kubernetes Engine +Google App Engine Admin API +Cloud Storage -The `sample-webapp` folder contains a simple Google App Engine Python application as the "system under test". To deploy the application to your project use the `gcloud app deploy` command. + $ gcloud services enable \ + cloudbuild.googleapis.com \ + compute.googleapis.com \ + container.googleapis.com \ + containeranalysis.googleapis.com \ + containerregistry.googleapis.com - $ gcloud app deploy sample-webapp/app.yaml --project=PROJECT-ID +## Load testing tasks -**Note:** you will need the URL of the deployed sample web application when deploying the `locust-master` and `locust-worker` controllers. +To deploy the load testing tasks, you first deploy a load testing master and then deploy a group of load testing workers. With these load testing workers, you can create a substantial amount of traffic for testing purposes. -## Deploy Controllers and Services +**Note:** Keep in mind that generating excessive amounts of traffic to external systems can resemble a denial-of-service attack. Be sure to review the Google Cloud Platform Terms of Service and the Google Cloud Platform Acceptable Use Policy. -Before deploying the `locust-master` and `locust-worker` controllers, update each to point to the location of your deployed sample web application. Set the `TARGET_HOST` environment variable found in the `spec.template.spec.containers.env` field to your sample web application URL. +## Load testing master - - name: TARGET_HOST - value: http://PROJECT-ID.appspot.com +The first component of the deployment is the Locust master, which is the entry point for executing the load testing tasks described above. The Locust master is deployed with a single replica because we need only one master. -### Update Controller Docker Image (Optional) +The configuration for the master deployment specifies several elements, including the ports that need to be exposed by the container (`8089` for web interface, `5557` and `5558` for communicating with workers). This information is later used to configure the Locust workers. The following snippet contains the configuration for the ports: -The `locust-master` and `locust-worker` controllers are set to use the pre-built `locust-tasks` Docker image, which has been uploaded to the [Google Container Registry](http://gcr.io) and is available at `gcr.io/cloud-solutions-images/locust-tasks`. If you are interested in making changes and publishing a new Docker image, refer to the following steps. + ports: + - name: loc-master-web + containerPort: 8089 + protocol: TCP + - name: loc-master-p1 + containerPort: 5557 + protocol: TCP + - name: loc-master-p2 + containerPort: 5558 + protocol: TCP -First, [install Docker](https://docs.docker.com/installation/#installation) on your platform. Once Docker is installed and you've made changes to the `Dockerfile`, you can build, tag, and upload the image using the following steps: +Next, we would deploy a Service to ensure that the exposed ports are accessible to other pods via `hostname:port` within the cluster, and referenceable via a descriptive port name. The use of a service allows the Locust workers to easily discover and reliably communicate with the master, even if the master fails and is replaced with a new pod by the deployment. The Locust master service also includes a directive to create an external forwarding rule at the cluster level (i.e. type of LoadBalancer), which provides the ability for external traffic to access the cluster resources. - $ gcloud container builds submit --tag gcr.io/PROJECT-ID/locust-tasks:latest . +After you deploy the Locust master, you can access the web interface using the public IP address of the external forwarding rule. After you deploy the Locust workers, you can start the simulation and look at aggregate statistics through the Locust web interface. -**Note:** you are not required to use the Google Container Registry. If you'd like to publish your images to the [Docker Hub](https://hub.docker.com) please refer to the steps in [Working with Docker Hub](https://docs.docker.com/userguide/dockerrepos/). +## Load testing workers -Once the Docker image has been rebuilt and uploaded to the registry you will need to edit the controllers with your new image location. Specifically, the `spec.template.spec.containers.image` field in each controller controls which Docker image to use. +The next component of the deployment includes the Locust workers, which execute the load testing tasks described above. The Locust workers are deployed by a single deployment that creates multiple pods. The pods are spread out across the Kubernetes cluster. Each pod uses environment variables to control important configuration information such as the hostname of the system under test and the hostname of the Locust master. -If you uploaded your Docker image to the Google Container Registry: +After the Locust workers are deployed, you can return to the Locust master web interface and see that the number of slaves corresponds to the number of deployed workers. - image: gcr.io/PROJECT-ID/locust-tasks:latest +## Setup -If you uploaded your Docker image to the Docker Hub: +1. Create GKE cluster - image: USERNAME/locust-tasks:latest + $ gcloud container clusters create $CLUSTER \ + --zone $ZONE \ + --scopes "https://www.googleapis.com/auth/cloud-platform" \ + --num-nodes "3" \ + --enable-autoscaling --min-nodes "3" \ + --max-nodes "10" \ + --addons HorizontalPodAutoscaling,HttpLoadBalancing -**Note:** the image location includes the `latest` tag so that the image is pulled down every time a new Pod is launched. To use a Kubernetes-cached copy of the image, remove `:latest` from the image location. + $ gcloud container clusters get-credentials $CLUSTER \ + --zone $ZONE \ + --project $PROJECT -### Deploy Kubernetes Cluster +2. Clone tutorial repo in a local directory on your cloud shell environment -First create the [Google Kubernetes Engine](http://cloud.google.com/kubernetes-engine) cluster using the `gcloud` command as shown below. + $ git clone - $ gcloud container clusters create CLUSTER-NAME +3. Build docker image and store it in your project's container registry -### Deploy locust-master + $ pushd gke-load-test + $ gcloud builds submit --tag gcr.io/$PROJECT/locust-tasks:latest docker-image/. -Now that `kubectl` is setup, deploy the `locust-master-controller`: +4. Deploy sample application on GAE - $ kubectl create -f locust-master-controller.yaml + $ gcloud app deploy sample-webapp/app.yaml --project=$PROJECT -To confirm that the Replication Controller and Pod are created, run the following: +5. Replace [TARGET_HOST] and [PROJECT_ID] in locust-master-controller.yaml and locust-worker-controller.yaml with the deployed endpoint and project-id respectively. - $ kubectl get rc - $ kubectl get pods -l name=locust,role=master + $ sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-master-controller.yaml + $ sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-worker-controller.yaml + $ sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-master-controller.yaml + $ sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-worker-controller.yaml -Next, deploy the `locust-master-service`: +6. Deploy Locust master and worker nodes: - $ kubectl create -f locust-master-service.yaml + $ kubectl apply -f kubernetes-config/locust-master-controller.yaml + $ kubectl apply -f kubernetes-config/locust-master-service.yaml + $ kubectl apply -f kubernetes-config/locust-worker-controller.yaml -This step will expose the Pod with an internal DNS name (`locust-master`) and ports `8089`, `5557`, and `5558`. As part of this step, the `type: LoadBalancer` directive in `locust-master-service.yaml` will tell Google Kubernetes Engine to create a Google Compute Engine forwarding-rule from a publicly avaialble IP address to the `locust-master` Pod. To view the newly created forwarding-rule, execute the following: +7. Get the external ip of Locust master service - $ kubectl get svc locust-master + $ EXTERNAL_IP=$(kubectl get svc locust-master -o yaml | grep ip | awk -F":" '{print $NF}') -### Deploy locust-worker +8. Starting load testing +The Locust master web interface enables you to execute the load testing tasks against the system under test, as shown in the following image. Access the url as http://$EXTERNAL_IP:8089. -Now deploy `locust-worker-controller`: +To begin, specify the total number of users to simulate and a rate at which each user should be spawned. Next, click Start swarming to begin the simulation. To stop the simulation, click **Stop** and the test will terminate. The complete results can be downloaded into a spreadsheet. - $ kubectl create -f locust-worker-controller.yaml +9. [Optional] Scaling clients +Scaling up the number of simulated users will require an increase in the number of Locust worker pods. To increase the number of pods deployed by the deployment, Kubernetes offers the ability to resize deployments without redeploying them. For example, the following command scales the pool of Locust worker pods to 20: -The `locust-worker-controller` is set to deploy 10 `locust-worker` Pods, to confirm they were deployed run the following: + $ kubectl scale deployment/locust-worker --replicas=20 - $ kubectl get pods -l name=locust,role=worker +## Cleaning up -To scale the number of `locust-worker` Pods, issue a replication controller `scale` command. - - $ kubectl scale --replicas=20 replicationcontrollers locust-worker - -To confirm that the Pods have launched and are ready, get the list of `locust-worker` Pods: - - $ kubectl get pods -l name=locust,role=worker - -**Note:** depending on the desired number of `locust-worker` Pods, the Kubernetes cluster may need to be launched with more than 3 compute engine nodes and may also need a machine type more powerful than n1-standard-1. Refer to the [`gcloud alpha container clusters create`](https://cloud.google.com/sdk/gcloud/reference/alpha/container/clusters/create) documentation for more information. - -## Execute Tests - -To execute the Locust tests, navigate to the IP address of your service (see above) and port `8089` and enter the number of clients to spawn and the client hatch rate then start the simulation. - -## Deployment Cleanup - -To teardown the workload simulation cluster, use the following steps. First, delete the Kubernetes cluster: - - $ gcloud container clusters delete CLUSTER-NAME - -To delete the sample web application, visit the [Google Cloud Console](https://console.developers.google.com). + $ gcloud container clusters delete $CLUSTER --zone $ZONE ## License This code is Apache 2.0 licensed and more information can be found in `LICENSE`. For information on licenses for third party software and libraries, refer to the `docker-image/licenses` directory. + + From be11c59dbefb6bb246ad64d69d86ff176a2b66e5 Mon Sep 17 00:00:00 2001 From: Prakhar Date: Fri, 22 Mar 2019 14:27:52 +0530 Subject: [PATCH 07/13] updated manifests and python dependencies --- docker-image/Dockerfile | 2 -- docker-image/locust-tasks/requirements.txt | 4 ++-- .../locust-master-controller.yaml | 20 ++++++++-------- kubernetes-config/locust-master-service.yaml | 6 ++--- .../locust-worker-controller.yaml | 23 ++++++++----------- 5 files changed, 23 insertions(+), 32 deletions(-) diff --git a/docker-image/Dockerfile b/docker-image/Dockerfile index f0db361..751083b 100644 --- a/docker-image/Dockerfile +++ b/docker-image/Dockerfile @@ -16,8 +16,6 @@ # Start with a base Python 2.7.8 image FROM python:2.7.8 -MAINTAINER Sandeep Parikh - # Add the licenses for third party software and libraries ADD licenses /licenses diff --git a/docker-image/locust-tasks/requirements.txt b/docker-image/locust-tasks/requirements.txt index 3684955..abc8f7c 100644 --- a/docker-image/locust-tasks/requirements.txt +++ b/docker-image/locust-tasks/requirements.txt @@ -1,4 +1,4 @@ -Flask==0.10.1 +Flask==0.12.3 gevent==1.0.1 greenlet==0.4.5 itsdangerous==0.24 @@ -7,5 +7,5 @@ locustio==0.7.2 MarkupSafe==0.23 msgpack-python==0.4.6 pyzmq==14.5.0 -requests==2.6.2 +requests==2.20.0 Werkzeug==0.10.4 diff --git a/kubernetes-config/locust-master-controller.yaml b/kubernetes-config/locust-master-controller.yaml index 231e730..63466f1 100644 --- a/kubernetes-config/locust-master-controller.yaml +++ b/kubernetes-config/locust-master-controller.yaml @@ -13,32 +13,30 @@ # limitations under the License. -kind: ReplicationController -apiVersion: v1 +apiVersion: "extensions/v1beta1" +kind: "Deployment" metadata: name: locust-master labels: - name: locust - role: master + name: locust-master spec: replicas: 1 selector: - name: locust - role: master + matchLabels: + app: locust-master template: metadata: labels: - name: locust - role: master + app: locust-master spec: containers: - - name: locust - image: gcr.io/cloud-solutions-images/locust-tasks:latest + - name: locust-master + image: gcr.io/[PROJECT_ID]/locust-tasks:latest env: - name: LOCUST_MODE value: master - name: TARGET_HOST - value: http://workload-simulation-webapp.appspot.com + value: https://[TARGET_HOST] ports: - name: loc-master-web containerPort: 8089 diff --git a/kubernetes-config/locust-master-service.yaml b/kubernetes-config/locust-master-service.yaml index 033460b..3757115 100644 --- a/kubernetes-config/locust-master-service.yaml +++ b/kubernetes-config/locust-master-service.yaml @@ -18,8 +18,7 @@ apiVersion: v1 metadata: name: locust-master labels: - name: locust - role: master + app: locust-master spec: ports: - port: 8089 @@ -35,6 +34,5 @@ spec: protocol: TCP name: loc-master-p2 selector: - name: locust - role: master + app: locust-master type: LoadBalancer diff --git a/kubernetes-config/locust-worker-controller.yaml b/kubernetes-config/locust-worker-controller.yaml index 236eae5..7c1a682 100644 --- a/kubernetes-config/locust-worker-controller.yaml +++ b/kubernetes-config/locust-worker-controller.yaml @@ -12,32 +12,29 @@ # See the License for the specific language governing permissions and # limitations under the License. - -kind: ReplicationController -apiVersion: v1 +apiVersion: "extensions/v1beta1" +kind: "Deployment" metadata: name: locust-worker labels: - name: locust - role: worker + name: locust-worker spec: - replicas: 10 + replicas: 5 selector: - name: locust - role: worker + matchLabels: + app: locust-worker template: metadata: labels: - name: locust - role: worker + app: locust-worker spec: containers: - - name: locust - image: gcr.io/cloud-solutions-images/locust-tasks:latest + - name: locust-worker + image: gcr.io/[PROJECT_ID]/locust-tasks:latest env: - name: LOCUST_MODE value: worker - name: LOCUST_MASTER value: locust-master - name: TARGET_HOST - value: http://workload-simulation-webapp.appspot.com + value: https://[TARGET_HOST] From d2589d48fefd451eb745734d7439d1045cdadebf Mon Sep 17 00:00:00 2001 From: Drew Stevens Date: Fri, 22 Mar 2019 19:33:55 -0700 Subject: [PATCH 08/13] upgrade locust 0.11.0, python 3.7 --- docker-image/Dockerfile | 4 +- docker-image/locust-tasks/requirements.txt | 29 ++++++++----- sample-webapp/app.py | 47 --------------------- sample-webapp/app.yaml | 8 ++-- sample-webapp/main.py | 48 ++++++++++++++++++++++ sample-webapp/requirements.txt | 1 + 6 files changed, 73 insertions(+), 64 deletions(-) delete mode 100644 sample-webapp/app.py create mode 100644 sample-webapp/main.py create mode 100644 sample-webapp/requirements.txt diff --git a/docker-image/Dockerfile b/docker-image/Dockerfile index 751083b..230756a 100644 --- a/docker-image/Dockerfile +++ b/docker-image/Dockerfile @@ -13,8 +13,8 @@ # limitations under the License. -# Start with a base Python 2.7.8 image -FROM python:2.7.8 +# Start with a base Python 3.7.2 image +FROM python:3.7.2 # Add the licenses for third party software and libraries ADD licenses /licenses diff --git a/docker-image/locust-tasks/requirements.txt b/docker-image/locust-tasks/requirements.txt index abc8f7c..00c869c 100644 --- a/docker-image/locust-tasks/requirements.txt +++ b/docker-image/locust-tasks/requirements.txt @@ -1,11 +1,18 @@ -Flask==0.12.3 -gevent==1.0.1 -greenlet==0.4.5 -itsdangerous==0.24 -Jinja2==2.7.3 -locustio==0.7.2 -MarkupSafe==0.23 -msgpack-python==0.4.6 -pyzmq==14.5.0 -requests==2.20.0 -Werkzeug==0.10.4 +certifi==2019.3.9 +chardet==3.0.4 +Click==7.0 +Flask==1.0.2 +gevent==1.4.0 +greenlet==0.4.15 +idna==2.8 +itsdangerous==1.1.0 +Jinja2==2.10 +locustio==0.11.0 +MarkupSafe==1.1.1 +msgpack==0.6.1 +msgpack-python==0.5.6 +pyzmq==18.0.1 +requests==2.21.0 +six==1.12.0 +urllib3==1.24.1 +Werkzeug==0.15.1 diff --git a/sample-webapp/app.py b/sample-webapp/app.py deleted file mode 100644 index 257b1da..0000000 --- a/sample-webapp/app.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2015 Google Inc. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -import webapp2 - - -class HomeHandler(webapp2.RequestHandler): - def get(self): - self.response.headers['Content-Type'] = 'text/plain' - self.response.write('Welcome to the "Distributed Load Testing Using Kubernetes" sample web app\n') - - -class LoginHandler(webapp2.RequestHandler): - def post(self): - deviceid = self.request.get('deviceid') - self.response.headers['Content-Type'] = 'text/plain' - self.response.write('/login - device: {}\n'.format(deviceid)) - - -class MetricsHandler(webapp2.RequestHandler): - def post(self): - deviceid = self.request.get('deviceid') - timestamp = self.request.get('timestamp') - - self.response.headers['Content-Type'] = 'text/plain' - self.response.write('/metrics - device: {}, timestamp: {}\n'.format(deviceid, timestamp)) - - -app = webapp2.WSGIApplication([ - (r'/', HomeHandler), - (r'/login', LoginHandler), - (r'/metrics', MetricsHandler), -]) diff --git a/sample-webapp/app.yaml b/sample-webapp/app.yaml index d4c090e..fd4770d 100644 --- a/sample-webapp/app.yaml +++ b/sample-webapp/app.yaml @@ -13,10 +13,10 @@ # limitations under the License. -runtime: python27 -api_version: 1 -threadsafe: true +runtime: python37 + +instance_class: F2 handlers: - url: /.* - script: app.app \ No newline at end of file + script: auto diff --git a/sample-webapp/main.py b/sample-webapp/main.py new file mode 100644 index 0000000..06bc573 --- /dev/null +++ b/sample-webapp/main.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +# Copyright 2019 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from flask import Flask, request + +app = Flask(__name__) + + +@app.route('/') +def root(): + return 'Welcome to the "Distributed Load Testing Using Kubernetes" sample web app\n' + +@app.route('/login', methods=['GET', 'POST']) +def login(): + deviceid = request.values.get('deviceid') + return '/login - device: {}\n'.format(deviceid) + +@app.route('/metrics', methods=['GET', 'POST']) +def metrics(): + deviceid = request.values.get('deviceid') + timestamp = request.values.get('timestamp') + + return '/metrics - device: {}, timestamp: {}\n'.format(deviceid, timestamp) + + +if __name__ == '__main__': + # This is used when running locally only. When deploying to Google App + # Engine, a webserver process such as Gunicorn will serve the app. This + # can be configured by adding an `entrypoint` to app.yaml. + # Flask's development server will automatically serve static files in + # the "static" directory. See: + # http://flask.pocoo.org/docs/1.0/quickstart/#static-files. Once deployed, + # App Engine itself will serve those files as configured in app.yaml. + app.run(host='127.0.0.1', port=8080, debug=True) diff --git a/sample-webapp/requirements.txt b/sample-webapp/requirements.txt new file mode 100644 index 0000000..90d10eb --- /dev/null +++ b/sample-webapp/requirements.txt @@ -0,0 +1 @@ +Flask>=1.0.2 From abe478fcc0d250f6f00c3255f3deacf1c3bb4427 Mon Sep 17 00:00:00 2001 From: Drew Stevens <43360753+googledrew@users.noreply.github.com> Date: Fri, 19 Apr 2019 13:14:39 -0700 Subject: [PATCH 09/13] security patches in dependencies CVE-2019-10906 - Jinja2 CVE-2019-11324 - urllib3 --- docker-image/locust-tasks/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-image/locust-tasks/requirements.txt b/docker-image/locust-tasks/requirements.txt index 00c869c..14c17cf 100644 --- a/docker-image/locust-tasks/requirements.txt +++ b/docker-image/locust-tasks/requirements.txt @@ -6,7 +6,7 @@ gevent==1.4.0 greenlet==0.4.15 idna==2.8 itsdangerous==1.1.0 -Jinja2==2.10 +Jinja2==2.10.1 locustio==0.11.0 MarkupSafe==1.1.1 msgpack==0.6.1 @@ -14,5 +14,5 @@ msgpack-python==0.5.6 pyzmq==18.0.1 requests==2.21.0 six==1.12.0 -urllib3==1.24.1 +urllib3==1.24.2 Werkzeug==0.15.1 From f919a6c85a30ccd55da157b7c86b64a060ac22c1 Mon Sep 17 00:00:00 2001 From: taisho6339 Date: Tue, 16 Jun 2020 09:35:06 +0900 Subject: [PATCH 10/13] upgrade deployment api version apps/v1 --- kubernetes-config/locust-master-controller.yaml | 2 +- kubernetes-config/locust-worker-controller.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes-config/locust-master-controller.yaml b/kubernetes-config/locust-master-controller.yaml index 63466f1..9e9322c 100644 --- a/kubernetes-config/locust-master-controller.yaml +++ b/kubernetes-config/locust-master-controller.yaml @@ -13,7 +13,7 @@ # limitations under the License. -apiVersion: "extensions/v1beta1" +apiVersion: "apps/v1" kind: "Deployment" metadata: name: locust-master diff --git a/kubernetes-config/locust-worker-controller.yaml b/kubernetes-config/locust-worker-controller.yaml index 7c1a682..a2d205f 100644 --- a/kubernetes-config/locust-worker-controller.yaml +++ b/kubernetes-config/locust-worker-controller.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -apiVersion: "extensions/v1beta1" +apiVersion: "apps/v1" kind: "Deployment" metadata: name: locust-worker From bb320238a5bee4931bb38a5d32eaecc35aca137c Mon Sep 17 00:00:00 2001 From: Drew Stevens <43360753+googledrew@users.noreply.github.com> Date: Tue, 19 Apr 2022 16:10:45 -0700 Subject: [PATCH 11/13] version updates, and locust example task refresh (#38) add script to start web application proxy instance add source code embed tags for docs updsate README, remove content and encourage readers to visit guide split server into ClusterIP and LoadBalancer for different ports --- README.md | 128 +----------------- docker-image/Dockerfile | 6 +- docker-image/locust-tasks/requirements.txt | 47 ++++--- docker-image/locust-tasks/run.sh | 6 +- docker-image/locust-tasks/tasks.py | 12 +- ...yaml => locust-master-controller.yaml.tpl} | 6 +- ...ce.yaml => locust-master-service.yaml.tpl} | 23 +++- ...yaml => locust-worker-controller.yaml.tpl} | 6 +- sample-webapp/.gcloudignore | 19 +++ sample-webapp/app.yaml | 4 +- sample-webapp/main.py | 6 +- scripts/start-proxy.sh | 32 +++++ 12 files changed, 127 insertions(+), 168 deletions(-) rename kubernetes-config/{locust-master-controller.yaml => locust-master-controller.yaml.tpl} (86%) rename kubernetes-config/{locust-master-service.yaml => locust-master-service.yaml.tpl} (78%) rename kubernetes-config/{locust-worker-controller.yaml => locust-worker-controller.yaml.tpl} (83%) create mode 100644 sample-webapp/.gcloudignore create mode 100755 scripts/start-proxy.sh diff --git a/README.md b/README.md index dd9fbd6..a85349f 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,6 @@ -## Distribute Load Testing Using GKE +## Distributed Load Testing Using GKE and Locust -## Introduction - -Load testing is key to the development of any backend infrastructure because load tests demonstrate how well the system functions when faced with real-world demands. An important aspect of load testing is the proper simulation of user and device behavior to identify and understand any possible system bottlenecks, well in advance of deploying applications to production. - -However, dedicated test infrastructure can be expensive and difficult to maintain because it is not needed on a continuous basis. Moreover, dedicated test infrastructure is often a one-time capital expense with a fixed capacity, which makes it difficult to scale load testing beyond the initial investment and can limit experimentation. This can lead to slowdowns in productivity for development teams and lead to applications that are not properly tested before production deployments. - -## Before you begin - -Open Cloud Shell to execute the commands listed in this tutorial. - -Define environment variables for the project id, region and zone you want to use for this tutorial. - - $ PROJECT=$(gcloud config get-value project) - $ REGION=us-central1 - $ ZONE=${REGION}-b - $ CLUSTER=gke-load-test - $ TARGET=${PROJECT}.appspot.com - $ gcloud config set compute/region $REGION - $ gcloud config set compute/zone $ZONE - -**Note:** Following services should be enabled in your project: -Cloud Build -Kubernetes Engine -Google App Engine Admin API -Cloud Storage - - $ gcloud services enable \ - cloudbuild.googleapis.com \ - compute.googleapis.com \ - container.googleapis.com \ - containeranalysis.googleapis.com \ - containerregistry.googleapis.com - -## Load testing tasks - -To deploy the load testing tasks, you first deploy a load testing master and then deploy a group of load testing workers. With these load testing workers, you can create a substantial amount of traffic for testing purposes. - -**Note:** Keep in mind that generating excessive amounts of traffic to external systems can resemble a denial-of-service attack. Be sure to review the Google Cloud Platform Terms of Service and the Google Cloud Platform Acceptable Use Policy. - -## Load testing master - -The first component of the deployment is the Locust master, which is the entry point for executing the load testing tasks described above. The Locust master is deployed with a single replica because we need only one master. - -The configuration for the master deployment specifies several elements, including the ports that need to be exposed by the container (`8089` for web interface, `5557` and `5558` for communicating with workers). This information is later used to configure the Locust workers. The following snippet contains the configuration for the ports: - - ports: - - name: loc-master-web - containerPort: 8089 - protocol: TCP - - name: loc-master-p1 - containerPort: 5557 - protocol: TCP - - name: loc-master-p2 - containerPort: 5558 - protocol: TCP - -Next, we would deploy a Service to ensure that the exposed ports are accessible to other pods via `hostname:port` within the cluster, and referenceable via a descriptive port name. The use of a service allows the Locust workers to easily discover and reliably communicate with the master, even if the master fails and is replaced with a new pod by the deployment. The Locust master service also includes a directive to create an external forwarding rule at the cluster level (i.e. type of LoadBalancer), which provides the ability for external traffic to access the cluster resources. - -After you deploy the Locust master, you can access the web interface using the public IP address of the external forwarding rule. After you deploy the Locust workers, you can start the simulation and look at aggregate statistics through the Locust web interface. - -## Load testing workers - -The next component of the deployment includes the Locust workers, which execute the load testing tasks described above. The Locust workers are deployed by a single deployment that creates multiple pods. The pods are spread out across the Kubernetes cluster. Each pod uses environment variables to control important configuration information such as the hostname of the system under test and the hostname of the Locust master. - -After the Locust workers are deployed, you can return to the Locust master web interface and see that the number of slaves corresponds to the number of deployed workers. - -## Setup - -1. Create GKE cluster - - $ gcloud container clusters create $CLUSTER \ - --zone $ZONE \ - --scopes "https://www.googleapis.com/auth/cloud-platform" \ - --num-nodes "3" \ - --enable-autoscaling --min-nodes "3" \ - --max-nodes "10" \ - --addons HorizontalPodAutoscaling,HttpLoadBalancing - - $ gcloud container clusters get-credentials $CLUSTER \ - --zone $ZONE \ - --project $PROJECT - -2. Clone tutorial repo in a local directory on your cloud shell environment - - $ git clone - -3. Build docker image and store it in your project's container registry - - $ pushd gke-load-test - $ gcloud builds submit --tag gcr.io/$PROJECT/locust-tasks:latest docker-image/. - -4. Deploy sample application on GAE - - $ gcloud app deploy sample-webapp/app.yaml --project=$PROJECT - -5. Replace [TARGET_HOST] and [PROJECT_ID] in locust-master-controller.yaml and locust-worker-controller.yaml with the deployed endpoint and project-id respectively. - - $ sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-master-controller.yaml - $ sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-worker-controller.yaml - $ sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-master-controller.yaml - $ sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-worker-controller.yaml - -6. Deploy Locust master and worker nodes: - - $ kubectl apply -f kubernetes-config/locust-master-controller.yaml - $ kubectl apply -f kubernetes-config/locust-master-service.yaml - $ kubectl apply -f kubernetes-config/locust-worker-controller.yaml - -7. Get the external ip of Locust master service - - $ EXTERNAL_IP=$(kubectl get svc locust-master -o yaml | grep ip | awk -F":" '{print $NF}') - -8. Starting load testing -The Locust master web interface enables you to execute the load testing tasks against the system under test, as shown in the following image. Access the url as http://$EXTERNAL_IP:8089. - -To begin, specify the total number of users to simulate and a rate at which each user should be spawned. Next, click Start swarming to begin the simulation. To stop the simulation, click **Stop** and the test will terminate. The complete results can be downloaded into a spreadsheet. - -9. [Optional] Scaling clients -Scaling up the number of simulated users will require an increase in the number of Locust worker pods. To increase the number of pods deployed by the deployment, Kubernetes offers the ability to resize deployments without redeploying them. For example, the following command scales the pool of Locust worker pods to 20: - - $ kubectl scale deployment/locust-worker --replicas=20 - -## Cleaning up - - $ gcloud container clusters delete $CLUSTER --zone $ZONE +This is the sample code for the [Distributed load testing using Google Kubernetes Engine](https://cloud.google.com/architecture/distributed-load-testing-using-gke) tutorial. ## License diff --git a/docker-image/Dockerfile b/docker-image/Dockerfile index 230756a..0f0ff2c 100644 --- a/docker-image/Dockerfile +++ b/docker-image/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ # limitations under the License. -# Start with a base Python 3.7.2 image -FROM python:3.7.2 +# Start with a base image Python 3.9.12 Debian 11 (bullseye) slim +FROM python:3.9.12-slim-bullseye # Add the licenses for third party software and libraries ADD licenses /licenses diff --git a/docker-image/locust-tasks/requirements.txt b/docker-image/locust-tasks/requirements.txt index 14c17cf..1fa8603 100644 --- a/docker-image/locust-tasks/requirements.txt +++ b/docker-image/locust-tasks/requirements.txt @@ -1,18 +1,31 @@ -certifi==2019.3.9 -chardet==3.0.4 -Click==7.0 -Flask==1.0.2 -gevent==1.4.0 -greenlet==0.4.15 -idna==2.8 -itsdangerous==1.1.0 -Jinja2==2.10.1 -locustio==0.11.0 -MarkupSafe==1.1.1 -msgpack==0.6.1 +Brotli==1.0.9 +certifi==2021.10.8 +chardet==4.0.0 +charset-normalizer==2.0.12 +click==8.1.2 +ConfigArgParse==1.5.3 +Flask==2.1.1 +Flask-BasicAuth==0.2.0 +Flask-Cors==3.0.10 +gevent==21.12.0 +geventhttpclient==1.5.3 +greenlet==1.1.2 +idna==3.3 +importlib-metadata==4.11.3 +itsdangerous==2.1.2 +Jinja2==3.0.3 +locust==2.8.6 +MarkupSafe==2.1.1 +msgpack==1.0.3 msgpack-python==0.5.6 -pyzmq==18.0.1 -requests==2.21.0 -six==1.12.0 -urllib3==1.24.2 -Werkzeug==0.15.1 +psutil==5.9.0 +pyzmq==22.3.0 +requests==2.27.1 +roundrobin==0.0.2 +six==1.16.0 +typing_extensions==4.1.1 +urllib3==1.26.9 +Werkzeug==2.1.1 +zipp==3.8.0 +zope.event==4.5.0 +zope.interface==5.4.0 diff --git a/docker-image/locust-tasks/run.sh b/docker-image/locust-tasks/run.sh index ba5f684..4f909ed 100644 --- a/docker-image/locust-tasks/run.sh +++ b/docker-image/locust-tasks/run.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,9 +22,9 @@ LOCUST_MODE=${LOCUST_MODE:-standalone} if [[ "$LOCUST_MODE" = "master" ]]; then LOCUS_OPTS="$LOCUS_OPTS --master" elif [[ "$LOCUST_MODE" = "worker" ]]; then - LOCUS_OPTS="$LOCUS_OPTS --slave --master-host=$LOCUST_MASTER" + LOCUS_OPTS="$LOCUS_OPTS --worker --master-host=$LOCUST_MASTER" fi echo "$LOCUST $LOCUS_OPTS" -$LOCUST $LOCUS_OPTS \ No newline at end of file +$LOCUST $LOCUS_OPTS diff --git a/docker-image/locust-tasks/tasks.py b/docker-image/locust-tasks/tasks.py index 6e6fc55..4e6d6ea 100644 --- a/docker-image/locust-tasks/tasks.py +++ b/docker-image/locust-tasks/tasks.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,9 +18,11 @@ import uuid from datetime import datetime -from locust import HttpLocust, TaskSet, task +from locust import FastHttpUser, TaskSet, task +# [START locust_test_task] + class MetricsTaskSet(TaskSet): _deviceid = None @@ -38,5 +40,7 @@ def post_metrics(self): "/metrics", {"deviceid": self._deviceid, "timestamp": datetime.now()}) -class MetricsLocust(HttpLocust): - task_set = MetricsTaskSet \ No newline at end of file +class MetricsLocust(FastHttpUser): + tasks = {MetricsTaskSet} + +# [END locust_test_task] diff --git a/kubernetes-config/locust-master-controller.yaml b/kubernetes-config/locust-master-controller.yaml.tpl similarity index 86% rename from kubernetes-config/locust-master-controller.yaml rename to kubernetes-config/locust-master-controller.yaml.tpl index 9e9322c..e5069b5 100644 --- a/kubernetes-config/locust-master-controller.yaml +++ b/kubernetes-config/locust-master-controller.yaml.tpl @@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,12 +31,12 @@ spec: spec: containers: - name: locust-master - image: gcr.io/[PROJECT_ID]/locust-tasks:latest + image: ${REGION}-docker.pkg.dev/${PROJECT}/${AR_REPO}/${LOCUST_IMAGE_NAME}:${LOCUST_IMAGE_TAG} env: - name: LOCUST_MODE value: master - name: TARGET_HOST - value: https://[TARGET_HOST] + value: https://${SAMPLE_APP_TARGET} ports: - name: loc-master-web containerPort: 8089 diff --git a/kubernetes-config/locust-master-service.yaml b/kubernetes-config/locust-master-service.yaml.tpl similarity index 78% rename from kubernetes-config/locust-master-service.yaml rename to kubernetes-config/locust-master-service.yaml.tpl index 3757115..6cca5fe 100644 --- a/kubernetes-config/locust-master-service.yaml +++ b/kubernetes-config/locust-master-service.yaml.tpl @@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,10 +21,6 @@ metadata: app: locust-master spec: ports: - - port: 8089 - targetPort: loc-master-web - protocol: TCP - name: loc-master-web - port: 5557 targetPort: loc-master-p1 protocol: TCP @@ -35,4 +31,21 @@ spec: name: loc-master-p2 selector: app: locust-master +--- +kind: Service +apiVersion: v1 +metadata: + name: locust-master-web + annotations: + networking.gke.io/load-balancer-type: "Internal" + labels: + app: locust-master +spec: + ports: + - port: 8089 + targetPort: loc-master-web + protocol: TCP + name: loc-master-web + selector: + app: locust-master type: LoadBalancer diff --git a/kubernetes-config/locust-worker-controller.yaml b/kubernetes-config/locust-worker-controller.yaml.tpl similarity index 83% rename from kubernetes-config/locust-worker-controller.yaml rename to kubernetes-config/locust-worker-controller.yaml.tpl index a2d205f..6583b38 100644 --- a/kubernetes-config/locust-worker-controller.yaml +++ b/kubernetes-config/locust-worker-controller.yaml.tpl @@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -30,11 +30,11 @@ spec: spec: containers: - name: locust-worker - image: gcr.io/[PROJECT_ID]/locust-tasks:latest + image: ${REGION}-docker.pkg.dev/${PROJECT}/${AR_REPO}/${LOCUST_IMAGE_NAME}:${LOCUST_IMAGE_TAG} env: - name: LOCUST_MODE value: worker - name: LOCUST_MASTER value: locust-master - name: TARGET_HOST - value: https://[TARGET_HOST] + value: https://${SAMPLE_APP_TARGET} diff --git a/sample-webapp/.gcloudignore b/sample-webapp/.gcloudignore new file mode 100644 index 0000000..a987f11 --- /dev/null +++ b/sample-webapp/.gcloudignore @@ -0,0 +1,19 @@ +# This file specifies files that are *not* uploaded to Google Cloud Platform +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +# Python pycache: +__pycache__/ +# Ignored by the build system +/setup.cfg \ No newline at end of file diff --git a/sample-webapp/app.yaml b/sample-webapp/app.yaml index fd4770d..b56981a 100644 --- a/sample-webapp/app.yaml +++ b/sample-webapp/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ # limitations under the License. -runtime: python37 +runtime: python39 instance_class: F2 diff --git a/sample-webapp/main.py b/sample-webapp/main.py index 06bc573..2040de7 100644 --- a/sample-webapp/main.py +++ b/sample-webapp/main.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# Copyright 2019 Google Inc. All rights reserved. +# Copyright 2022 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ def root(): return 'Welcome to the "Distributed Load Testing Using Kubernetes" sample web app\n' +# [START sample_app_endpoints] @app.route('/login', methods=['GET', 'POST']) def login(): deviceid = request.values.get('deviceid') @@ -33,8 +34,9 @@ def login(): def metrics(): deviceid = request.values.get('deviceid') timestamp = request.values.get('timestamp') - + return '/metrics - device: {}, timestamp: {}\n'.format(deviceid, timestamp) +# [END sample_app_endpoints] if __name__ == '__main__': diff --git a/scripts/start-proxy.sh b/scripts/start-proxy.sh new file mode 100755 index 0000000..8cc808f --- /dev/null +++ b/scripts/start-proxy.sh @@ -0,0 +1,32 @@ +# Copyright 2022 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +gcloud compute instances create-with-container ${PROXY_VM} \ + --zone ${ZONE} \ + --container-image gcr.io/cloud-marketplace/google/nginx1:latest \ + --container-mount-host-path=host-path=/tmp/server.conf,mount-path=/etc/nginx/conf.d/default.conf \ + --metadata=startup-script="#! /bin/bash + cat < /tmp/server.conf + server { + listen 8089; + location / { + proxy_pass http://${INTERNAL_LB_IP}:8089; + } + } +EOF" + +echo "To open an SSH tunnel between your workstation and this proxy instance, use this command:" +echo " gcloud compute ssh --zone ${ZONE} ${PROXY_VM} -- -N -L 8089:localhost:8089" From bcc426c40c48ca17f000eddd2e4dfdfd54574652 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 12 Nov 2024 09:58:34 +0100 Subject: [PATCH 12/13] Configure Renovate (#51) * Add renovate.json * Update renovate.json --------- Co-authored-by: Niel Markwick --- renovate.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..1e013d1 --- /dev/null +++ b/renovate.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended", + ":semanticCommits", + ":semanticCommitTypeAll(fix)", + ":enableVulnerabilityAlertsWithLabel(security)", + ], + rangeStrategy: "bump", +} From c857affebb99e93a8826831c5a0e5f970805a069 Mon Sep 17 00:00:00 2001 From: Niel Markwick Date: Tue, 12 Nov 2024 10:46:51 +0100 Subject: [PATCH 13/13] Update renovate.json --- renovate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index 1e013d1..b3c0703 100644 --- a/renovate.json +++ b/renovate.json @@ -6,5 +6,5 @@ ":semanticCommitTypeAll(fix)", ":enableVulnerabilityAlertsWithLabel(security)", ], - rangeStrategy: "bump", + "rangeStrategy": "bump", }