Setting up a network load balancer with a backend service

This guide provides instructions for creating a basic Network Load Balancing deployment using a regional backend service. This example creates a network load balancer that supports either TCP or UDP traffic. If you want to create a network load balancer that load-balances TCP, UDP, ESP, GRE, ICMP, and ICMPv6 traffic (not just TCP or UDP), see Setting up a network load balancer for multiple IP protocols.

In this example, we'll use the load balancer to distribute TCP traffic across backend VMs in two zonal managed instance groups in the us-central1 region. An equally valid approach would be to use a single regional managed instance group for the us-central1 region.

Network load balancer with zonal instance groups
Network Load Balancing with zonal managed instance groups

This scenario distributes TCP traffic across healthy instances. To support this example, TCP health checks are configured to ensure that traffic is sent only to healthy instances. Note that TCP health checks are only supported with a backend service-based load balancer. Target pool-based load balancers can only use legacy HTTP health checks.

This example load balances TCP traffic, but you can use Network Load Balancing to load balance UDP, SSL, and HTTP(S) traffic.

The network load balancer is a regional load balancer. All load balancer components (backend VMs, backend service, and forwarding rule) must be in the same region.

Before you begin

Install the Google Cloud CLI. For a complete overview of the tool, see the gcloud CLI overview. You can find commands related to load balancing in the API and gcloud reference guide.

If you haven't run the Google Cloud CLI previously, first run gcloud init to authenticate.

This guide assumes that you are familiar with bash.

Set up the network and subnets

The example on this page uses a custom mode VPC network named lb-network. You can use an auto mode network if you only want to handle IPv4 traffic. However, IPv6 traffic requires a custom mode subnet.

IPv6 traffic also requires a dual-stack subnet (stack-type set to IPv4_IPv6). When you create a dual stack subnet on a custom mode VPC network, you choose an IPv6 access type for the subnet. For this example, we set the subnet's ipv6-access-type parameter to EXTERNAL. This means new VMs on this subnet can be assigned both external IPv4 addresses and external IPv6 addresses.

The backend instance group and the load balancer components used for this example are located in this region and subnet:

  • Region: us-central1
  • Subnet: lb-subnet, with primary IPv4 address range 10.1.2.0/24. Although you choose which IPv4 address range is configured on the subnet, the IPv6 address range is assigned automatically. Google provides a fixed size (/64) IPv6 CIDR block.

To create the example network and subnet, follow these steps.

Console

To support both IPv4 and IPv6 traffic, use the following steps:

  1. In the Google Cloud console, go to the VPC networks page.
    Go to VPC networks
  2. Click Create VPC network.
  3. Enter a Name of lb-network.
  4. In the Subnets section:
    • Set the Subnet creation mode to Custom.
    • In the New subnet section, configure the following fields:
      • Name: lb-subnet
      • Region: us-central1
      • IP stack type: IPv4 and IPv6 (dual-stack)
      • IPv4 range: 10.1.2.0/24
        Although you can configure an IPv4 range of addresses for the subnet, you cannot choose the range of the IPv6 addresses for the subnet. Google provides a fixed size (/64) IPv6 CIDR block.
      • IPv6 access type: External
      • Click Done.
  5. Click Create.

To support IPv4 traffic only, use the following steps:

  1. In the Google Cloud console, go to the VPC networks page.
    Go to VPC networks
  2. Click Create VPC network.
  3. Enter a Name of lb-network.
  4. In the Subnets section:
    • Set the Subnet creation mode to Custom.
    • In the New subnet section, configure the following fields:
      • Name: lb-subnet
      • Region: us-central1
      • IP stack type: IPv4 (single-stack)
      • IPv4 range: 10.1.2.0/24
      • Click Done.
  5. Click Create.

gcloud

  1. Create the custom mode VPC network:

    gcloud compute networks create lb-network \
        --subnet-mode=custom
    
  2. Within the lb-network network, create a subnet for backends in the us-central1 region.

    For both IPv4 and IPv6 traffic, use the following command:

    gcloud compute networks subnets create lb-subnet \
      --stack-type=IPV4_IPv6 \
      --ipv6-access-type=EXTERNAL \
      --network=lb-network \
      --range=10.1.2.0/24 \
      --region=us-central1
    

    For IPv4 traffic only, use the following command:

    gcloud compute networks subnets create lb-subnet \
      --network=lb-network \
      --range=10.1.2.0/24 \
      --region=us-central1
    

Create the zonal managed instance groups

