Network Load Balancer Target Groups
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed how to create a Network Load Balancer using AWS CLI.
https://cloudaffaire.com/how-to-create-a-network-load-balancer-using-aws-cli/
In this blog post, we will create a Network Load Balancer Target Groups.
Network Load Balancer Target Groups:
What are target groups:
Target group is used to route requests to one or more registered targets. When you create each listener rule, you specify a target group and conditions. When a rule condition is met, traffic is forwarded to the corresponding target group. You can create different target groups for different types of requests.
You define health check settings for your load balancer on a per target group basis. Each target group uses the default health check settings, unless you override them when you create the target group or modify them later on. After you specify a target group in a rule for a listener, the load balancer continually monitors the health of all targets registered with the target group that are in an Availability Zone enabled for the load balancer. The load balancer routes requests to the registered targets that are healthy.
Routing Configuration:
By default, a load balancer routes requests to its targets using the protocol and port number that you specified when you created the target group. Alternatively, you can override the port used for routing traffic to a target when you register it with the target group. Target groups for Network Load Balancers support the following protocols and ports:
- Protocols: TCP, TLS, UDP, TCP_UDP
- Ports: 1-65535
Target Type:
When you create a target group, you specify its target type, which determines how you specify its targets. After you create a target group, you cannot change its target type. The following are the possible target types:
- instance: The targets are specified by instance ID.
- ip: The targets are specified by IP address.
Note: Network Load Balancers do not support the lambda target type, only Application Load Balancers support the lambda target type.
Request Routing and IP Addresses:
If you specify targets using an instance ID, traffic is routed to instances using the primary private IP address specified in the primary network interface for the instance. The load balancer rewrites the destination IP address from the data packet before forwarding it to the target instance.
If you specify targets using IP addresses, you can route traffic to an instance using any private IP address from one or more network interfaces. This enables multiple applications on an instance to use the same port. Note that each network interface can have its own security group. The load balancer rewrites the destination IP address before forwarding it to the target.
Source IP Preservation:
If you specify targets using an instance ID, the source IP addresses of the clients are preserved and provided to your applications.
If you specify targets by IP address, the source IP addresses are the private IP addresses of the load balancer nodes. If you need the IP addresses of the clients, enable Proxy Protocol and get the client IP addresses from the Proxy Protocol header.
If you have micro services on instances registered with a Network Load Balancer, you cannot use the load balancer to provide communication between them unless the load balancer is internet-facing or the instances are registered by IP address.
Registered Targets:
Your load balancer serves as a single point of contact for clients and distributes incoming traffic across its healthy registered targets. Each target group must have at least one registered target in each Availability Zone that is enabled for the load balancer. You can register each target with one or more target groups. You can register each EC2 instance or IP address with the same target group multiple times using different ports, which enables the load balancer to route requests to microservices.
Deregistration Delay:
When you deregister an instance, the load balancer stops creating new connections to the instance. The load balancer uses connection draining to ensure that in-flight traffic completes on the existing connections. If the deregistered instance stays healthy and an existing connection is not idle, the load balancer can continue to send traffic to the instance. To ensure that existing connections are closed, you can ensure that the instance is unhealthy before you deregister it, or you can periodically close client connections.
The initial state of a deregistering target is draining. By default, the load balancer changes the state of a deregistering target to unused after 300 seconds. To change the amount of time that the load balancer waits before changing the state of a deregistering target to unused, update the deregistration delay value. We recommend that you specify a value of at least 120 seconds to ensure that requests are completed.
Proxy Protocol:
Network Load Balancers use Proxy Protocol version 2 to send additional connection information such as the source and destination. Proxy Protocol version 2 provides a binary encoding of the Proxy Protocol header. The load balancer prepends a proxy protocol header to the TCP data. It does not discard or overwrite any existing data, including any proxy protocol headers sent by the client or any other proxies, load balancers, or servers in the network path. Therefore, it is possible to receive more than one proxy protocol header. Also, if there is another network path to your targets outside of your Network Load Balancer, the first proxy protocol header might not be the one from your Network Load Balancer.
If you specify targets by IP address, the source IP addresses provided to your applications are the private IP addresses of the load balancer nodes. If your applications need the IP addresses of the clients, enable Proxy Protocol and get the client IP addresses from the Proxy Protocol header.
If you specify targets by instance ID, the source IP addresses provided to your applications are the client IP addresses. However, if you prefer, you can enable Proxy Protocol and get the client IP addresses from the Proxy Protocol header.
Network Load Balancer Target Group Demo:
Step 1: Create a custom VPC for your Network Load Balancer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
########################################## ## Network Load Balancer Targets Groups ## ########################################## ## Prerequisite: AWS CLI installed and configured with proper access ## https://cloudaffaire.com/category/aws/aws-cli/ ##---------------------------------- ## Create custom vpc for your nlb ## ##---------------------------------- ## Create a directory for this demo mkdir nlb_target_demo && cd nlb_target_demo ## Create a VPC AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text) ## Create two public subnets AWS_SUBNET_PUBLIC_ONE_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.1.0/24 \ --availability-zone ap-south-1a --query 'Subnet.{SubnetId:SubnetId}' \ --output text) && AWS_SUBNET_PUBLIC_TWO_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.2.0/24 \ --availability-zone ap-south-1b --query 'Subnet.{SubnetId:SubnetId}' \ --output text) ## Enable Auto-assign Public IP on Public Subnets aws ec2 modify-subnet-attribute \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --map-public-ip-on-launch && aws ec2 modify-subnet-attribute \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --map-public-ip-on-launch ## Create an Internet Gateway AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.{InternetGatewayId:InternetGatewayId}' \ --output text) && aws ec2 attach-internet-gateway \ --vpc-id $AWS_VPC_ID \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Create a route table AWS_CUSTOM_ROUTE_TABLE_ID=$(aws ec2 create-route-table \ --vpc-id $AWS_VPC_ID \ --query 'RouteTable.{RouteTableId:RouteTableId}' \ --output text ) ## Create route to Internet Gateway aws ec2 create-route \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id $AWS_INTERNET_GATEWAY_ID ## Associate the public subnet with route table AWS_ROUTE_TABLE_ASSOID_ONE=$(aws ec2 associate-route-table \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --query 'AssociationId' \ --output text) && AWS_ROUTE_TABLE_ASSOID_TWO=$(aws ec2 associate-route-table \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \ --query 'AssociationId' \ --output text) ## Create a security group aws ec2 create-security-group \ --vpc-id $AWS_VPC_ID \ --group-name myvpc-security-group \ --description 'My VPC non default security group' ## Get security group ID's AWS_DEFAULT_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `default`].GroupId' \ --output text) && AWS_CUSTOM_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \ --filters "Name=vpc-id,Values=$AWS_VPC_ID" \ --query 'SecurityGroups[?GroupName == `myvpc-security-group`].GroupId' \ --output text) ## Create security group ingress rules aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow SSH"}]}]' && aws ec2 authorize-security-group-ingress \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID \ --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 0, "ToPort": 65535, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Allow TCP"}]}]' |
Step 2: Create two EC2 instances for your Network Load Balancer Target.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
##---------------------------- ## Create two ec2 instances ## ##---------------------------- ## Get Amazon Linux 2 latest AMI ID AWS_AMI_ID=$(aws ec2 describe-images \ --owners 'amazon' \ --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????-x86_64-gp2' 'Name=state,Values=available' \ --query 'sort_by(Images, &CreationDate)[-1].[ImageId]' \ --output 'text') ## Create a key-pair aws ec2 create-key-pair \ --key-name myvpc-keypair \ --query 'KeyMaterial' \ --output text > myvpc-keypair.pem ## Change access to key pair to make it secure chmod 400 myvpc-keypair.pem ## Create user data to configure LAMP stack vi myuserdataone.txt ----------------------- #!/bin/bash sudo yum install -y httpd sudo systemctl start httpd sudo usermod -a -G apache ec2-user sudo chown -R ec2-user:apache /var/www sudo chmod 2775 /var/www sudo find /var/www -type d -exec chmod 2775 {} \; sudo find /var/www -type f -exec chmod 0664 {} \; sudo echo "hello from instance one" > /var/www/html/index.html ----------------------- :wq vi myuserdatatwo.txt ----------------------- #!/bin/bash sudo yum install -y httpd sudo systemctl start httpd sudo usermod -a -G apache ec2-user sudo chown -R ec2-user:apache /var/www sudo chmod 2775 /var/www sudo find /var/www -type d -exec chmod 2775 {} \; sudo find /var/www -type f -exec chmod 0664 {} \; sudo echo "hello from instance two" > /var/www/html/index.html ----------------------- :wq ## Create two EC2 instance in two public subnet AWS_EC2_INSTANCE_ONE_ID=$(aws ec2 run-instances \ --image-id $AWS_AMI_ID \ --instance-type t2.micro \ --key-name myvpc-keypair \ --monitoring "Enabled=false" \ --security-group-ids $AWS_CUSTOM_SECURITY_GROUP_ID \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID \ --user-data file://myuserdataone.txt \ --private-ip-address 10.0.1.10 \ --query 'Instances[0].InstanceId' \ --output text) ## Check if the instance one is running ## It will take some time for the instance to get ready aws ec2 describe-instance-status \ --instance-ids $AWS_EC2_INSTANCE_ONE_ID --output text AWS_EC2_INSTANCE_TWO_ID=$(aws ec2 run-instances \ --image-id $AWS_AMI_ID \ --instance-type t2.micro \ --key-name myvpc-keypair \ --monitoring "Enabled=false" \ --security-group-ids $AWS_CUSTOM_SECURITY_GROUP_ID \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID \ --user-data file://myuserdatatwo.txt \ --private-ip-address 10.0.2.10 \ --query 'Instances[0].InstanceId' \ --output text) ## Check if the instance two is running ## It will take some time for the instance to get ready aws ec2 describe-instance-status \ --instance-ids $AWS_EC2_INSTANCE_TWO_ID --output text |
Step 3: Create your Network Load Balancer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
##------------------------------------ ## Create Network load balancer ## ##------------------------------------ ## Create the Network load balancer AWS_NLB_ARN=$(aws elbv2 create-load-balancer \ --name my-network-load-balancer \ --subnets $AWS_SUBNET_PUBLIC_ONE_ID $AWS_SUBNET_PUBLIC_TWO_ID \ --type network \ --query 'LoadBalancers[0].LoadBalancerArn' \ --output text) ## Check the status of load balancer aws elbv2 describe-load-balancers \ --load-balancer-arns $AWS_NLB_ARN \ --query 'LoadBalancers[0].State.Code' \ --output text ## Once the nlb status is active, get the DNS name for your nlb AWS_NLB_DNS=$(aws elbv2 describe-load-balancers \ --load-balancer-arns $AWS_NLB_ARN \ --query 'LoadBalancers[0].DNSName' \ --output text) && echo $AWS_NLB_DNS |
Step 4: Create target group with instance as targets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
##---------------------- ## instance as target ## ##---------------------- ## Create the target group of instance type for your nlb AWS_NLB_TARGET_GROUP_INSTANCE_ARN=$(aws elbv2 create-target-group \ --name my-nlb-instance-targets \ --protocol TCP --port 80 \ --vpc-id $AWS_VPC_ID \ --target-type instance \ --query 'TargetGroups[0].TargetGroupArn' \ --output text) ## Register both the instances in the target group aws elbv2 register-targets --target-group-arn $AWS_NLB_TARGET_GROUP_INSTANCE_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID Id=$AWS_EC2_INSTANCE_TWO_ID ## Create a listener for your load balancer with a default rule that forwards requests to your target group AWS_NLB_LISTNER_INSTANCE_ARN=$(aws elbv2 create-listener --load-balancer-arn $AWS_NLB_ARN \ --protocol TCP --port 80 \ --default-actions Type=forward,TargetGroupArn=$AWS_NLB_TARGET_GROUP_INSTANCE_ARN \ --query 'Listeners[0].ListenerArn' \ --output text) ## Verify the health of the registered targets for your target group aws elbv2 describe-target-health --target-group-arn $AWS_NLB_TARGET_GROUP_INSTANCE_ARN ## Open the DNS name of your nlb (below output) in your browser and hit refresh several time ## Or curl your nlb DNS name repetedly echo $AWS_NLB_DNS curl $AWS_NLB_DNS |
Step 5: Create target group with IP as targets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
##---------------- ## ip as target ## ##---------------- ## Create the target group of ip type for your nlb AWS_NLB_TARGET_GROUP_IP_ARN=$(aws elbv2 create-target-group \ --name my-nlb-ip-targets \ --protocol TCP --port 80 \ --vpc-id $AWS_VPC_ID \ --target-type ip \ --query 'TargetGroups[0].TargetGroupArn' \ --output text) ## Register both the ip address in the target group aws elbv2 register-targets --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN \ --targets Id=10.0.1.10,Port=80,AvailabilityZone=ap-south-1a && aws elbv2 register-targets --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN \ --targets Id=10.0.2.10,Port=80,AvailabilityZone=ap-south-1b ## Modify the listener for your load balancer with a default rule that forwards requests to your target group aws elbv2 modify-listener --listener-arn $AWS_NLB_LISTNER_INSTANCE_ARN \ --default-actions Type=forward,TargetGroupArn=$AWS_NLB_TARGET_GROUP_IP_ARN ## Verify the health of the registered targets for your target group aws elbv2 describe-target-health --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN ## Open the DNS name of your nlb (below output) in your browser and hit refresh several time ## Or curl your nlb DNS name repetedly echo $AWS_NLB_DNS curl $AWS_NLB_DNS |
Step 6: Cleanup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
##----------- ## Cleanup ## ##----------- ## Delete the listener aws elbv2 delete-listener \ --listener-arn $AWS_NLB_LISTNER_INSTANCE_ARN ## Deregister targets aws elbv2 deregister-targets --target-group-arn $AWS_NLB_TARGET_GROUP_INSTANCE_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID Id=$AWS_EC2_INSTANCE_TWO_ID && aws elbv2 deregister-targets --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN \ --targets Id=10.0.1.10,Port=80,AvailabilityZone=ap-south-1a && aws elbv2 deregister-targets --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN \ --targets Id=10.0.2.10,Port=80,AvailabilityZone=ap-south-1b ## Delete all the target groups aws elbv2 delete-target-group \ --target-group-arn $AWS_NLB_TARGET_GROUP_INSTANCE_ARN && aws elbv2 delete-target-group \ --target-group-arn $AWS_NLB_TARGET_GROUP_IP_ARN ## Delete Network Load Balancer aws elbv2 delete-load-balancer \ --load-balancer-arn $AWS_NLB_ARN ## Terminate the ec2 instances aws ec2 terminate-instances \ --instance-ids $AWS_EC2_INSTANCE_ONE_ID && aws ec2 terminate-instances \ --instance-ids $AWS_EC2_INSTANCE_TWO_ID ## Delete key pair aws ec2 delete-key-pair \ --key-name myvpc-keypair ## Delete custom security group (once instances are terminated) aws ec2 delete-security-group \ --group-id $AWS_CUSTOM_SECURITY_GROUP_ID ## Delete internet gateway aws ec2 detach-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID \ --vpc-id $AWS_VPC_ID && aws ec2 delete-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID ## Disassociate the subnets from custom route table aws ec2 disassociate-route-table \ --association-id $AWS_ROUTE_TABLE_ASSOID_ONE && aws ec2 disassociate-route-table \ --association-id $AWS_ROUTE_TABLE_ASSOID_TWO ## Delete custom route table aws ec2 delete-route-table \ --route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID ## Delete the public subnets aws ec2 delete-subnet \ --subnet-id $AWS_SUBNET_PUBLIC_ONE_ID && aws ec2 delete-subnet \ --subnet-id $AWS_SUBNET_PUBLIC_TWO_ID ## Delete the vpc aws ec2 delete-vpc \ --vpc-id $AWS_VPC_ID ## Remove the directory cd .. && rm -rf nlb_target_demo |
Hope you have enjoyed this article, In the next blog post, we will discuss Health Checks in Network Load Balancer.
All the public cloud providers are changing the console user interface rapidly and due to this some of the screenshots used in our previous AWS blogs are no longer relevant. Hence, we have decided that from now onwards most of the demo will be done programmatically. Let us know your feedback on this in the comment section.
To get more details on AWS ELB, please refer below AWS documentation
https://docs.aws.amazon.com/elasticloadbalancing/index.html