Photo by Kenny Eliason on Unsplash
How to distribute traffic load between docker container web servers using nginx load balancer.
Table of contents
I am using two AWS Instance server with different configuration. Details are:-First of all we will setup docker installation on server1 and run application with 2 docker containers.
Server Hostname | Private Ipv4 | Public IPv4 | Configuration |
dockerserver.example.com | 172.31.84.250 | 54.175.218.1 | T2.medium + 20 GB storage + 2 core cpu + 4 GB RAM |
loadserver.example.com | 172.31.32.25 | 54.175.228.52 | T2.Micro (Default) |
Note: I am using Mobaxterm for AWS instances remote access on Windows OS
On Docker-Server (54.175.218.1)
Step-1 (How to setup docker on server machine with Ubuntu OS )
we do follow official documentation for this: https://docs.docker.com/engine/install/ubuntu/
$ sudo for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
# Add Docker's official GPG key:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Step-2 (Manage Docker as a non-root user.)
# add a new user ram and give password to him
ubuntu@docker~$ sudo adduser ram
$ sudo vim /etc/sudoers.d/ram
ram ALL=(ALL) NOPASSWD: /usr/bin/docker #Give docker related authorized permission
$ sudo systemctl restart sshd
# run docker container with Non-Root user
$ sudo usermod -aG docker ram # Make ram as a secondary group member of docker group
$ su - ram
$ docker version
$ docker info
Step-3 (How to run nginx web application on docker containers)
First we do pull nginx image from repository server like dockerhub and run container with following configuration parameters like volume, restart policy, port, neme etc.
[admin@server1 ~]$ docker pull nginx # Pull docker nginx image
--------------------------------------------------------
# we need to add two 8080 & 8081 tcp port to firewall with admin users sudoers power
[admin@server1 ~]$ sudo firewall-cmd --add-port=8080/tcp --permanent
success
[admin@server1 ~]$ sudo firewall-cmd --add-port=8081/tcp --permanent
success
# Reload firewall-cmd
[admin@server1 ~]$ sudo firewall-cmd --reload
success
--------------------------------------------------------
# now switch to ram user and run nginx web containers
[admin@server1 ~]$ su - ram
ram@dockerserver:~$ docker run --name web-nginx1 -p 8081:80 --restart=always -v vol1:/usr/share/nginx/html -d nginx
6787f299798d6b6d47171e0995d0532ee8bdd352bba6407b561b4e6b7d4400b4
ram@dockerserver:~$ docker run --name web-nginx2 -p 8082:80 --restart=always -v vol1:/usr/share/nginx/html -d nginx
5bcf77f85e4a827579261f7251a7abce698f56f00a1e653fd59caeae677d4c90
ram@dockerserver:~$ ls /var/lib/docker/volumes/vol1/_data/
50x.html index.html
ram@dockerserver:~$ sudo echo "<h1> This is nginx web container1 </h1>" >> /var/lib/docker/volumes/vol1/_data/index.html
ram@dockerserver:~$ sudo ls /var/lib/docker/volumes/vol2/_data/
50x.html index.html
ram@dockerserver:~$ sudo echo "<h1> This is nginx web container2 </h1>" >> /var/lib/docker/volumes/vol2/_data/index.html
root@dockerserver:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81abf80b6307 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:8082->80/tcp, :::8082->80/tcp web-nginx2
83dec3eeac1c nginx "/docker-entrypoint.…" 10 minutes ago Up 10 minutes 0.0.0.0:8081->80/tcp, :::8081->80/tcp web-nginx1
ram@dockerserver:~& docker exec -it 81abf80b6307 bash
root@81abf80b6307:/# cat /usr/share/nginx/html/
50x.html index.html
root@81abf80b6307:/# cat /usr/share/nginx/html/index.html
<h1> This is nginx web container2 </h1>
root81abf80b6307:/# read escape sequence
ram@dockerserver:~# docker exec -it 83dec3eeac1c bash
root@83dec3eeac1c:/# cat /usr/share/nginx/html/index.html
<h1> This is nginx web container1 </h1>
Access web page using Docker server public ip address with 8081 and 8082 port number: Example:
http://54.175.218.1:8081
http://54.175.218.1:8082
On Load-Server (34.227.83.161)
Step-1 (How to configure nginx Load Balancer on "load-server" to distribute trrafic requests load between docker containers on "Docker-Server" )
$ sudo apt-get update
$ sudo apt-get install nginx
$ sudo systemctl restart nginx
$ sudo systemctl enable nginx
$ sudo vi /etc/nginx/conf.d/load.conf
upstream backend { # backend is a group name for below mentioned servers
server 54.175.218.1:8081; # Public IP of Docker-Server:port
server 54.175.218.1:8082;
}
server {
listen 80; # You may want to specify the appropriate port
server_name 54.175.228.52; # Load-Server public IP (nginx-load-balancer server running on)
location / {
proxy_pass http://backend;
}
}
$ nginx -t # to check nginx.conf configuration is correct or not
$ sudo systemctl restart nginx
Step-2 (Check nginx Load-Server to traffic distribution working or not)
Go to browser and paste : public-ip-of-load-server
http://54.175.228.52 and refresh the browser continusely to check
Reference:
Docker setup on ubuntu : https://docs.docker.com/engine/install/ubuntu/
Manage Docker as a Non-Root User: https://cloudyuga.guru/hands_on_lab/docker-as-non-root-user
Nginx Load Balancer Complete Documentation : https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/How-to-setup-an-Nginx-load-balancer-example