For this load balancing scenario, you create two Compute Engine zonal managed instance groups and install an Apache web server on each instance.

To handle both IPv4 and IPv6 traffic, configure the backend VMs to be dual-stack. Set the VM's stack-type to IPv4_IPv6. The VMs also inherit the ipv6-access-type setting (in this example, EXTERNAL) from the subnet.

Instances that participate as backend VMs for network load balancers must be running the appropriate Linux Guest Environment, Windows Guest Environment, or other processes that provide equivalent functionality.

Setting up the instances

Cloud console

  1. Create an instance template. In the console, go to the Instance templates page.

    Go to Instance templates

    1. Click Create instance template.
    2. For Name, enter ig-us-template.
    3. Ensure that the Boot disk is set to a Debian image, such as Debian GNU/Linux 10 (buster). These instructions use commands that are only available on Debian, such as apt-get.
    4. Click Networking, disks, security, management, sole tenancy.
    5. Click Management and copy the following script into the Startup script field.

      #! /bin/bash
      sudo apt-get update
      sudo apt-get install apache2 -y
      sudo a2ensite default-ssl
      sudo a2enmod ssl
      sudo vm_hostname="$(curl -H "Metadata-Flavor:Google" \
      http://169.254.169.254/computeMetadata/v1/instance/name)"
      sudo echo "Page served from: $vm_hostname" | \
      tee /var/www/html/index.html
      sudo systemctl restart apache2
      
    6. Click Networking.

      1. For Network tags, enter lb-tag.
      2. For Network interfaces, click the default interface and configure the following fields:
        1. Network: lb-network
        2. Subnetwork: lb-subnet
    7. Click Create.

  2. Create a managed instance group. Go to the Instance groups page in the console.

    Go to Instance groups

    1. Click Create instance group.
    2. Select New managed instance group (stateless). For more information, see Stateless or stateful MIGs.
    3. For the Name, enter ig-us-1.
    4. Under Location, select Single zone.
    5. For the Region, select us-central1.
    6. For the Zone, select us-central1-a.
    7. Under Instance template, select ig-us-template.
    8. Specify the number of instances that you want to create in the group.

      For this example, specify the following options under Autoscaling:

      • For Autoscaling mode, select Off:do not autoscale.
      • For Maximum number of instances, enter 2.
    9. Click Create.

  3. Repeat the previous steps to create a second managed instance group in the us-central1-c zone with the following specifications:

    • Name: ig-us-2
    • Zone: us-central1-c
    • Instance template: Use the same ig-us-template template created in the previous section.

gcloud

The gcloud instructions in this guide assume that you are using Cloud Shell or another environment with bash installed.

  1. Create a VM instance template with HTTP server with the gcloud compute instance-templates create command.

    To handle both IPv4 and IPv6 traffic, use the following command.

    gcloud compute instance-templates create ig-us-template \
    --region=us-central1 \
    --network=lb-network \
    --subnet=lb-subnet \
    --ipv6-network-tier=PREMIUM \
    --stack-type=IPv4_IPv6 \
    --tags=lb-tag \
    --image-family=debian-10 \
    --image-project=debian-cloud \
    --metadata=startup-script='#! /bin/bash
    apt-get update
    apt-get install apache2 -y
    a2ensite default-ssl
    a2enmod ssl
    vm_hostname="$(curl -H "Metadata-Flavor:Google" \
    http://169.254.169.254/computeMetadata/v1/instance/name)"
    echo "Page served from: $vm_hostname" | \
    tee /var/www/html/index.html
    systemctl restart apache2'
    

    To handle IPv4 traffic only traffic, use the following command.

    gcloud compute instance-templates create ig-us-template \
    --region=us-central1 \
    --network=lb-network \
    --subnet=lb-subnet \
    --tags=lb-tag \
    --image-family=debian-10 \
    --image-project=debian-cloud \
    --metadata=startup-script='#! /bin/bash
    apt-get update
    apt-get install apache2 -y
    a2ensite default-ssl
    a2enmod ssl
    vm_hostname="$(curl -H "Metadata-Flavor:Google" \
    http://169.254.169.254/computeMetadata/v1/instance/name)"
    echo "Page served from: $vm_hostname" | \
    tee /var/www/html/index.html
    systemctl restart apache2'
    
  2. Create a managed instance group in the zone with the gcloud compute instance-groups managed create command.

    gcloud compute instance-groups managed create ig-us-1 \
        --zone us-central1-a \
        --size 2 \
        --template ig-us-template
    
  3. Create a second managed instance group in the us-central1-c zone:

    gcloud compute instance-groups managed create ig-us-2 \
        --zone us-central1-c \
        --size 2 \
        --template ig-us-template
    

