Creating a TCP network load balancer


TCP network load balancers support SSL natively, making it possible to secure network traffic. Unlike SSL proxy load balancing and HTTP(S) load balancing, TCP network load balancing simply allows SSL traffic to pass through the load balancer and terminate at the VM itself.

For NLBs, there are four higher-level primary components involved: a target pool, a regional forwarding rule, health checks, and a regional IP address.

First, create a startup script named startup-script.sh to serve HTTP requests on port 80. This script will respond with the instance name and zone, allowing us to see which instance the response is being served from.

#!/bin/bash

meta_url='http://metadata.google.internal/computeMetadata/v1/instance/'
meta_header='Metadata-Flavor: Google'

instance_name=$(curl -H "$meta_header" "$meta_url/name")
instance_zone=$(curl -H "$meta_header" "$meta_url/zone" | awk -F/ '{print $NF}')

mkdir $HOME/simple-server
cd $HOME/simple-server

cat >index.html <<EOL
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <h3>Hello from Google Compute Engine!</h3>
    Instance: ${instance_name}
    <br/>
    Zone: ${instance_zone}
</body>
EOL

busybox httpd -f -p 80

Next, create a new instance template, referencing the startup script. This instance template assumes that the default-allow-http firewall rule exists to enable TCP traffic on port 80 to all instances tagged with http-server:

gcloud compute instance-templates create simple-http-server-v1 \
    --machine-type f1-micro \
    --region us-east1 \
    --tags http-server \
    --metadata-from-file startup-script=./startup-script.sh

Next, create two Compute Engine instances using the template, one in us-east1-b and one in us-east1-c:

gcloud compute instances create simple-http-server-1 \
    --source-instance-template simple-http-server-v1 \
    --zone us-east1-b

gcloud compute instances create simple-http-server-2 \
    --source-instance-template simple-http-server-v1 \
    --zone us-east1-c

Create an HTTP health check named simple-http-get. Because we didn’t specify any optional arguments, the health check will use default behavior, polling each instance on port 80 at the root path (/). This health check will be performed every 5 seconds, marking an instance unhealthy when it fails two consecutive checks, and healthy when it passes two consecutive checks:

gcloud compute http-health-checks create simple-http-get

Next, create a new target pool named us-east-tcp-unmanaged in the same region as the instances. Specify that the target pool should use the simple-http-get health check:

gcloud compute target-pools create us-east-tcp-unmanaged \
    --region us-east1 \
    --http-health-check simple-http-get

With the target pool created, add the two Compute Engine instances to the pool:

gcloud compute target-pools add-instances us-east-tcp-unmanaged \
    --region us-east1 \
    --instances simple-http-server-1 \
    --instances-zone us-east1-b \

gcloud compute target-pools add-instances us-east-tcp-unmanaged \
    --region us-east1 \
    --instances simple-http-server-2 \
    --instances-zone us-east1-c

Next, create a static regional IP address named us-east-tcp-ip to be used by the load balancer:

gcloud compute addresses create us-east-tcp-ip \
   --region us-east1

Lastly, create a regional forwarding rule to listen on the us-east-tcp-ip address and forward requests to the us-east-tcp-unmanaged target pool:

gcloud compute forwarding-rules create us-east1-tcp-http \
    --region us-east1 \
    --target-pool us-east-tcp-unmanaged \
    --target-pool-region us-east1 \
    --ports 80 \
    --address us-east-tcp-ip \
    --address-region us-east1

Should an instance become unhealthy, the load balancer will stop routing requests to it. This can be seen by stopping the HTTP server process running on the simple-http-server-1 instance:

gcloud compute ssh simple-http-server-1 \
    --zone us-east1-b \
    -- sudo pkill -f 'busybox\ httpd'