GithubHelp home page GithubHelp logo

giantthinkwell / tsung-docker Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ddragosd/tsung-docker

0.0 3.0 0.0 21 KB

Docker image to run Tsung distributed load testing tool

License: Apache License 2.0

Makefile 13.09% Shell 86.91%

tsung-docker's Introduction

tsung-docker

Docker image to run Tsung distributed load testing tool.

Usage

This Docker container is designed to execute Tsung in 3 modes: SINGLE, MASTER and SLAVE.

Single Mode

Use this single mode to test on the local box, with a single Tsung agent:

docker run \
   -v /local/tests:/usr/local/tsung ddragosd/tsung-docker:latest \
   -f /usr/local/tsung/mytest.xml \
   -r \"ssh -p 22\" start

In this mode you can use a single Tsung client <client host="localhost" cpu="1" use_controller_vm="true"> </client> Note the -r flag setting ssh port to 22. This is needed as the SSH runs on port 22 inside the docker container. In a MASTER / SLAVE scenarios, we'll have this port mapped to 21 as a convention.

Master Mode

This mode should be used on a local machine by mounting a folder containing the Tsung tests into the container, like in the following example:

docker run \
   -p 21:22 \
   -p 4369:4369 \
   -p 9001-9050:9001-9050 \
   -v /local/tests:/usr/local/tsung ddragosd/tsung-docker:latest \
   -f /usr/local/tsung/mytest.xml start

where /local/tests is a folder containing an XML file mytest.xml.

  • Note: Master Node has to be accessible from all the Slave nodes. Be aware of this when running behind a firewall.

Slave Mode

Use this mode in the distributed mode. All the agents that the MASTER Tsung needs to connect to must be started in this mode. By convention, the Agents run SSHD on port 21 b/c port 22 might be taken by the hosts running the docker service. For this reason, in order to avoid conflicts, the agents expose ssh on port 21. Erlang needs port 4369 open as its EPMD Port and all Slaves and Master nodes need to be able to use this port. Erlang also uses other ports for communication and this container exposes ports in the range 9001-9050.

To start a Docker container in the Slave mode issue the following command:

docker run \
   -p 21:22 \
   -p 4369:4369 \
   -p 9001-9050:9001-9050 \
   -e "SLAVE=true" \
   ddragosd/tsung-docker:latest

Running Tsung in a static environment

When you know the IPs of the nodes running Tsung you can manually expose them to docker through the --add-host parameter.

For the master node you can use:

docker run -d \
  -p 21:22 \
  -p 4369:4369 \
  -p 9001-9050:9001-9050 \
  --add-host tsung_slave1:10.132.35.108 \
  --add-host tsung_slave2:10.132.35.109 \
  --add-host target:10.132.35.110 \
  -h tsung_master \
  --name tsung \
  ddragosd/tsung-docker:latest -f /usr/local/tsung/tsung.xml start

And for the tsung-slave nodes:

docker run -d \
  -p 21:22 \
  -p 4369:4369 \
  -p 9001-9050:9001-9050 \  
  -e "SLAVE=true" \
  -h tsung_slave1 \
  --add-host tsung_master:10.132.35.107 \
  --add-host target:10.132.35.110 \
  --name tsung_slave \
  ddragosd/tsung-docker:latest

Running in Apache Mesos and Marathon

image

The main purpose of running a Docker container with Tsung is the ease of scale and Mesos with Marathon have great support for this. The containers need Marathon's base URL in order to auto-discover the nodes in the cluster; this is set in an environment variable : MARATHON_URL.

  • First step is to start the tsung-master node. It should be a single node. The configuration is almost identical to the Slaves with 2 differences: id and parameters.

It's recommended to also mount a volume from the host machine to /usr/local/tsung inside the container and place the tsung logs in there. You can then expose that data via a web-server such as nginx. The directory on the host must be specified as an absolute path and if the directory doesn't exist Docker should automatically create it for you.

Use Marathon API to make a POST to http://<marathon-url>/v2/apps

