Set up a cross-region internal Application Load Balancer with Cloud Run Stay organized with collections Save and categorize content based on your preferences.
This document shows you how to deploy a cross-region internal Application Load Balancer withCloud Run. To set this up, you use aserverless NEG backend for the load balancer.
Although this document describes a Cloud Run configuration, aserverless NEG for Cloud Run can point to either aCloud Run resource or a Cloud Run functions (2nd gen) resource.
Serverless NEGs let you useCloud Run services with your load balancer. After you configurea load balancer with the serverless NEG backend, requests to the load balancerare routed to the Cloud Run backend.
Cross-regional load balancing provides redundancy, so that if a region isunreachable, traffic is automatically diverted to another region.Based on the location of the Envoy, proxy traffic is distributed toCloud Run services as follows:
- If multi-region Cloud Run services are configured in the sameregion as the Envoy, the NEG that is located in the same region as the Envoyis preferred. Traffic is sent to the failover region only if outlierdetection is enabled and the local NEG is unhealthy.
- If multi-region Cloud Run services are not configured in thesame region as the Envoy, traffic is distributed evenly acrossall NEGs. The NEGs located closer are not preferred.
- IfIdentity-Aware Proxy is enabled, only a singleserverless NEG is supported. You can, however, configure additionalCloud Run services but the load balancer does not send anytraffic to them.
Before you begin
Before following this guide, familiarize yourself with the following:
- Internal Application Load Balancer overview,including theLimitationssection
- VPC firewall rules
- Serverless network endpoint groups overview
Deploy a Cloud Run service
The instructions on this page assume you already have aCloud Run service running.
For the example on this page, you can useany of theCloud Run quickstarts to deploy aCloud Run service.
To prevent access to the Cloud Run service from theinternet,restrict ingress tointernal. Trafficfrom the internal Application Load Balancer is consideredinternal traffic.
Placing the Cloud Run service in multiple regions helpsprevent failures in a single region. To deploy theCloud Run service inREGION_A andREGION_B regions, run the following commands:
gcloud
gcloud run deployCLOUD_RUN_SERVICE_NAMEA \ --platform=managed \ --allow-unauthenticated \ --ingress=internal \ --region=REGION_A \ --image=IMAGE_URLA
gcloud run deployCLOUD_RUN_SERVICE_NAMEB \ --platform=managed \ --allow-unauthenticated \ --ingress=internal \ --region=REGION_B \ --image=IMAGE_URLB
Note the name of the service that you create. The rest of this page shows youhow to set up a load balancer that routes requests to this service.
Set up an SSL certificate resource
Create a Certificate Manager SSL certificate resource as follows:
- Deploy a global self-managed certificate
- Create a Google-managed certificate issued by your Certificate Authority Service instance
- Create a Google-managed certificate with DNS authorization
We recommend using a Google-managed certificate.
Permissions
To follow this guide, you must be able to create instances and modify anetwork in a project. You must be either a projectowner or editor, or you must have all ofthe followingCompute Engine IAM roles.
| Task | Required role |
|---|---|
| Create networks, subnets, and load balancer components | Compute Network Admin |
| Add and remove firewall rules | Compute Security Admin |
| Create instances | Compute Instance Admin |
For more information, see the following guides:
Setup overview
You can configure the cross-region internal Application Load Balancer as described in the following diagram:
As shown in the diagram, this example creates a cross-region internal Application Load Balancer in aVPC network, with one backendservice and two Cloud Run deployments inREGION_A andREGION_B regions.
The cross-region internal Application Load Balancer setup is described as follows:
A VPC network with the following subnets:
- Subnet
SUBNET_Aand a proxy-only subnet inREGION_A. - Subnet
SUBNET_Band a proxy-only subnet inREGION_B.
You must createproxy-only subnetsin each region of a VPC network where you usecross-region internal Application Load Balancers. The region'sproxy-only subnet is shared among all cross-region internal Application Load Balancers inthe region. Source addresses of packets sent from the load balancerto your service's backends are allocated from theproxy-only subnet.In this example, the proxy-only subnet for the region
REGION_Ahas a primary IP addressrange of10.129.0.0/23and forREGION_Bhas a primary IP address range of10.130.0.0/23which is therecommended subnet size.- Subnet
A firewall rule that permits proxy-only subnet traffic flows in yournetwork. This means adding one rule that allows TCP port
80,443, and8080traffic from10.129.0.0/23and10.130.0.0/23(the range of theproxy-only subnets in this example).Another firewall rule for thehealthcheck probes.
A high availability setup that has serverless backends forCloud Run deployments in
REGION_AandREGION_Bregions. If the backends in one region happen to be down, traffic fails overto the other region.A global backend service that monitors the usage and health ofbackends. Ensure that youenable outlier detection onthe backend service.
A global URL map that parses the URL of a request and forwardsrequests to specific backend services based on the host and path of therequest URL.
A global target HTTP or HTTPS proxy, which receives a request from theuser and forwards it to the URL map. For HTTPS, configure a regional SSLcertificate resource. The target proxy uses the SSL certificate to decrypt SSLtraffic if you configure HTTPS load balancing. The target proxy can forwardtraffic to your instances by using HTTP or HTTPS.
Global forwarding rules, which have the internal IP address of your loadbalancer, to forward each incoming request to the target proxy.
The internal IP address associated with the forwarding rule can come fromany subnet in the same network and region. Note the following conditions:
- The IP address can (but does not need to) come from the same subnet asthe backend instance groups.
- The IP address must not come from a reserved proxy-only subnet that hasits
--purposeflag set toGLOBAL_MANAGED_PROXY. - If you want touse the same internal IP address with multiple forwardingrules, set the IP address
--purposeflag toSHARED_LOADBALANCER_VIP.
Optional:Configure DNS routing policiesof type
GEOto route client traffic to the load balancer VIP inthe region closest to the client.
Configure the network and subnets
Within the VPC network, configure a subnet in each regionwhere your backends are configured. In addition, configure aproxy-only-subnetin each region in which you want to configure the load balancer.
This example uses the following VPC network, region, andsubnets:
Network. The network is acustom mode VPCnetwork named
NETWORK.Subnets for backends. A subnet named
SUBNET_Ain theREGION_Aregion uses10.1.2.0/24for its primaryIP range. Subnet namedSUBNET_Bin theREGION_Bregion uses10.1.3.0/24for its primaryIP range.Subnet for proxies. A subnet named
PROXY_SN_Ain theREGION_Aregion uses10.129.0.0/23for its primaryIP range. A subnet namedPROXY_SN_Bin theREGION_Bregion uses10.130.0.0/23for its primaryIP range.
Cross-region internal Application Load Balancers can be accessed from any region within the VPC.So clients from any region can globally access your load balancer backends.
Note: Subsequent steps in this guide use the network, region,and subnet parameters as outlined here.Configure the backend subnets
Console
In the Google Cloud console, go to theVPC networks page.
ClickCreate VPC network.
Provide aName for the network.
In theSubnets section, set theSubnet creation mode toCustom.
Create a subnet for the load balancer's backends. In theNew subnetsection, enter the following information:
- Provide aName for the subnet.
- Select aRegion:REGION_A
- Enter anIP address range:
10.1.2.0/24
ClickDone.
ClickAdd subnet.
Create a subnet for the load balancer's backends. In theNewsubnet section, enter the following information:
- Provide aName for the subnet.
- Select aRegion:REGION_B
- Enter anIP address range:
10.1.3.0/24
ClickDone.
ClickCreate.
gcloud
Create the custom VPC network with the
gcloud computenetworks createcommand:gcloud compute networks createNETWORK --subnet-mode=custom
Create a subnet in the
NETWORKnetwork in theREGION_Aregion withthegcloud compute networks subnets createcommand:gcloud compute networks subnets createSUBNET_A \ --network=NETWORK \ --range=10.1.2.0/24 \ --region=REGION_A
Create a subnet in the
NETWORKnetwork in theREGION_Bregion withthegcloud compute networks subnets createcommand:gcloud compute networks subnets createSUBNET_B \ --network=NETWORK \ --range=10.1.3.0/24 \ --region=REGION_B
API
Make aPOST request to thenetworks.insert method.ReplacePROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks{ "routingConfig": { "routingMode": "regional" }, "name": "NETWORK", "autoCreateSubnetworks": false}Make aPOST request to thesubnetworks.insert method.ReplacePROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/subnetworks{ "name": "SUBNET_A", "network": "projects/PROJECT_ID/global/networks/NETWORK", "ipCidrRange": "10.1.2.0/24", "region": "projects/PROJECT_ID/regions/REGION_A",}Make aPOST request to thesubnetworks.insert method.ReplacePROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/subnetworks{ "name": "SUBNET_B", "network": "projects/PROJECT_ID/global/networks/NETWORK", "ipCidrRange": "10.1.3.0/24", "region": "projects/PROJECT_ID/regions/REGION_B",}Configure the proxy-only subnet
Aproxy-only subnet provides aset of IP addresses that Google Cloud uses to run Envoy proxies on your behalf.The proxies end connections from the client and create connections to thebackends.
This proxy-only subnet is used by all Envoy-based regional loadbalancers in the same region as the VPC network. There can only beone active proxy-only subnet for a given purpose, per region, per network.
Important: Don't try to assign addresses from the proxy-only subnet to your loadbalancer's forwarding rule or backends. You assign the forwarding rule's IPaddress and the backend instance IP addresses froma different subnet range (or ranges), not this one.Google Cloud reserves this subnet range for Google Cloud-managedproxies.Console
If you're using the Google Cloud console, you can wait and create the proxy-only subnet later on theLoad balancing page.
If you want to create the proxy-only subnet now, use the following steps:
In the Google Cloud console, go to theVPC networks page.
- Click the name of the VPC network.
- On theSubnets tab, clickAdd subnet.
- Provide aName for the proxy-only subnet.
- In theRegion list, selectREGION_A.
- In thePurpose list, selectCross-region Managed Proxy.
- In theIP address range field, enter
10.129.0.0/23. - ClickAdd.
Create the proxy-only subnet inREGION_B
- ClickAdd subnet.
- Provide aName for the proxy-only subnet.
- In theRegion list, selectREGION_B.
- In thePurpose list, selectCross-region Managed Proxy.
- In theIP address range field, enter
10.130.0.0/23. - ClickAdd.
gcloud
Create the proxy-only subnets with thegcloud compute networks subnets create command.
gcloud compute networks subnets createPROXY_SN_A \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=REGION_A \ --network=NETWORK \ --range=10.129.0.0/23
gcloud compute networks subnets createPROXY_SN_B \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=REGION_B \ --network=NETWORK \ --range=10.130.0.0/23
API
Create the proxy-only subnets with thesubnetworks.insert method, replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/subnetworks { "name": "PROXY_SN_A", "ipCidrRange": "10.129.0.0/23", "network": "projects/PROJECT_ID/global/networks/NETWORK", "region": "projects/PROJECT_ID/regions/REGION_A", "purpose": "GLOBAL_MANAGED_PROXY", "role": "ACTIVE" } POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/subnetworks { "name": "PROXY_SN_B", "ipCidrRange": "10.130.0.0/23", "network": "projects/PROJECT_ID/global/networks/NETWORK", "region": "projects/PROJECT_ID/regions/REGION_B", "purpose": "GLOBAL_MANAGED_PROXY", "role": "ACTIVE" }Create the serverless NEGs
Create a serverless NEG for your Cloud Runservice:
gcloud compute network-endpoint-groups create gl7ilb-serverless-neg-a \ --region=REGION_A \ --network-endpoint-type=serverless \ --cloud-run-service=CLOUD_RUN_SERVICE_NAMEA
gcloud compute network-endpoint-groups create gl7ilb-serverless-neg-b \ --region=REGION_B \ --network-endpoint-type=serverless \ --cloud-run-service=CLOUD_RUN_SERVICE_NAMEB
Configure the load balancer
Traffic going from the load balancer to the serverless NEG backends uses specialroutes defined outside your VPC that are not subject to firewallrules. Therefore, if your load balancer only has serverless NEG backends, youdon't need to create firewall rules to allow traffic from the proxy-only subnetto the serverless backend.
Console
Select the load balancer type
In the Google Cloud console, go to theLoad balancing page.
- ClickCreate load balancer.
- ForType of load balancer, selectApplication Load Balancer (HTTP/HTTPS) and clickNext.
- ForPublic facing or internal, selectInternal and clickNext.
- ForCross-region or single region deployment, selectBest for cross-region workloads and clickNext.
- ClickConfigure.
Basic configuration
- Provide aName for the load balancer.
- ForNetwork, selectNETWORK.
Configure the frontend with two forwarding rules
For HTTP:
- ClickFrontend configuration.
- Provide aName for the forwarding rule.
- In theSubnetwork region list, selectREGION_A.
Reserve a proxy-only subnet
If you already configured theproxy-only subnet, theReserve subnet button isn't displayed.You can continue with the next steps. - In theSubnetwork list, selectSUBNET_A.
- In theIP address list, clickCreate IP address. TheReserve a static internal IP address page opens.
- Provide aName for the static IP address.
- In theStatic IP address list, selectLet me choose.
- In theCustom IP address field, enter
10.1.2.99. - SelectReserve.
- ClickDone.
- To add the second forwarding rule, clickAdd frontend IP and port.
- Provide aName for the forwarding rule.
- In theSubnetwork region list, selectREGION_B.
Reserve a proxy-only subnet
Because you have already configured theproxy-only subnet, theReserve subnet button isn't displayed.You can continue with the next steps. - In theSubnetwork list, selectSUBNET_B.
- In theIP address list, clickCreate IP address. TheReserve a static internal IP address page opens.
- Provide aName for the static IP address.
- In theStatic IP address list, selectLet me choose.
- In theCustom IP address field, enter
10.1.3.99. - SelectReserve.
- ClickDone.
For HTTPS:
To assign an SSL certificate to the target HTTPS proxy of the load balancer, you need to use a Certificate Manager certificate.
- ClickFrontend configuration.
- Provide aName for the forwarding rule.
- In theProtocol field, select
HTTPS (includes HTTP/2). - Ensure that thePort is set to
443. - In theSubnetwork region list, selectREGION_A.
Reserve a proxy-only subnet
Because you have already configured theproxy-only subnet,theReserve subnet button isn't displayed.You can continue with the next steps. - In theSubnetwork list, selectSUBNET_A.
- In theIP address list, clickCreate IP address. TheReserve a static internal IP address page opens.
- Provide aName for the static IP address.
- In theStatic IP address list, selectLet me choose.
- In theCustom IP address field, enter
10.1.3.99. - SelectReserve.
- ClickAdd certificate to select an existing certificate or create a new certificate.
If you already have an existing Certificate Manager certificate to select, do the following:
- ClickAdd Certificate.
- ClickSelect an existing certificate and select the certificate from the list of certificates.
- ClickSelect.
After you select the new Certificate Manager certificate, it appears in the list of certificates.
To create a new Certificate Manager certificate, do the following:
- ClickAdd Certificate.
- ClickCreate a new certificate.
- To create a new certificate, follow the steps starting fromstep 3 as outlined in any one of the following configuration methods in the Certificate Manager documentation:
- Select an SSL policy from theSSL policy list. If you have not created any SSL policies, adefault Google Cloud SSL policy is applied.
- ClickDone.
- Provide aName for the frontend configuration.
- In theProtocol field, select
HTTPS (includes HTTP/2). - Ensure that thePort is set to
443. - In theSubnetwork region list, selectREGION_B.
Reserve a proxy-only subnet
Because you have already configured theproxy-only subnet,theReserve subnet button isn't displayed.You can continue with the next steps. - In theSubnetwork list, selectSUBNET_B.
- In theIP address list, clickCreate IP address. TheReserve a static internal IP address page opens.
- Provide aName for the static IP address.
- In theStatic IP address list, selectLet me choose.
- In theCustom IP address field, enter
10.1.3.99. - SelectReserve.
- ClickAdd certificate and then select an existing certificateor create a new certificate.
- Select an SSL policy from theSSL policy list. If you have not created any SSL policies, adefault Google Cloud SSL policy is applied.
- ClickDone.
- ClickBackend configuration.
- In theCreate or select backend services list, clickCreate a backend service.
- Provide aName for the backend service.
- ForProtocol, selectHTTP.
- ForNamed Port, enter
http. - In theBackend type list, selectServerless network endpoint group.
- In theNew backend section:
- In theServerless network endpoint group list, select
gl7ilb-serverless-neg-a. - ClickDone.
- To add another backend, clickAdd backend.
- In theServerless network endpoint group list, select
gl7ilb-serverless-neg-b. - ClickDone.
- ClickRouting rules.
- ForMode, selectSimple host and path rule.
- Ensure that there is only one backend service for any unmatched host and any unmatched path.
- ClickReview and finalize.
- Review your load balancer configuration settings.
- ClickCreate.
Add the second frontend configuration:
Configure the routing rules
Review the configuration
gcloud
Define the backend service with the
gcloud compute backend-servicescreatecommand.gcloud compute backend-services create gil7-backend-service \ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTP \ --global
Add backends to the backend service with the
gcloud compute backend-servicesadd-backendcommand.gcloud compute backend-services add-backend gil7-backend-service \ --network-endpoint-group=gl7ilb-serverless-neg-a \ --network-endpoint-group-region=REGION_A \ --global
gcloud compute backend-services add-backend gil7-backend-service \ --network-endpoint-group=gl7ilb-serverless-neg-b \ --network-endpoint-group-region=REGION_B \ --global
Create the URL map with the
gcloud compute url-mapscreatecommand.gcloud compute url-maps create gil7-map \ --default-service=gil7-backend-service \ --global
Create the target proxy.
For HTTP:
Create the target proxy with the
gcloud compute target-http-proxiescreatecommand.gcloud compute target-http-proxies create gil7-http-proxy \ --url-map=gil7-map \ --global
For HTTPS:
To create a Google-managed certificate, see the following documentation:
- Create a Google-managed certificate issued by your Certificate Authority Service instance
- Create a Google-managed certificate with DNS authorization
After you create the Google-managed certificate,attach the certificate directly to the target proxy.Certificate maps are not supported by cross-region internal Application Load Balancers.
To create a self-managed certificate, see the following documentation:
Assign your file paths to variable names.
export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
export LB_PRIVATE_KEY=PATH_TO_LB_PRIVATE_KEY_FILE
Create an all region SSL certificate using the
gcloud certificate-managercertificates createcommand.gcloud certificate-manager certificates create gilb-certificate \ --private-key-file=$LB_PRIVATE_KEY \ --certificate-file=$LB_CERT \ –-scope=all-regions
Use the SSL certificate to create a target proxy with the
gcloudcompute target-https-proxies createcommandgcloud compute target-https-proxies create gil7-https-proxy \ --url-map=gil7-map \ --certificate-manager-certificates=gilb-certificate
Create two forwarding rules: one with a VIP (
10.1.2.99) in theREGION_Bregion andanother one with a VIP (10.1.3.99) in theREGION_Aregion.For custom networks, you must reference the subnet in the forwardingrule. Note that this is the virtual machine (VM) instance subnet, not theproxy subnet.
For HTTP:
Use the
gcloud compute forwarding-rulescreatecommandwith the correct flags.gcloud compute forwarding-rules create gil7-forwarding-rule-a \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=NETWORK \ --subnet=SUBNET_B \ --subnet-region=REGION_B \ --address=10.1.3.99 \ --ports=80 \ --target-http-proxy=gil7-http-proxy \ --global
gcloud compute forwarding-rules create gil7-forwarding-rule-b \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=NETWORK \ --subnet=SUBNET_A \ --subnet-region=REGION_A \ --address=10.1.2.99 \ --ports=80 \ --target-http-proxy=gil7-http-proxy \ --global
For HTTPS:
Create the forwarding rule with the
gcloud compute forwarding-rulescreatecommandwith the correct flags.gcloud compute forwarding-rules create gil7-forwarding-rule-a \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=NETWORK \ --subnet=SUBNET_B \ --address=10.1.3.99 \ --ports=443 \ --target-https-proxy=gil7-https-proxy \ --global
gcloud compute forwarding-rules create gil7-forwarding-rule-b \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=NETWORK \ --subnet=SUBNET_A \ --address=10.1.2.99 \ --ports=443 \ --target-https-proxy=gil7-https-proxy \ --global
API
Create the global backend service by making aPOST request to thebackendServices.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices{"name": "gil7-backend-service","backends": [ { "group": "projects/PROJECT_ID/zones/ZONE_A/instanceGroups/gl7ilb_serverless_negwest", "balancingMode": "UTILIZATION" }, { "group": "projects/PROJECT_ID/zones/ZONE_B/instanceGroups/gl7ilb_serverless_negeast", }],"loadBalancingScheme": "INTERNAL_MANAGED"}Create the URL map by making aPOST request to theurlMaps.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/urlMaps{"name": "l7-ilb-map","defaultService": "projects/PROJECT_ID/global/backendServices/gil7-backend-service"}For HTTP:
Create the target HTTP proxy by making aPOST request to thetargetHttpProxies.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/targetHttpProxy{"name": "l7-ilb-proxy","urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-map"}Create the forwarding rule by making aPOST request to theglobalforwardingRules.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules{"name": "gil7-forwarding-rule-a","IPAddress": "10.1.2.99","IPProtocol": "TCP","portRange": "80-80","target": "projects/PROJECT_ID/global/targetHttpProxies/l7-ilb-proxy","loadBalancingScheme": "INTERNAL_MANAGED","subnetwork": "projects/PROJECT_ID/regions/REGION_A/subnetworks/SUBNET_A","network": "projects/PROJECT_ID/global/networks/NETWORK","networkTier": "PREMIUM"}POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules{"name": "gil7-forwarding-rule-b","IPAddress": "10.1.3.99","IPProtocol": "TCP","portRange": "80-80","target": "projects/PROJECT_ID/global/targetHttpProxies/l7-ilb-proxy","loadBalancingScheme": "INTERNAL_MANAGED","subnetwork": "projects/PROJECT_ID/regions/REGION_B/subnetworks/SUBNET_B","network": "projects/PROJECT_ID/global/networks/NETWORK","networkTier": "PREMIUM"}For HTTPS:
Read the certificate and private key files, and then create the SSLcertificate. The following example showshow to do this with Python.
Create the target HTTPS proxy by making aPOST request to thetargetHttpsProxies.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/targetHttpsProxy{"name": "l7-ilb-proxy","urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-map","sslCertificates": /projects/PROJECT_ID/global/sslCertificates/SSL_CERT_NAME}Create the forwarding rule by making aPOST request to theglobalForwardingRules.insert method,replacingPROJECT_ID with your project ID.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules{"name": "gil7-forwarding-rule-a","IPAddress": "10.1.2.99","IPProtocol": "TCP","portRange": "80-80","target": "projects/PROJECT_ID/global/targetHttpsProxies/l7-ilb-proxy","loadBalancingScheme": "INTERNAL_MANAGED","subnetwork": "projects/PROJECT_ID/regions/REGION_A/subnetworks/SUBNET_A","network": "projects/PROJECT_ID/global/networks/NETWORK","networkTier": "PREMIUM"}POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/forwardingRules{"name": "gil7-forwarding-rule-b","IPAddress": "10.1.3.99","IPProtocol": "TCP","portRange": "80-80","target": "projects/PROJECT_ID/global/targetHttpsProxies/l7-ilb-proxy","loadBalancingScheme": "INTERNAL_MANAGED","subnetwork": "projects/PROJECT_ID/regions/REGION_B/subnetworks/SUBNET_B","network": "projects/PROJECT_ID/global/networks/NETWORK","networkTier": "PREMIUM"}Test the load balancer
Now that the load balancing service is running, you can send traffic to theforwarding rule and observe the traffic being dispersed to different instances.
Configure the firewall rule
This example requires thefw-allow-ssh firewall rule for the test client VM.fw-allow-ssh is an ingress rule that is applicable to the test client VM andthat allows incoming SSH connectivity on TCP port22 from anyaddress. You can choose a more restrictive source IP address range for thisrule; for example, you can specify just the IP address ranges of the system fromwhich you initiate SSH sessions. This example uses the target tagallow-ssh.
gcloud
Create the
fw-allow-sshfirewall rule to allow SSH connectivity toVMs with the network tagallow-ssh. When you omitsource-ranges,Google Cloudinterprets the rule to mean anysource.gcloud compute firewall-rules create fw-allow-ssh \ --network=NETWORK \ --action=allow \ --direction=ingress \ --target-tags=allow-ssh \ --rules=tcp:22
Create a VM instance to test connectivity
Create a client VM:
gcloud compute instances create l7-ilb-client-a \ --image-family=debian-12 \ --image-project=debian-cloud \ --network=NETWORK \ --subnet=SUBNET_A \ --zone=ZONE_A \ --tags=allow-ssh
gcloud compute instances create l7-ilb-client-b \ --image-family=debian-12 \ --image-project=debian-cloud \ --network=NETWORK \ --subnet=SUBNET_B \ --zone=ZONE_B \ --tags=allow-ssh
Connect, using SSH, to each client instance.
gcloud compute ssh l7-ilb-client-a \ --zone=ZONE_A
gcloud compute ssh l7-ilb-client-b \ --zone=ZONE_B
Verify that the IP address is serving its hostname.
Verify that the client VM can reach both IP addresses. The command succeedsand returns the name of the backend VM that served the request:
For HTTP testing:
curl 10.1.2.99
curl 10.1.3.99
For HTTPS testing:
curl -k -s 'https://DOMAIN_NAME:443' --connect-toDOMAIN_NAME:443:10.1.2.99:443
curl -k -s 'https://DOMAIN_NAME:443' --connect-toDOMAIN_NAME:443:10.1.3.99:443
ReplaceDOMAIN_NAME with your application domain name, forexample,
test.example.com.The
-kflag causes curl to skip certificate validation.Optional: Use the configuredDNS record to resolvethe IP address.
curl service.example.com
Run 100 requests and confirm that they are load balanced
For HTTP:
{ RESULTS= for i in {1..100} do RESULTS="$RESULTS:$(curl --silent 10.1.2.99)" done echo "" echo " Results of load-balancing to 10.1.2.99: " echo "***" echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c echo } { RESULTS= for i in {1..100} do RESULTS="$RESULTS:$(curl --silent 10.1.3.99)" done echo "" echo " Results of load-balancing to 10.1.3.99: " echo "***" echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c echo }For HTTPS:
ReplaceDOMAIN_NAME with your application domain name, for example,test.example.com.
{ RESULTS= for i in {1..100} do RESULTS="$RESULTS:$(curl -k -s 'https://DOMAIN_NAME:443' --connect-toDOMAIN_NAME:443:10.1.2.99:443)" done echo "" echo " Results of load-balancing to 10.1.2.99: " echo "***" echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c echo } { RESULTS= for i in {1..100} do RESULTS="$RESULTS:$(curl -k -s 'https://DOMAIN_NAME:443' --connect-toDOMAIN_NAME:443:10.1.3.99:443)" done echo "" echo " Results of load-balancing to 10.1.3.99: " echo "***" echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c echo }Test failover
Verify failover to backends in the
REGION_Aregion when backends in theREGION_Bregions are unhealthy orunreachable. We simulate this by removing all of thebackends fromREGION_B:gcloud compute backend-services remove-backend gil7-backend-service \ --network-endpoint-group=gl7ilb-serverless-neg-b \ --network-endpoint-group-zone=ZONE_B
Connect, using SSH, to a client VM in
REGION_B.gcloud compute ssh l7-ilb-client-b \ --zone=ZONE_B
Send requests to the load balanced IP address in the
REGION_Bregion.The command output displays responses from backend VMs inREGION_A.ReplaceDOMAIN_NAME with your application domain name, forexample,
test.example.com.{RESULTS=for i in {1..100}do RESULTS="$RESULTS:$(curl -k -s 'https://DOMAIN_NAME:443' --connect-toDOMAIN_NAME:443:10.1.3.99:443)"doneecho "***"echo "*** Results of load-balancing to 10.1.3.99: "echo "***"echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -cecho}
Additional configuration options
This section expands on the configuration example to provide alternative andadditional configuration options. All of the tasks are optional. You can performthem in any order.
Using a URL mask
When creating a serverless NEG, instead of selecting a specificCloud Run service, you can use a URL mask to point tomultiple services serving at the same domain. A URL mask is a template of yourURL schema. The serverless NEG uses this template to extract the servicename from the incoming request's URL and map the request to the appropriateservice.
URL masks are particularly useful if your service ismapped to a customdomain rather than to the default addressthat Google Cloud provides for the deployed service. A URL mask lets youtarget multiple services and versions with a single rule even when yourapplication is using a custom URL pattern.
If you haven't already done so, make sure you read theServerless NEGSoverview: URLMasks.
Construct a URL mask
To construct a URL mask for your load balancer, start with the URL of yourservice. This example uses a sample serverless app running athttps://example.com/login. This is the URL where the app'slogin serviceis served.
- Remove the
httporhttpsfrom the URL. You are left withexample.com/login. - Replace the service name with a placeholder for the URL mask.
- Cloud Run: Replace theCloud Run service name with theplaceholder
<service>. If the Cloud Runservice has a tag associated with it,replace the tag name with the placeholder<tag>.In this example, the URL mask you are left with isexample.com/<service>.
- Cloud Run: Replace theCloud Run service name with theplaceholder
Optional: If the service name can beextracted from the path portion of the URL, the domain can be omitted. Thepath part of the URL mask is distinguishedby the first slash (
/) character. If a slash (/) is not present in theURL mask, the mask is understood to represent the host only. Therefore, forthis example, the URL mask can be reduced to/<service>.Similarly, if
<service>can be extracted from the host part of theURL, you can omit the path altogether from the URL mask.You can also omitany host or subdomain components that come before the first placeholder aswell as any path components that come after the last placeholder. In suchcases, the placeholder captures the required information for the component.
Here are a few more examples that demonstrate these rules:
This table assumes that you have a custom domain calledexample.com andall your Cloud Run services are beingmappedto this domain.
| Service, Tag name | Cloud Run custom domain URL | URL mask |
|---|---|---|
| service: login | https://login-home.example.com/web | <service>-home.example.com |
| service: login | https://example.com/login/web | example.com/<service> or /<service> |
| service: login, tag: test | https://test.login.example.com/web | <tag>.<service>.example.com |
| service: login, tag: test | https://example.com/home/login/test | example.com/home/<service>/<tag> or /home/<service>/<tag> |
| service: login, tag: test | https://test.example.com/home/login/web | <tag>.example.com/home/<service> |
Creating a serverless NEG with a URL mask
Console
For a new load balancer, you can use the same end-to-end process asdescribed previously in this document. When configuring the backend service,instead of selecting a specific service, enter a URL mask.
If you have an existing load balancer, you can edit the backend configurationand have the serverless NEG point to a URL mask instead of a specific service.
To add a URL mask-based serverless NEG to an existing backend service,do the following:
- In the Google Cloud console, go to theLoad balancing page.
Go to Load balancing - Click the name of the load balancer that has the backend service you want to edit.
- On theLoad balancer details page, clickEdit.
- On theEdit global external Application Load Balancer page, clickBackend configuration.
- On theBackend configuration page, clickEdit for the backend service you want to modify.
- ClickAdd backend.
- SelectCreate Serverless network endpoint group.
- For theName, enter
helloworld-serverless-neg. - UnderRegion, the region of the load balancer is displayed.
- UnderServerless network endpoint group type,Cloud Run is the only supported network endpoint group type.
- SelectUse URL Mask.
- Enter a URL mask. For information about how to create a URL mask, seeConstructing a URL mask.
- ClickCreate.
- In theNew backend, clickDone.
- ClickUpdate.
gcloud
To create a serverless NEG with a sample URL mask ofexample.com/<service>:
gcloud compute network-endpoint-groups createSERVERLESS_NEG_MASK_NAME \ --region=REGION \ --network-endpoint-type=serverless \ --cloud-run-url-mask="example.com/<service>"
Use the same IP address between multiple internal forwarding rules
For multiple internal forwarding rules to share the same internal IP address,you must reserve the IP address and set its--purpose flag toSHARED_LOADBALANCER_VIP.
gcloud
gcloud compute addresses createSHARED_IP_ADDRESS_NAME \ --region=REGION \ --subnet=SUBNET_NAME \ --purpose=SHARED_LOADBALANCER_VIP
Configure DNS routing policies
If your clients are in multiple regions, you might want to make yourcross-region internal Application Load Balancer accessible by using VIPs in these regions. You can useDNS routing policies of typeGEO to route clienttraffic to the load balancer VIP in the region closest to the client. Thismulti-region setup minimizes latency and network transit costs. In addition, itlets you set up a DNS-based, global, load balancing solution that providesresilience against regional outages.
Cloud DNS supports health checking and enables automatic failover whenthe endpoints fail their health checks. During a failover, Cloud DNSautomatically adjusts the traffic split among the remaining healthy endpoints.For more information, seeManage DNS routing policies and healthchecks.
gcloud
To create a DNS entry with a 30 second TTL, use thegcloud dns record-sets create command.
gcloud dns record-sets createDNS_ENTRY --ttl="30" \ --type="A" --zone="service-zone" \ --routing-policy-type="GEO" \ --routing-policy-data="REGION_A=gil7-forwarding-rule-a@global;REGION_B=gil7-forwarding-rule-b@global" \ --enable-health-checking
Replace the following:
DNS_ENTRY: DNS or domain name of the record-setFor example,
service.example.comREGION_AandREGION_B:the regions where you have configured the load balancer
API
Create the DNS record by making aPOST request to theResourceRecordSets.create method.ReplacePROJECT_ID with your project ID.
POST https://www.googleapis.com/dns/v1/projects/PROJECT_ID/managedZones/SERVICE_ZONE/rrsets{ "name": "DNS_ENTRY", "type": "A", "ttl": 30, "routingPolicy": { "geo": { "items": [ { "location": "REGION_A", "healthCheckedTargets": { "internalLoadBalancers": [ { "loadBalancerType": "globalL7ilb", "ipAddress": "IP_ADDRESS", "port": "80", "ipProtocol": "tcp", "networkUrl": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/lb-network", "project": "PROJECT_ID" } ] } }, { "location": "REGION_B", "healthCheckedTargets": { "internalLoadBalancers": [ { "loadBalancerType": "globalL7ilb", "ipAddress": "IP_ADDRESS_B", "port": "80", "ipProtocol": "tcp", "networkUrl": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/lb-network", "project": "PROJECT_ID" } ] } } ] } }}Enable outlier detection
You can enableoutlierdetectionon global backend services to identify unhealthy serverless NEGs and reduce thenumber the requests sent to the unhealthy serverless NEGs.
Outlier detection is enabled on the backend service by using one of the following methods:
- The
consecutiveErrorsmethod (outlierDetection.consecutiveErrors), inwhich a5xxseries HTTP status code qualifies as an error. - The
consecutiveGatewayFailuremethod(outlierDetection.consecutiveGatewayFailure), in which only the502,503, and504HTTP status codes qualify as an error.
Use the following steps to enable outlier detection for an existing backendservice. Note that even after enabling outlier detection, some requests can besent to the unhealthy service and return a5xx status code tothe clients. To further reduce the error rate, you can configure more aggressivevalues for the outlier detection parameters. For more information, see theoutlierDetection field.
Console
In the Google Cloud console, go to theLoad balancing page.
Click the name of the load balancer whose backend service you want toedit.
On theLoad balancer details page, clickEdit.
On theEdit cross-region internal Application Load Balancer page, clickBackend configuration.
On theBackend configuration page, clickEdit for the backend service thatyou want to modify.
Scroll down and expand theAdvanced configurations section.
In theOutlier detection section, select theEnable checkbox.
ClickEdit to configureoutlier detection.
Verify that the following options are configured with these values:
Property Value Consecutive errors 5 Interval 1000 Base ejection time 30000 Max ejection percent 50 Enforcing consecutive errors 100 In this example, the outlier detection analysis runs every one second. Ifthe number of consecutive HTTP
5xxstatus codesreceived by anEnvoy proxy is five or more, the backend endpoint is ejected from theload-balancing pool of that Envoy proxy for 30 seconds. When theenforcing percentage is set to 100%, the backend service enforces theejection of unhealthy endpoints from the load-balancing pools of thosespecific Envoy proxies every time the outlier detection analysis runs. Ifthe ejection conditions are met, up to 50% of the backend endpoints fromthe load-balancing pool can be ejected.ClickSave.
To update the backend service, clickUpdate.
To update the load balancer, on theEdit cross-region internal Application Load Balancer page, clickUpdate.
gcloud
Export the backend service into a YAML file.
gcloud compute backend-services exportBACKEND_SERVICE_NAME \ --destination=BACKEND_SERVICE_NAME.yaml --global
Replace
BACKEND_SERVICE_NAMEwith the name of thebackend service.Edit the YAML configuration of the backend service to add the fields foroutlier detection as highlighted in the following YAML configuration,in the
outlierDetectionsection:In this example, the outlier detection analysis runs every one second. Ifthe number of consecutive HTTP
5xxstatus codesreceived by anEnvoy proxy is five or more, the backend endpoint is ejected from theload-balancing pool of that Envoy proxy for 30 seconds. When theenforcing percentage is set to 100%, the backend service enforces theejection of unhealthy endpoints from the load-balancing pools of thosespecific Envoy proxies every time the outlier detection analysis runs. Ifthe ejection conditions are met, up to 50% of the backend endpoints fromthe load-balancing pool can be ejected.name:BACKEND_SERVICE_NAMEbackends:- balancingMode: UTILIZATION capacityScaler: 1.0 group: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_A/networkEndpointGroups/SERVERLESS_NEG_NAME- balancingMode: UTILIZATION capacityScaler: 1.0 group: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION_B/networkEndpointGroups/SERVERLESS_NEG_NAME_2outlierDetection: baseEjectionTime: nanos: 0 seconds: 30 consecutiveErrors: 5 enforcingConsecutiveErrors: 100 interval: nanos: 0 seconds: 1 maxEjectionPercent: 50port: 80selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/BACKEND_SERVICE_NAMEsessionAffinity: NONEtimeoutSec: 30...
Replace the following:
BACKEND_SERVICE_NAME: the name of the backendservicePROJECT_ID: the ID of your projectREGION_AandREGION_B:the regions where the load balancer has been configured.SERVERLESS_NEG_NAME: the name of the firstserverless NEGSERVERLESS_NEG_NAME_2: the name of the secondserverless NEG
Update the backend service by importing the latest configuration.
gcloud compute backend-services importBACKEND_SERVICE_NAME \ --source=BACKEND_SERVICE_NAME.yaml --global
Outlier detection is now enabled on the backend service.
Deleting a serverless NEG
A network endpoint group cannot be deleted if it is attached to a backendservice. Before you delete a NEG, ensure that it is detached from thebackend service.
Console
- To make sure the serverless NEG you want to delete is not in use by any backend service, go to theBackend services tab on theLoad balancing components page.
Go to Backend services - If the serverless NEG is in use, do the following:
- Click the name of the backend service that is using the serverless NEG.
- ClickEdit.
- From the list ofBackends, click to remove the serverless NEG backend from the backend service.
- ClickSave.
- Go to theNetwork endpoint group page in the Google Cloud console.
Go to Network endpoint group - Select the checkbox for the serverless NEG you want to delete.
- ClickDelete.
- ClickDelete again to confirm.
gcloud
To remove a serverless NEG from a backend service, you must specifythe region where the NEG was created.
gcloud compute backend-services remove-backendBACKEND_SERVICE_NAME \ --network-endpoint-group=SERVERLESS_NEG_NAME \ --network-endpoint-group-region=REGION \ --region=REGION
To delete the serverless NEG:
gcloud compute network-endpoint-groups deleteSERVERLESS_NEG_NAME \ --region=REGION
What's next
- Deploy an internal Application Load Balancer with Cloud Run by using Terraform
- Clean up a load balancing setup
- Deprovision Shared VPC
- Internal Application Load Balancer logging and monitoring
- Troubleshoot issues with internal Application Load Balancers
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.