NGINX layer-7 load-balancing demo in AWS
Prerequisites
An AWS account
Creating an Amazon VPC(Virtual Private Cloud)
select VPC from AWS account, then click to 'create VPC'. Provide name-tag and IPV4 CIDR range.
Your VPC is created.
Attatched IGW(Internet GateWay) to the VPC
from VPC, select 'internet gateway', then click to 'Create internet gateway'.
Your IGW is created, now attatched it to the VPC (nginx-prod-vpc).
IGW is attatched to VPC.
Create Subnet
from VPC, select 'subnets', then click to 'Create subnet'.
Then create subnet in this VPC (nginx-prod-vpc), named it nginx-prod-subnet-01.
Now provide IPV4 CIDR range.
REMEMBER -
The CIDR block of a subnet can be the same as the CIDR block for the VPC (for a single subnet in the VPC), or a subset of the CIDR block for the VPC (for multiple subnets). The allowed block size is between a /28 netmask and /16 netmask. If you create more than one subnet in a VPC, the CIDR blocks of the subnets cannot overlap.
For example, if you create a VPC with CIDR block 10.0.0.0/24, it supports 256 IP addresses. You can break this CIDR block into two subnets, each supporting 128 IP addresses. One subnet uses CIDR block 10.0.0.0/25 (for addresses 10.0.0.0 - 10.0.0.127) and the other uses CIDR block 10.0.0.128/25 (for addresses 10.0.0.128 - 10.0.0.255).
Here the CIDR block for the VPC is 10.30.0.0/16 and the CIDR block for the Subnet is 10.30.2.0/24, which is a subset of the CIDR block for the VPC(10.30.0.0/16).
Create EC2(Elastic Compute Cloud) instance
from instance, select your instances, then click to Launch instances.
Step 1: Choose an Amazon Machine Image (AMI)
click the Select button for the Ubuntu Server of your choice.
Step 2: Choose an Instance Type
click the radio button for the appropriate instance type. Here I select t2.large
Step 3: Configure Instance Details
select the default subnet for your VPC in the Subnet field, then click the Next: Add Storage button
Step 4: Add Storage
leave the defaults unchanged. Click the Next: Add Tags button.
Step 5: Add Tags
click the Add Tag button. Type Name in the Key field, and in the Value field type the instance name (the screenshot shows the result).
Step 6: Configure Security Group
select or enter the following values in the indicated fields:
Assign a security group –
If you are setting up a deployment with multiple instances, and this is the first instance you are creating, select Create a new security group For subsequent instances, select Select an existing security group instead (it makes sense for all instances in a deployment to use the same security group).
Here I use a new security group. It would be better if I changed the name of the SG. I used the default one.
Step 7: Review Instance Launch
verify the settings are correct.
then, When you click the Launch button, a window pops up asking you to select an existing key pair or create a new key pair. Take the appropriate action for your use case, then click the Launch Instances button. If you lost the key pair, you lost the access to the VPC
nginx-ec2 is launched and running.
Create New EC2(Elastic Compute Cloud) instances
Want to create same ec2 instances, so, select the 'launch more like this' from the button 'launch instances'
create two ec2 instances like the previous one. Named- nginx-node1-ec2 and nginx-node2-ec2.
Deploy the project in ec2 instances (nginx-node1-ec2 and nginx-node2-ec2) project link: simple-express-api
Route Table
Now go to the subnet (nginx-prod-subnet-01) and manage the route table. You can see that, there is already a route exists, and it's destination is 10.30.0.0/16 and target is local. It means, in this range(10.30.0.0/16), traffic will travel locally.
Now add another route. If the IP is not in this range(10.30.0.0/16), then traffic will get out of the IGW(Internet Gate way) of the vpc. So, go to the route table and edit it.
Here you may notice, why Name tag is important. In your AWS portal, so many IGWs, VPCs, Subnets, EC2 instances. To find the required one, you need proper Name-tag. In this case, I need the IGW (nginx-prod-igw), which I created for the VPC (nginx-prod-vpc).
NGINX
At this point, you can have access to the VPC from your computer, if you have the key-pair, generated by AWS.
ssh -i nginx-key-pair.pem ubuntu@54.179.166.223
for ssh, you must have to allow ssh trafic in SG(Security Group).
then, edit the nginx.conf for my application, here it works as layer 7 load balancer
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
}
http {
upstream app {
server 10.30.2.121:8080;
server 10.30.2.196:8080;
}
server{
listen 80;
location /{
proxy_pass http://app/;
}
}
}
Initially my docker host port for the application is 8080, so, in SG(Security Group) allow the traffic for 8080 port.
Please notice, all three instances share same SG(Security Group). So, if you change in any one, all SG will change. I will separate those in future.
here I skip some steps, like, how to deploy the application in instances. As It is Ubuntu instance, so, the process is exactly like any ubuntu os. I will try to create another repo for this.
Docker run command for run the application. Run this command separately for 2 node instances (nginx-node1-ec2,nginx-node2-ec2) to run the application.
docker run -p 8080:3000 --name express_api -e APPID=2222 f98ab
now application is running
So, now, the nginx-node1-ec2 instance serve the application, you can go to the public IP, port 8080, and get the output. here you can see in below screenshot.
same for nginx-node2-ec2 instance
Now, I want to see the output through nginx-ec2 instance, as I am done with my nginx.conf, here nginx is listening to the port 80, so in SG, port 80 have to be open.
Now you can see, my application load-balancer is working.
Here comes the twist. I told you previously, all the instances share same SG, now it's time to separate those. Right now I want, only nginx server (nginx-ec2 instance) can have the access to the applications, but from outer world no one can access the 'nginx-node1-ec2' and 'nginx-node2-ec2'. and anyone can have access to the nginx-ec2 instance. I think you get my point. So, what I have to do, edit/create a new Security Group rules for the node instances, where only allows VPC traffic.