Configuring firewall rules

Create firewall rules that allow external traffic (which includes health check probes) to reach the backend instances.

This example creates a firewall rule that allows TCP traffic from all source ranges to reach your backend instances on port 80. If you want to create separate firewall rules specifically for the health check probes, use the source IP address ranges documented in the Health checks overview: Probe IP ranges and firewall rules.

Console

  1. Go to the Firewalls page in the Google Cloud console.
    Go to the Firewalls page
  2. To allow IPv4 traffic, perform the following steps:
    1. Click Create firewall rule.
    2. Enter a Name of allow-network-lb-ipv4.
    3. Select the Network that the firewall rule applies to (lb-network).
    4. Under Targets, select Specified target tags.
    5. In the Target tags field, enter lb-tag.
    6. Under Source filter, select IPv4 ranges.
    7. Set the Source IPv4 ranges to 0.0.0.0/0. This allows IPv4 traffic from any source. This also allows Google's health check probes to reach the backend instances.
    8. Under Specified protocols and ports, click the checkbox next to tcp and enter 80.
    9. Click Create. It might take a moment for the console to display the new firewall rule, or you might have to click Refresh to see the rule.
  3. To allow IPv6 traffic, perform the following steps:
    1. Click Create firewall rule again.
    2. Enter a Name of allow-network-lb-ipv6.
    3. Select the Network that the firewall rule applies to (lb-network).
    4. Under Targets, select Specified target tags.
    5. In the Target tags field, enter lb-tag.
    6. Under Source filter, select IPv6 ranges.
    7. Set the Source IPv6 ranges to ::/0. This allows IPv6 traffic from any source. This also allows Google's health check probes to reach the backend instances.
    8. Under Specified protocols and ports, click the checkbox next to tcp and enter 80.
    9. Click Create. It might take a moment for the Console to display the new firewall rule, or you might have to click Refresh to see the rule.

gcloud

  1. To allow IPv4 traffic, run the following command:

    gcloud compute firewall-rules create allow-network-lb-ipv4 \
        --network=lb-network \
        --target-tags=lb-tag \
        --allow=tcp:80 \
        --source-ranges=0.0.0.0/0
    
  2. To allow IPv6 traffic, run the following command:

    gcloud compute firewall-rules create allow-network-lb-ipv6 \
      --network=lb-network \
      --target-tags=lb-tag \
      --allow=tcp:80 \
      --source-ranges=::/0
    

Configure the load balancer

Next, set up the load balancer.

When you configure the load balancer, your virtual machine instances will receive packets that are destined for the static external IP address you configure. If you are using an image provided by Compute Engine, your instances are automatically configured to handle this IP address. If you are using any other image, you must configure this address as an alias on eth0 or as a loopback on each instance.

Console

  1. Go to the Create a load balancer page in the Google Cloud console.
    Go to the Create a load balancer page
  2. Under TCP Load Balancing, click the Start configuration button.

  3. For Internet facing or internal only, select From Internet to my VMs.

  4. For Multiple regions or single region, select Single region only.

  5. For Backend type, select Backend Service.

  6. Click Continue.

Backend configuration

  1. On the New TCP load balancer screen, enter a Name of tcp-network-lb for the new load balancer. For the Region, select us-central1.
  2. Click Backend configuration. The load balancer Name you entered previously appears, but is not modifiable.
  3. On the Backend configuration screen, make the following changes:
    1. Under New Backend, select the IP stack type. If you created dual-stack backends to handle both IPv4 and IPv6 traffic, select IPv4 and IPv6 (dual-stack). To handle IPv4 traffic only, select IPv4(single-stack).
    2. Use the Instance group dropdown to select ig-us-1. Click Done. Click Add backend and repeat this step to add ig-us-2.
    3. Under Health check, choose Create a health check or Create another health check, enter the following information:
      • Name: tcp-health-check
      • Protocol: TCP
      • Port: 80
    4. Click Save.
  4. Verify that there is a blue check mark next to Backend configuration before continuing.

Frontend configuration

  1. Click Frontend configuration.
  2. For the Name, enter network-lb-forwarding-rule.
  3. To handle IPv4 traffic, use the following steps:
    1. For IP version, select IPv4.
    2. Under IP address, click the drop-down menu and select Create IP address.
      1. On the Reserve a new static IP address screen, assign a Name of network-lb-ip.
      2. Click Reserve.
    3. Under Ports, choose Single, and enter 80 for the Port number.
    4. Click Done.
  4. To handle IPv6 traffic, use the following steps:

    1. For IP version, select IPv6.
    2. For Subnetwork, select lb-subnet.
    3. The IPv6 range is auto-allocated from lb-subnet.
    4. Under Ports, choose Single, and enter 80 for the Port number.
    5. Click Done.

    A blue circle with a checkmark to the left of Frontend configuration indicates a successful set-up.

Review the configuration

  1. Click the Review and finalize button to check all of your configuration settings for the load balancer.
  2. If the settings are correct, click Create. It takes a few minutes for the load balancer to be created.

    On the load balancing screen, under the Backend column for your new load balancer, you should see a green checkmark showing that the new load balancer is healthy.

gcloud

  1. (For IPv4 traffic only) Create a static external IPv4 address for your load balancer.

    gcloud compute addresses create network-lb-ipv4 \
        --region us-central1
    

    The IPv6 forwarding rule uses an ephemeral IP address.

  2. Create a TCP health check.

    gcloud compute health-checks create tcp tcp-health-check \
        --region us-central1 \
        --port 80
    
  3. Create a backend service.

    gcloud compute backend-services create network-lb-backend-service \
        --protocol TCP \
        --health-checks tcp-health-check \
        --health-checks-region us-central1 \
        --region us-central1
    
  4. Add the instance groups to the backend service.

    gcloud compute backend-services add-backend network-lb-backend-service \
    --instance-group ig-us-1 \
    --instance-group-zone us-central1-a \
    --region us-central1
    
    gcloud compute backend-services add-backend network-lb-backend-service \
    --instance-group ig-us-2 \
    --instance-group-zone us-central1-c \
    --region us-central1
    
  5. Create the forwarding rules depending on whether you want to handle IPv4 traffic or IPv6 traffic. Create both forwarding rules to handle both types of traffic.

    1. For IPv4 traffic. Create a forwarding rule to route incoming TCP traffic to the backend service. Use the IPv4 address reserved in step 1 as the static external IP address of the load balancer.

      gcloud compute forwarding-rules create network-lb-forwarding-rule-ipv4 \
        --load-balancing-scheme EXTERNAL \
        --region us-central1 \
        --ports 80 \
        --address network-lb-ipv4 \
        --backend-service network-lb-backend-service
      
    2. For IPv6 traffic. Use the following command to create a forwarding rule with an ephemeral IPv6 address.

      gcloud compute forwarding-rules create network-lb-forwarding-rule-ipv6 \
          --load-balancing-scheme EXTERNAL \
          --region us-central1 \
          --subnet lb-subnet \
          --ip-version IPV6 \
          --ports 80 \
          --backend-service network-lb-backend-service
    

Test the load balancer

Now that the load balancing service is configured, you can start sending traffic to the load balancer's external IP address and watch traffic get distributed to the backend instances.

Look up the load balancer's external IP address

Console

  1. On the Advanced load balancing page, go to the Forwarding Rules tab.
    Go to the Forwarding Rules tab
  2. Locate the forwarding rule used by the load balancer.
  3. In the Address column, note the external IP address listed.

gcloud: IPv4

Enter the following command to view the external IPv4 address of the network-lb-forwarding-rule forwarding rule used by the load balancer.

gcloud compute forwarding-rules describe network-lb-forwarding-rule-ipv4 \
    --region us-central1

gcloud: IPv6

Enter the following command to view the external IPv6 address of the network-lb-forwarding-rule forwarding rule used by the load balancer.

gcloud compute forwarding-rules describe network-lb-forwarding-rule-ipv6 \
    --region us-central1

Send traffic to the load balancer

Make web requests to the load balancer using curl to contact its IP address.

  • From clients with IPv4 connectivity, run the following command:

    $ while true; do curl -m1 IPV4_ADDRESS; done
    
  • From clients with IPv6 connectivity, run the following command:

    $ while true; do curl -m1 http://IPV6_ADDRESS; done
    

    For example, if the assigned IPv6 address is [2001:db8:1:1:1:1:1:1/96]:80, the command should look like:

    $ while true; do curl -m1 http://[2001:db8:1:1:1:1:1:1]:80; done
    

Note the text returned by the curl command. The name of the backend VM generating the response is displayed in that text; for example: Page served from: VM_NAME

