Skip to content

nohan-budry/RES-HTTPInfra

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RES 2019 - Lab HTTP Infra

Authors: Nohan Budry, Andrés Moreno

This rapport contains the different stages of the lab HTTP infra executed during the webcast (Labo-HTTP).

Stage 1

During this first stage, we've created a new folder named docker-images that contains the whole structure of the lab. Inside this folder we've created another folder named apache-php-image. Inside this folder we can find everything that we need in order to build a docker image of an https server (created from a docker image php:7.2-apache) with static http content (the content is located at the "content" folder).

Inside docker-images/apache-php-image/content we've added a framework bootstrap, in order to add a template. The template added comes from START-BOOTSTRAP and goes by the name of "Greyscale". (This template is not the same as the webcast).

Stage 2

The objective of this stage was to write an http application in Node.js that returns a JSON payload on GET requests. We've added a new folder named express-dynamic inside docker-images that contains all the elements related to this stage (a Dockerfile in order to build our image and a src folder that contains the script). We added two modules with node packet manager (npm). The first one is chance. Chance is used to genereate aleatory names, numbers, etc. The second one is express which is a minimalist web framework for node. The code found at index.js is not the same as the webcast, instead of generating students we've decided to generate adventurers and send as payload their id, name, level, health, strength and their pet.

We created two endpoints to get data from:

  • /adventurers : returns a list of 10 random adventurers
  • /adventurers/{id} : returns the information of the adventurer with the given id (a positive integer).

Stage 3

The objective of this stage was to create a reverse proxy in order to have a unique entry point for the infrastucture. We've created a new folder named apache-reverse-proxy inside docker-images that contains a Dockerfile (in order to build an image) and config folder containing the reverse proxy configuration (contains the path to the different containers). Need to take into account that the ip adress needs to be the same as the docker containers from apache static and dynamic servers).

Stage 4

The objective of this stage was to use JQuery in order to make an AJAX request. We've added a custom script to index.html named adventurers.js located at docker-images/apache-php-images/content/js that loads the adventurer's name and level's into an element from the html page, this function is executed periodically each two seconds (we've modify the index.html file by adding an id to an h2 element in order to easily edit its content).

Stage 5

The objective of this stage was to remove the hard-coded IP adresses inside the reverse proxy configuration. In order to achive this, we've modified the Dockerfile form apache-reverse-proxy making it possible to run a php script that will wirte the configuration file of the server using a template. The script uses environement variables (STATIC_APP and DYNAMIC_APP) to configure the reverse-proxy.

Usage

At this point, it is possible to manually run one reverse proxy, one apache static app and one adventurers API.

Notes: The commands are executed at the root of the project folder. The names given to the images and containers are important and if you change them at one point you need to change them everywhere else.

First, let's create the images:

# Apache static image
docker build -t res/apache-static docker-images/apache-php-image/
# Express dynamic image
docker build -t res/adventurers-api docker-images/express-dynamic/
# Reverse proy image
docker build -t res/reverse-proxy docker-images/apache-reverse-proxy/

Then run one apache static and one adventurer API.

# Run apache static container (in background)
docker run -d --name apache-static res/apache-static
# Run adventurers api container (in background)
docker run -d --name adventurers-api res/adventurers-api

In order to run the reverse proxy, we need the know IP adresses assigned to the two container we just started. We can find them with the docker inspect command.

# Apache static IP adress
docker inspect apache-static | grep -i ipaddress
# Advenurers API IP adress
docker inspect adventurers-api | grep -i ipaddress

The output of each command should look like that.

Docker Inspect Result

In this case, the IP address of the apache-static container is "172.17.0.2". To run the reverse proxy we also. need to expose a port (the example use 8080 but you can chose whatever) and tell docker to set two environment variables.

  • STATIC_APP: Contains the IP of the apache-static container.
  • DYNAMIC_APP: Contains the IP of the adventurers-api container.

Here is the command:

docker run -d -p 8080:80 \
	-e STATIC_APP=172.17.0.2 -e DYNAMIC_APP=172.17.0.3 \
	--name reverse-proxy res/reverse-proxy

You need to change the two IP adresses to what you got with docker inspect.

In the default configuration of the proxy, only request with the host demo.res.ch are accepted. So we need to register it in our hosts list for our browsers to recognise it. For UNIX systems, modify the file "/etc/hosts" and add a line with "127.0.0.1 demo.res.ch". The IP adress corresponds to the one your docker daemon uses and may be different depending on your docker configuration (for example: "192.168.99.100" for a default docker-machine setup).

In your browser, you may now go to "http://demo.res.ch:8080" to see the apache static app or to "http://demo.res.ch:8080/api/adventurers" for the adventurers api.

Additional steps

The tree first additional steps proposed were accomplished using Traefik. Traefik is a dynamic reverse proxy / load balancer that we used to replace our simple reverse proxy. We have been able to easily use multiple containers of the apache static and the adventurers API apps with load balancing and sticky sessions. Because it is dynamic, it detects automatically when containers are started or stoped. Also, we use Docker- Compose to configure Traefik and scale the number of running containers (or services as called in docker compose). The last additional step was accomplish using Portainer.

Dynamic cluster managment

With traefik and Docker compose, we can easily setup a dynamic cluster. All we need is a "docker-compose.yml" file and comfigure it properly in order to start a Traefik container and other containers that Traefik will manage. In the compose.yml file for each services we need to add a set of labels so that Traefik knows what to do. For example, we can set the host or the port used for requests.

Traefik needs the ports 80 and 8080 to be exposed. The port 80 is used for any request to the setup services. The port 8080 is used to acces the Traefik dashboard where we have useful infomations like the running containers and their configuration.

Load balancing with round robin

When we run multiple services, Traefik uses a load balancing with a weighted round robin algorithm by default. To demonstrate the load balancing, we added a new endpoint to our API. A request to "/keeper", shows the imfomation of what we call the server keeper. In fact it is just an adventurer with its id corresponding to the container IP adress (with the dots removed, so 172.17.0.2 is 1721702). In other words, this endpoint always returns the same adventurer for each different server. When everything is running, you can go to "http://res.ch/api/keeper" and every time you refresh the page, an other keeper will be shown. And if you look carefully, you may see round robin in action.

Load balancing with sticky sessions

We enabled sticky sessions on the apache static app with two simple Traefik labels. One to enable it and the other to specify the name of the cookie that is used for the sticky session. This permits us to easily demonstrate sticky sessions by accessing the created cookie and use its value to know the IP address of the container we were affected to by Traefik. With the IP we can fetch a server keeper from the API (with the endpoint "/adventurer/{id}") with the same technique as before to calculate the adventurer's ID.

Management UI

To create a web app that allows to start and stop containers, we used Portainer. We configured it by adding it to the "docker-compose.yml" file. This lets us see running containers, stop them or duplicate existing ones.

Usage

Note: This command is executed at the root of the project folder.

With the additionnal steps, we can achieve a similar setup as before by only using one command.

docker-compose up -d --scale apache-static=3 --scale adventurers-api=3

This command start every services decribed by the "docker-compose.yml" file. The flag -d is for detached mode. --scale lets us chose how many containers for the specified service should run. You can edit the numbers as you like to have more or less of them.

You now have access to "http://res.ch/" for the apache static app, to "http://res.ch/api/" for the adventurers API, to "http://res.ch:8080/" for Treafik dashboard and to "http://portainer.res.ch/" for the Portainer dashboard. Remember to add those hosts in your system like we did with demo.res.ch after step 5.

If you access the apache static app, you can see that the server keeper doesn't change (cookies should be enabled) which mean the sticky sessions are working. You can also look at the cookie list to see "STICKY" with the container's UP as the value. If you delete it an other one will be create with the same container's IP or one of the others' IP.

If you go to "http://res.ch/api/keeper" you can see round robin in action.

About

RES 2019 - Lab HTTP Infra

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •