Garden of KnowledgeApplied Sciences › Computer Science › Software › Security › Certifications › LFCS

q16-loadbalancer

Énoncé§

Solve this question on: web-srv1

Server web-srv1 is hosting two applications, one accessible on port 1111 and one on 2222. These are served using Nginx and it’s not allowed to change their config. The ip of web-srv1 is 192.168.10.60.

Create a new HTTP LoadBalancer on that server which:

Solution§

First we check if everything works as claimed:

curl web-srv1:1111
app1
curl web-srv1:2222
app2
curl web-srv1:2222/special
app2 special

Cool, we can work with that! Here we’re now going to create an Nginx LoadBalancer, but it would also be possible to use any other technology if you’re more familiar with it.

candidate@terminal:~$ ssh web-srv1
root@web-srv1:~$ cd /etc/nginx/sites-available
root@web-srv1:/etc/nginx/sites-available$ ls -lh
total 2.0K
-rw-r--r-- 1 root root 329 Jun 14 17:17 app1
-rw-r--r-- 1 root root 413 Jun 14 17:17 app2
root@web-srv1:/etc/nginx/sites-available$ cat app1
server {
        listen 1111 default_server;
        listen [::]:1111 default_server;
        server_name _;
        location / {
                return 200 'app1\n';
        }
}

There we see the two existing applications app1 and app2 which we aren’t allowed to be changed. But we sure can use one as template for our new LoadBalancer:

root@web-srv1:/etc/nginx/sites-available$ cp app1 lb
root@web-srv1:/etc/nginx/sites-available$ vim lb
server {
        listen 8001 default_server;                           # change port
        listen [::]:8001 default_server;                      # change port
        server_name _;
        location / {
                proxy_pass http://192.168.10.60:2222/special; # reverse proxy to the requested url
        }
}

We start slowly with the easier one on port 8001 where we simply use a proxy_pass option. Save the file and:

root@web-srv1:/etc/nginx/sites-available$ cd ../sites-enabled
root@web-srv1:/etc/nginx/sites-enabled$ ln -s ../sites-available/lb . # this is the nginx way for enabling
root@web-srv1:/etc/nginx/sites-enabled$ service nginx restart
root@web-srv1:/etc/nginx/sites-enabled$ curl localhost:8001           # our LB is reachable on port 8001
app2 special

Working! Now we go ahead and copy the first part, make some additions and use it as the second part:

root@web-srv1:/etc/nginx/sites-enabled$ vim lb
### FIRST PART
server {
        listen 8001 default_server;
        listen [::]:8001 default_server;
        server_name _;
        location / {
                proxy_pass http://192.168.10.60:2222/special; # reverse proxy to the requested url
        }
}
### SECOND PART
upstream backend {
        # when no load balancing method is specified, Round Robin is used
        server 192.168.10.60:1111; # app1
        server 192.168.10.60:2222; # app2
}
server {
        listen 8000 default_server;
        listen [::]:8000 default_server;
        server_name _;
        location / {
                proxy_pass http://backend; # reverse proxy to the requested url
        }
}

The second part is mostly the same as before. It’s possible to create multiple servers which listen on different ports within the same file. Here we simply created an upstream backend that contains the provided urls and we use it in the proxy_pass directive. Pretty nice right! But does it work?

root@web-srv1:/etc/nginx/sites-enabled$ service nginx restart
root@web-srv1:/etc/nginx/sites-enabled$ exit
curl web-srv1:8000
app1
curl web-srv1:8000
app2
curl web-srv1:8000
app1
curl web-srv1:8000
app2
curl web-srv1:8000
app1
curl web-srv1:8001
app2 special
curl web-srv1:8001
app2 special
curl web-srv1:8001/anything/even/not/special
app2 special

Above we see that requests to web-srv1:8000 are sent to both app1 and app2. And requests on web-srv1:8001 are only sent to app2 and path /special.

—The Gardener