curl -X POST -H "Content-Type:application/json" ${MARATHON_HOST}/v2/apps?force=true --data '
{
  "id": "tsung-master",
  "container": {
    "type": "DOCKER",
     "volumes": [
         {
             "containerPath": "/usr/local/tsung",
             "hostPath": "/var/lib/log/tsung",
             "mode": "RW"
         }
     ],
    "docker": {
      "image": "ddragosd/tsung-docker:latest",
      "network": "BRIDGE",
      "portMappings": [
        { "containerPort": 22, "hostPort": 1025, "protocol": "tcp" },
        { "containerPort": 4369, "hostPort": 4369, "protocol": "tcp" },
        { "containerPort": 9001, "hostPort": 9001, "protocol": "tcp" },
        { "containerPort": 9002, "hostPort": 9002, "protocol": "tcp" },
        { "containerPort": 9003, "hostPort": 9003, "protocol": "tcp" },
        { "containerPort": 9004, "hostPort": 9004, "protocol": "tcp" },
        { "containerPort": 9005, "hostPort": 9005, "protocol": "tcp" },
        { "containerPort": 9006, "hostPort": 9006, "protocol": "tcp" },
        { "containerPort": 9007, "hostPort": 9007, "protocol": "tcp" },
        { "containerPort": 9008, "hostPort": 9008, "protocol": "tcp" },
        { "containerPort": 9009, "hostPort": 9009, "protocol": "tcp" },
        { "containerPort": 9010, "hostPort": 9010, "protocol": "tcp" },
        { "containerPort": 9011, "hostPort": 9011, "protocol": "tcp" },
        { "containerPort": 9012, "hostPort": 9012, "protocol": "tcp" },
        { "containerPort": 9013, "hostPort": 9013, "protocol": "tcp" },
        { "containerPort": 9014, "hostPort": 9014, "protocol": "tcp" },
        { "containerPort": 9015, "hostPort": 9015, "protocol": "tcp" },
        { "containerPort": 9016, "hostPort": 9016, "protocol": "tcp" },
        { "containerPort": 9017, "hostPort": 9017, "protocol": "tcp" },
        { "containerPort": 9018, "hostPort": 9018, "protocol": "tcp" },
        { "containerPort": 9019, "hostPort": 9019, "protocol": "tcp" },
        { "containerPort": 9020, "hostPort": 9020, "protocol": "tcp" },
        { "containerPort": 9021, "hostPort": 9021, "protocol": "tcp" },
        { "containerPort": 9022, "hostPort": 9022, "protocol": "tcp" },
        { "containerPort": 9023, "hostPort": 9023, "protocol": "tcp" },
        { "containerPort": 9024, "hostPort": 9024, "protocol": "tcp" },
        { "containerPort": 9025, "hostPort": 9025, "protocol": "tcp" },
        { "containerPort": 9026, "hostPort": 9026, "protocol": "tcp" },
        { "containerPort": 9027, "hostPort": 9027, "protocol": "tcp" },
        { "containerPort": 9028, "hostPort": 9028, "protocol": "tcp" },
        { "containerPort": 9029, "hostPort": 9029, "protocol": "tcp" },
        { "containerPort": 9030, "hostPort": 9030, "protocol": "tcp" },
        { "containerPort": 9031, "hostPort": 9031, "protocol": "tcp" },
        { "containerPort": 9032, "hostPort": 9032, "protocol": "tcp" },
        { "containerPort": 9033, "hostPort": 9033, "protocol": "tcp" },
        { "containerPort": 9034, "hostPort": 9034, "protocol": "tcp" },
        { "containerPort": 9035, "hostPort": 9035, "protocol": "tcp" },
        { "containerPort": 9036, "hostPort": 9036, "protocol": "tcp" },
        { "containerPort": 9037, "hostPort": 9037, "protocol": "tcp" },
        { "containerPort": 9038, "hostPort": 9038, "protocol": "tcp" },
        { "containerPort": 9039, "hostPort": 9039, "protocol": "tcp" },
        { "containerPort": 9040, "hostPort": 9040, "protocol": "tcp" },
        { "containerPort": 9041, "hostPort": 9041, "protocol": "tcp" },
        { "containerPort": 9042, "hostPort": 9042, "protocol": "tcp" },
        { "containerPort": 9043, "hostPort": 9043, "protocol": "tcp" },
        { "containerPort": 9044, "hostPort": 9044, "protocol": "tcp" },
        { "containerPort": 9045, "hostPort": 9045, "protocol": "tcp" },
        { "containerPort": 9046, "hostPort": 9046, "protocol": "tcp" },
        { "containerPort": 9047, "hostPort": 9047, "protocol": "tcp" },
        { "containerPort": 9048, "hostPort": 9048, "protocol": "tcp" },
        { "containerPort": 9049, "hostPort": 9049, "protocol": "tcp" },
        { "containerPort": 9050, "hostPort": 9050, "protocol": "tcp" }
     ],
      "parameters": [
          { "key": "hostname", "value": "tsung_master" }
      ]
    }
  },
  "cpus": 1,
  "mem": 512.0,
  "env": {
    "SLAVE": "true",
    "MARATHON_URL":"'${MARATHON_HOST}'"
  },
  "constraints": [ [ "hostname", "UNIQUE" ] ],
  "ports": [
    1025,
    4369,
    9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,
    9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,
    9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,
    9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,
    9041,9042,9043,9044,9045,9046,9047,9048,9049,9050
  ],
  "instances": 1
}'
  • Once the master is up and running you can start the slave nodes:
curl -X POST -H "Content-Type:application/json" ${MARATHON_HOST}/v2/apps?force=true --data '
{
  "id": "tsung-slaves",
  "container": {
    "type": "DOCKER",
    "docker": {
      "image": "ddragosd/tsung-docker:latest",
      "network": "BRIDGE",
      "portMappings": [
        { "containerPort": 22, "hostPort": 1025, "protocol": "tcp" },
        { "containerPort": 4369, "hostPort": 4369, "protocol": "tcp" },
        { "containerPort": 9001, "hostPort": 9001, "protocol": "tcp" },
        { "containerPort": 9002, "hostPort": 9002, "protocol": "tcp" },
        { "containerPort": 9003, "hostPort": 9003, "protocol": "tcp" },
        { "containerPort": 9004, "hostPort": 9004, "protocol": "tcp" },
        { "containerPort": 9005, "hostPort": 9005, "protocol": "tcp" },
        { "containerPort": 9006, "hostPort": 9006, "protocol": "tcp" },
        { "containerPort": 9007, "hostPort": 9007, "protocol": "tcp" },
        { "containerPort": 9008, "hostPort": 9008, "protocol": "tcp" },
        { "containerPort": 9009, "hostPort": 9009, "protocol": "tcp" },
        { "containerPort": 9010, "hostPort": 9010, "protocol": "tcp" },
        { "containerPort": 9011, "hostPort": 9011, "protocol": "tcp" },
        { "containerPort": 9012, "hostPort": 9012, "protocol": "tcp" },
        { "containerPort": 9013, "hostPort": 9013, "protocol": "tcp" },
        { "containerPort": 9014, "hostPort": 9014, "protocol": "tcp" },
        { "containerPort": 9015, "hostPort": 9015, "protocol": "tcp" },
        { "containerPort": 9016, "hostPort": 9016, "protocol": "tcp" },
        { "containerPort": 9017, "hostPort": 9017, "protocol": "tcp" },
        { "containerPort": 9018, "hostPort": 9018, "protocol": "tcp" },
        { "containerPort": 9019, "hostPort": 9019, "protocol": "tcp" },
        { "containerPort": 9020, "hostPort": 9020, "protocol": "tcp" },
        { "containerPort": 9021, "hostPort": 9021, "protocol": "tcp" },
        { "containerPort": 9022, "hostPort": 9022, "protocol": "tcp" },
        { "containerPort": 9023, "hostPort": 9023, "protocol": "tcp" },
        { "containerPort": 9024, "hostPort": 9024, "protocol": "tcp" },
        { "containerPort": 9025, "hostPort": 9025, "protocol": "tcp" },
        { "containerPort": 9026, "hostPort": 9026, "protocol": "tcp" },
        { "containerPort": 9027, "hostPort": 9027, "protocol": "tcp" },
        { "containerPort": 9028, "hostPort": 9028, "protocol": "tcp" },
        { "containerPort": 9029, "hostPort": 9029, "protocol": "tcp" },
        { "containerPort": 9030, "hostPort": 9030, "protocol": "tcp" },
        { "containerPort": 9031, "hostPort": 9031, "protocol": "tcp" },
        { "containerPort": 9032, "hostPort": 9032, "protocol": "tcp" },
        { "containerPort": 9033, "hostPort": 9033, "protocol": "tcp" },
        { "containerPort": 9034, "hostPort": 9034, "protocol": "tcp" },
        { "containerPort": 9035, "hostPort": 9035, "protocol": "tcp" },
        { "containerPort": 9036, "hostPort": 9036, "protocol": "tcp" },
        { "containerPort": 9037, "hostPort": 9037, "protocol": "tcp" },
        { "containerPort": 9038, "hostPort": 9038, "protocol": "tcp" },
        { "containerPort": 9039, "hostPort": 9039, "protocol": "tcp" },
        { "containerPort": 9040, "hostPort": 9040, "protocol": "tcp" },
        { "containerPort": 9041, "hostPort": 9041, "protocol": "tcp" },
        { "containerPort": 9042, "hostPort": 9042, "protocol": "tcp" },
        { "containerPort": 9043, "hostPort": 9043, "protocol": "tcp" },
        { "containerPort": 9044, "hostPort": 9044, "protocol": "tcp" },
        { "containerPort": 9045, "hostPort": 9045, "protocol": "tcp" },
        { "containerPort": 9046, "hostPort": 9046, "protocol": "tcp" },
        { "containerPort": 9047, "hostPort": 9047, "protocol": "tcp" },
        { "containerPort": 9048, "hostPort": 9048, "protocol": "tcp" },
        { "containerPort": 9049, "hostPort": 9049, "protocol": "tcp" },
        { "containerPort": 9050, "hostPort": 9050, "protocol": "tcp" }
      ]
    }
  },
  "cpus": 2,
  "mem": 2048.0,
  "env": {
    "SLAVE": "true",
    "MARATHON_URL":"'${MARATHON_HOST}'"
  },
  "constraints": [
    [
      "hostname",
      "UNIQUE"
    ]
  ],
  "ports": [
    1025,
    4369,
    9001,9002,9003,9004,9005,9006,9007,9008,9009,9010,
    9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,
    9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,
    9031,9032,9033,9034,9035,9036,9037,9038,9039,9040,
    9041,9042,9043,9044,9045,9046,9047,9048,9049,9050
  ],
  "instances": 2
}'

