Network Load Balancer Target Group Health Checks
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed Target Groups in Network Load Balancer.
https://cloudaffaire.com/network-load-balancer-target-groups/
In this blog post, we will discuss Network Load Balancer Target Groups health checks.
Network Load Balancer Target Group Health Checks:
Network Load Balancers use active and passive health checks to determine whether a target is available to handle requests. By default, each load balancer node routes requests only to the healthy targets in its Availability Zone. If you enable cross-zone load balancing, each load balancer node routes requests to the healthy targets in all enabled Availability Zones.
With active health checks, the load balancer periodically sends a request to each registered target to check its status. Each load balancer node checks the health of each target, using the health check settings for the target group with which the target is registered. After each health check is completed, the load balancer node closes the connection that was established for the health check.
With passive health checks, the load balancer observes how targets respond to connections. Passive health checks enable the load balancer to detect an unhealthy target before it is reported as unhealthy by the active health checks. You cannot disable, configure, or monitor passive health checks. Passive health checks are not supported for UDP traffic.
If one or more target groups does not have a healthy target in an enabled Availability Zone, we remove the IP address for the corresponding subnet from DNS so that requests cannot be routed to targets in that Availability Zone. If there are no enabled Availability Zones with a healthy target in each target group, requests are routed to targets in all enabled Availability Zones.
Health Check Settings:
You configure active health checks for the targets in a target group using the following settings. If the health checks exceed UnhealthyThresholdCount consecutive failures, the load balancer takes the target out of service. When the health checks exceed HealthyThresholdCount consecutive successes, the load balancer puts the target back in service.
- HealthCheckProtocol: The protocol the load balancer uses when performing health checks on targets. The possible protocols are HTTP, HTTPS, and TCP. The default is the TCP protocol.
- HealthCheckPort: The port the load balancer uses when performing health checks on targets. The default is to use the port on which each target receives traffic from the load balancer.
- HealthCheckPath: [HTTP/HTTPS health checks] The ping path that is the destination on the targets for health checks. The default is /.
- HealthCheckTimeoutSeconds: The amount of time, in seconds, during which no response from a target means a failed health check. This value must be 6 seconds for HTTP health checks and 10 seconds for TCP and HTTPS health checks.
- HealthCheckIntervalSeconds: The approximate amount of time, in seconds, between health checks of an individual target. This value can be 10 seconds or 30 seconds. The default is 30 seconds.
- HealthyThresholdCount: The number of consecutive successful health checks required before considering an unhealthy target healthy. The range is 2 to 10. The default is 3.
- UnhealthyThresholdCount: The number of consecutive failed health checks required before considering a target unhealthy. This value must be the same as the healthy threshold count.
- Matcher: [HTTP/HTTPS health checks] The HTTP codes to use when checking for a successful response from a target. This value must be 200 to 399.
Important: Health checks for a Network Load Balancer are distributed and use a consensus mechanism to determine target health. Therefore, targets receive more than the configured number of health checks. To reduce the impact to your targets if you are using HTTP health checks, use a simpler destination on the targets, such as a static HTML file, or switch to TCP health checks.
Target Health Status:
Before the load balancer sends a health check request to a target, you must register it with a target group, specify its target group in a listener rule, and ensure that the Availability Zone of the target is enabled for the load balancer.
- initial: The load balancer is in the process of registering the target or performing the initial health checks on the target.
- healthy: The target is healthy.
- unhealthy: The target did not respond to a health check or failed the health check.
- unused: The target is not registered with a target group, the target group is not used in a listener rule for the load balancer, or the target is in an Availability Zone that is not enabled for the load balancer.
- draining: The target is deregistering and connection draining is in process.
Network Load Balancer Target Groups Health Check 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 Target Groups Health Checks ## ####################################################### ## 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_health_check_demo && cd nlb_health_check_demo ## Create a VPC with DNS hotsname enabled AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text) && aws ec2 modify-vpc-attribute \ --vpc-id $AWS_VPC_ID \ --enable-dns-hostnames "{\"Value\":true}" ## 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 and attach to the VPC 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 with route to Internet Gateway AWS_CUSTOM_ROUTE_TABLE_ID=$(aws ec2 create-route-table \ --vpc-id $AWS_VPC_ID \ --query 'RouteTable.{RouteTableId:RouteTableId}' \ --output text ) && 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' && 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 your nlb target group ## ##-------------------------------------------------- ## 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 25 26 27 28 29 30 31 32 33 34 35 36 |
##-------------------------------- ## 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 ## Create the target group for your NLB AWS_NLB_TARGET_GROUP_ARN=$(aws elbv2 create-target-group \ --name my-nlb-targets \ --protocol TCP --port 80 \ --vpc-id $AWS_VPC_ID \ --query 'TargetGroups[0].TargetGroupArn' \ --output text) ## View details of current health check configuration of target groups aws elbv2 describe-target-groups \ --target-group-arns $AWS_NLB_TARGET_GROUP_ARN |
Step 4: Network Load Balancer Target Group Health Checks.
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 |
##------------------------------ ## Target Group Health Checks ## ##------------------------------ ## Register both the instances in the target group aws elbv2 register-targets --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID Id=$AWS_EC2_INSTANCE_TWO_ID ## Verify the health of the registered targets for your target group (State = unused) aws elbv2 describe-target-health \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --query 'TargetHealthDescriptions[*].TargetHealth' \ --output table ## Create a listener for your load balancer with a default rule that forwards requests to your target group AWS_NLB_LISTNER_ARN=$(aws elbv2 create-listener --load-balancer-arn $AWS_NLB_ARN \ --protocol TCP --port 80 \ --default-actions Type=forward,TargetGroupArn=$AWS_NLB_TARGET_GROUP_ARN \ --query 'Listeners[0].ListenerArn' \ --output text) ## Verify the health of the registered targets for your target group ## Initially its (State = initial) and then (State = healthy) aws elbv2 describe-target-health \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --query 'TargetHealthDescriptions[*].TargetHealth' \ --output table ## Change the healthy and unhealthy threshold count aws elbv2 modify-target-group \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --healthy-threshold-count 2 \ --unhealthy-threshold-count 2 ## 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 ## Responce from both instance one and two ## login to the second instance and stop webserver aws ec2 describe-instances \ --instance-ids $AWS_EC2_INSTANCE_TWO_ID \ --query 'Reservations[0].Instances[0].PublicIpAddress' \ --output text ssh -i myvpc-keypair.pem ec2-user@13.235.48.139 #replace the ip with above output sudo systemctl stop httpd exit ## Verify the health of the registered targets for your target group (State = unhealthy) ## Wait for 30 seconds for the target to become unhealthy aws elbv2 describe-target-health \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --query 'TargetHealthDescriptions[*].TargetHealth' \ --output table ## 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 ## Responce from instance one only ## Deregister instance one from target group aws elbv2 deregister-targets --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --targets Id=$AWS_EC2_INSTANCE_ONE_ID ## Verify the health of the registered targets for your target group (State = draining) aws elbv2 describe-target-health \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --query 'TargetHealthDescriptions[*].TargetHealth' \ --output table ## 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 #Initially responce from instance one during connection draining #Then No responce form any of the instances, 502 Bad Gateway |
Step 5: 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 |
##----------- ## Cleanup ## ##----------- ## Delete the listener aws elbv2 delete-listener \ --listener-arn $AWS_NLB_LISTNER_ARN ## Deregister targets aws elbv2 deregister-targets \ --target-group-arn $AWS_NLB_TARGET_GROUP_ARN \ --targets Id=$AWS_EC2_INSTANCE_TWO_ID ## Delete target group aws elbv2 delete-target-group \ --target-group-arn $AWS_NLB_TARGET_GROUP_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 ## Delete the directory for this demo cd .. && rm -rf nlb_health_check_demo |
Hope you have enjoyed this article, In the next blog post, we will discuss how to create an internet-facing network load balancer with static elastic ip address.
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