The response from the curl command alternates randomly among the backend instances. If your response is initially unsuccessful, you might need to wait approximately 30 seconds for the configuration to be fully loaded and for your instances to be marked healthy before trying again.

Additional configuration options

This section expands on the configuration example to provide instructions about how to further customize your network load balancer. These tasks are optional. You can perform them in any order.

Configure session affinity

The example configuration creates a backend service with session affinity disabled (value set to NONE). This section shows you how to update the backend service to change the load balancer's session affinity setting.

For supported session affinity types, see Session affinity options.

Console

  1. In the Google Cloud console, go to the Load balancing page.

    Go to Load balancing

  2. Click the name of the backend service, and then click Edit.

  3. On the Edit TCP load balancer page, click Backend configuration.

  4. Select an option from the Session affinity drop-down.

  5. Click Update.

gcloud

Use the following gcloud command to update session affinity for the backend service:

gcloud compute backend-services update BACKEND_SERVICE \
    --region=REGION \
    --session-affinity=SESSION_AFFINITY_OPTION

Replace the placeholders with valid values:

  • BACKEND_SERVICE: the backend service that you're updating
  • SESSION_AFFINITY_OPTION: the session affinity option that you want to set

    For the list of supported values for a network load balancer, see Session affinity options.

Configure a connection tracking policy

The example configuration creates a backend service with the default settings for its connection tracking policy. This section shows you how to update the backend service to change the load balancer's default connection tracking policy.

A connection tracking policy includes the following settings:

gcloud

Use the following gcloud compute backend-services command to update the connection tracking policy for the backend service:

gcloud compute backend-services update BACKEND_SERVICE \
    --region=REGION \
    --tracking-mode=TRACKING_MODE \
    --connection-persistence-on-unhealthy-backends=CONNECTION_PERSISTENCE_BEHAVIOR

Replace the placeholders with valid values:

  • BACKEND_SERVICE: the backend service that you're updating
  • TRACKING_MODE: the connection tracking mode to be used for incoming packets. For the list of supported values, see Tracking mode.
  • CONNECTION_PERSISTENCE_BEHAVIOR: the connection persistence behavior when backends are unhealthy. For the list of supported values, see Connection persistence on unhealthy backends.

Configure traffic steering

This section shows you how to update a load balancer's frontend configuration to set up source IP-based traffic steering. For details about how traffic steering works, see Traffic steering.

These instructions assume that you already have the parent base forwarding rule created. This example creates a second forwarding rule, which is the steering forwarding rule, with the same IP address, IP protocol, and ports as the parent. This steering forwarding rule is configured with source IP ranges so that you can customize how packets from those source IP ranges are forwarded.

gcloud

Use the following command to create a steering forwarding rule that points to a backend service:

gcloud beta compute backend-services create STEERING_FORWARDING_RULE_BS \
    --load-balancing-scheme=EXTERNAL \
    --backend-service=BACKEND_SERVICE \
    --address=LOAD_BALANCER_VIP \
    --ip-protocol=IP_PROTOCOL \
    --ports=PORTS \
    --region=REGION \
    --source-ip-ranges=SOURCE_IP_ADDRESS_RANGES

Use the following command to create a steering forwarding rule that points to a target instance:

gcloud beta compute backend-services create STEERING_FORWARDING_RULE_TI \
    --load-balancing-scheme=EXTERNAL \
    --target-instance=TARGET_INSTANCE \
    --address=LOAD_BALANCER_VIP \
    --ip-protocol=IP_PROTOCOL \
    --ports=PORTS \
    --region=REGION \
    --source-ip-ranges=SOURCE_IP_ADDRESS_RANGES

Replace the placeholders with valid values:

  • FORWARDING_RULE: the name of the steering forwarding rule that you're creating.
  • BACKEND_SERVICE or TARGET_INSTANCE: the name of the backend service or target instance to which this steering forwarding rule will send traffic. Even if the parent forwarding rule points to a backend service, you can create steering forwarding rules that point to target instances.
  • LOAD_BALANCER_VIP, IP_PROTOCOL, PORTS: the IP address, IP protocol, and ports, respectively, for the steering forwarding rule that you're creating. These settings should match a pre-existing base forwarding rule.
  • REGION: the region of the forwarding rule that you're creating.
  • SOURCE_IP_ADDRESS_RANGES: comma-separated list of IP addresses or IP address ranges. This forwarding rule will only forward traffic when the source IP address of the incoming packet falls into one of the IP ranges set here.

What's next