HTTP(S) Layer 7 Load Balancing on Google Cloud with Cloud CDN
This post provides you with detailed and advanced steps to setup HTTP(S) Layer 7 Load Balancer for your web application on Google Cloud Platform.
Here we will set up WordPress, Nginx, PHP, Cloud SQL, and Cloud Storage for your Load Balancer.
Carefully follow this tutorial without missing any steps for a successful setup.
Steps to setup Load Balancing on Google Cloud
- Enable APIs and create a Service account
- Nginx configuration for Load Balancer
- Create a Health Check
- Create Instance Template
- Create a Managed Instance Group
- Reserve Global Region IPv4 and IPv6 addresses
- Create Load Balancer
- Install LetsEncrypt SSL Certificate
- Configure DNS and setup Cloud CDN
Support
- You can hire me on Fiverr for $5 for professional Google Cloud services and WordPress website development
- Support me with $1 on Patreon to create more tutorials on Google Cloud and Wordpress
Prerequisites
- Setup Compute Engine Instance and setup Google Cloud DNS
- Have a Compute Engine running with Ubuntu, Nginx, PHP, and WordPress Installed
- Cloud SQL configured and connected with Compute Engine
- Google Cloud Storage configured to handle the WordPress Media Library
If you have all the above mentioned required requisites done and in place, you can proceed to setup Load Balancing.
Enable APIs and create a Service account
Go to APIs and Services and click Enable APIs and Services and enable Cloud SQL API
, Cloud SQL Admin API
and Service Networking API
Now go to IAM & Admin >> Service accounts and click Create service account
In step 1
Enter Service account Name
Click Create
In step 2
Select Role
Cloud SQL >> Cloud SQL Client
Project >> Editor
Click Continue
In step 3
Click Create Key
Choose Key type as JSON
Click Create
Nginx Configuration for Load Balancer
If you have followed the WordPress setup above
Go to Compute Engine >> Instances and SSH into your instance. You must have an Nginx configuration file in your /etc/nginx/sites-available
directory named as yourdomainname.com
Now you need to modify your Nginx configuration file to accept connections from Load Balancer, so edit the file
sudo nano /etc/nginx/sites-available/yourdomainname.com
and replace the contents with the following configuration and hit Ctrl+X
followed by Y
to save it. Make sure you replaced the yourdomainname.com
with your domain name.
fastcgi_cache_path /home/username/yourdomainname.com/cache levels=1:2 keys_zone=yourdomainname.com:100m inactive=60m;server {
listen [::]:80;
listen 80; server_name yourdomainname.com www.yourdomainname.com; if ($http_x_forwarded_proto != "https") {
return 301 https://www.yourdomainname.com$request_uri;
} error_log /home/username/yourdomainname.com/logs/error.log; root /home/username/yourdomainname.com/public/;
index index.htm index.html index.php; set $skip_cache 0; if ($request_method = POST) {
set $skip_cache 1;
} if ($query_string != "") {
set $skip_cache 1;
} if ( $cookie_woocommerce_items_in_cart = "1" ){
set $skip_cache 1;
} if ($request_uri ~* "/wp-admin/|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
set $skip_cache 1;
}
if ($request_uri ~* "/(cart|checkout|my-account)/*$") {
set $skip_cache 1;
} if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $skip_cache 1;
} location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
} location / {
try_files $uri $uri/ /index.php?$args;
} location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params; fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache; fastcgi_cache yourdomainname.com; fastcgi_cache_lock on;
fastcgi_cache_use_stale error timeout invalid_header updating http_500;
fastcgi_cache_valid 200 302 60m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 1m;
fastcgi_pass_header Set-Cookie:Set-Cookie;
fastcgi_pass_header Cookie;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_cache_background_update on; add_header X-Cache $upstream_cache_status; add_header Content-Security-Policy "img-src * 'self' data: blob: https:; default-src 'self' https://www.googletagmanager.com https://*.google-analytics.com https://www.yourdomainname.com https://*.googleapis.com https://*.gstatic.com https://*.gravatar.com https://*.w.org data: 'unsafe-inline' 'unsafe-eval';" always;
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Access-Control-Allow-Origin "https://www.yourdomainname.com";
add_header Referrer-Policy "origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
} location ~* \.(jpg|jpeg|png|gif|ico)$ {
expires 365d;
add_header Cache-Control "public";
} location ~* \.(?:css|js)$ {
expires 7d;
add_header Cache-Control "public";
} location ~* \.(?:eot|woff|woff2|ttf|svg|otf) {
expires 30d;
add_header Cache-Control "public"; types {font/opentype otf;}
types {application/vnd.ms-fontobject eot;}
types {font/truetype ttf;}
types {application/font-woff woff;}
types {font/x-woff woff2;}
}
}
Now edit the /etc/nginx/nginx.conf
file and change the value of keepalive_timeout
directive to 650s
and save the file.
Connect to Cloud SQL
Next, edit the WordPress config file by issuing the following command
sudo nano ~/yourdomainname.com/public/wp-config.php
As the instances are created dynamically you need to connect to Cloud SQL using Cloud SQL proxy or with Private IP.
Using Cloud SQL proxy
Change hostname to 127.0.0.1
Using Private IP
Go to your Cloud SQL Instance and enable Private IP.
Change hostname to PRIVATE_IP_ADDRESS
While using Private IP, make sure you are using the same VPN network.
Below define('DB_COLLATE', '');
add the following
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
Create Instance Template
Next, stop the VM Instance and go to Compute Engine >> Images and click Create Image.
In Name enter a unique name
In Source select Disk
In Source Disk select the disk of your VM Instance
Click Create
Once the Image is created go to Compute Engine >> Instance templates and click Create instance template
In Name enter name
of the template
In Machine type choose 1 vCPU 3.75 GB RAM
In the Boot Disk click Change and click the Custom images tab.
Choose the Image that you created earlier
In the Boot disk type select SSD persistent disk
Click Select
In Identity and API access choose Allow full access to all Cloud APIs
In Firewall check both Allow HTTP traffic
and Allow HTTPS traffic
Cloud SQL Proxy connection
If you are using the Private IP address to connect to Cloud SQL, you can skip the startup script.
In the Management tab find the Startup script and enter the following
#! /bin/bash
sudo apt-get update
sudo apt-get install mysql-client
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
chmod +x cloud_sql_proxy
sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306
Replace the INSTANCE_CONNECTION_NAME with your Cloud SQL connection name
In the Networking tab make sure Premium
is selected in Network Service Tier
Click Create
Create a Managed Instance Group
Goto Compute Engine >> Instance groups and click Create instance group
In Name enter name
In Location choose Single-zone
In Region choose your preferred region
Click Specify port name mapping
In Port name enter http
and in Port numbers enter 80
In Group type choose Managed instance group
In Instance template select the instance template you just created
Leave everything to default and click Create
Reserve Global Region IPv4 and IPv6 Address
Go to VPC network >> External IP addresses and click Reserve Static IP Address
In Name enter a name
for IPv4 address
In Network Service Tier choose Premium
In IP version choose IPv4
In Type choose Global
Click Reserve
Again click Reserve Static IP Address
In Name enter a name
for IPv6 address
In Network Service Tier choose Premium
In IP version choose IPv6
In Type choose Global
Click Reserve
Create Load Balancer
Go to Network Services >> Load Balancing and Click Create Load Balancer
In the HTTP(S) Load Balancing click Start Configuration
Backend configuration
Enter a name for your Load Balancer and click Backend configuration
In Backend services & backend buckets select Backend service >> Create backend service
Enter a name for your backend service
In Backend Type choose Instance group
In Backends select the Instance group you created
In Port numbers enter 80
In Balance mode choose Utilization
Click Done
Check Enable Cloud CDN
Create Health Check
In Health Check click create health check
In Name enter a health check name
In Protocol select TCP
In Port enter 80
In Proxy protocol select None
In Check Interval enter 10
In Timeout enter 5
In Healthy threshold enter 2
In Unhealthy threshold enter 3
Click Save and Continue
Frontend Configuration
Enter a name for your IPv4 frontend configuration
In Protocol select HTTPS
In IP version select IPv4
In IP address select the IP4 address
you reserved
In Certificate select Create Certificate
Enter a name for your certificate
In Create mode choose to Create Google-managed certificate
In Domains enter *.yourdomainname.com
This setting will issue a Google managed Let’sEncrypt Certificate.
Attention: Once you have created a certificate it will be in the PROVISION status. Once the certificate is ACTIVE, you’ll have SSL issues for a few minutes with the error message ERR_SSL_VERSION_OR_CIPHER_MISMATCH. It took 15 minutes for mine to have everything up and running.
Uploading your own Certificate
To upload your own certificate, In Create mode choose to Upload my certificate
Here we use the Let’s Encrypt SSL certificate as an example
If you haven’t setup SSL in your VM instance, please check Installing SSL in Google Cloud Platform
SSH your VM Instance and enter the following commands and copy all contents
sudo nano /etc/letsencrypt/live/yourdomainname.com/fullchain.pem
In Public key certificate copy and paste the contents of fullcahain.pem
file
sudo nano /etc/letsencrypt/live/yourdomainname.com/cert.pem
In Certificate chain copy and paste the contents of cert.pem
file
sudo nano /etc/letsencrypt/live/yourdomainname.com/privkey.pem
In Private key copy and paste the contents of privkey.pem
file
Click Create
Now in Frontend configuration click Done
Click Add Frontend IP and Port
Enter a name for your IPv6 frontend configuration
In Protocol select HTTPS
In IP version select IPv6
In IP address select the IPv6 address
you reserved
In Certificate select the certificate you just created
Click Done
That’s all now your Backend and Frontend are configured
Configure DNS and Setup Cloud CDN
Click Create
Now Goto Network services >> Cloud DNS and click your domain name
Edit the A record and replace the IPv4 address with your newly reserved IPv4 address
.
Click Add record set
In Resource record type select AAAA
record
Enter the IPv6 address
that you reserved
Goto Goto Network services >> Cloud CDN and click Add origin
In Origin select the Load balancer
you just created.
Click Add
Now go to Network services >> Load Balancing and wait for 10–15 minutes for the Load Balancing settings to propagate.
That’s all, now your Load Balancer is configured to scale your website horizontally with Nginx web server