Exposing Tsung test results from Master via Nginx

Use Marathon API to make a POST to http://<marathon-url>/v2/apps Note: This container should run on the same host where tsung-master runs. You can use constraints to achieve that.

TSUNG_MASTER_HOST=$(curl -s ${MARATHON_HOST}/v2/tasks | grep tsung-master | grep 9050 | awk '{print $3}' | sed 's/\(\:[0-9].*\)//') \
&& curl -X POST -H "Content-Type:application/json" ${MARATHON_HOST}/v2/apps?force=true --data '
{
  "id": "tsung-nginx",
  "cmd": "sed -i s/\"htm;\"/\"htm; autoindex on;\"/g /etc/nginx/conf.d/default.conf && nginx -g \"daemon off;\"",
  "container": {
    "type": "DOCKER",
     "volumes": [
         {
             "containerPath": "/usr/share/nginx/html/tsung",
             "hostPath": "/var/lib/log/tsung",
             "mode": "RO"
         }
     ],
    "docker": {
      "image": "nginx",
      "network": "BRIDGE",
      "portMappings": [
        { "containerPort": 80, "hostPort": 0, "protocol": "tcp" }
      ]
    }
  },
  "cpus": 0.5,
  "mem": 512.0,
  "constraints": [["hostname", "CLUSTER", "'${TSUNG_MASTER_HOST}'"]],
  "ports": [
    0
  ],
  "instances": 1
}'

By default the nginx server does not index directories. To fix this the Nginx container updates the default conf on start:

sed -i s/"htm;"/"htm; autoindex on;"/g /etc/nginx/conf.d/default.conf

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.