3
votes

I want to configure Google Could Load balancing so that:

  • All edge requests to port 443 terminate SSL at the load balancer and route to port 8080 in a managed instance group
  • All edge requests to port 80 route to port 8081 in a managed instance group which will then send a 307 response to the HTTPS service forcing SSL.

I have:

Global forwading rules

  • A global forwarding rule STATIC_IP:80 -> httpsreditect-target-proxy
  • A global forwarding rule STATIC_IP:443 -> webapp-target-proxy

Target proxies

  • httpsreditect-target-proxy -> httpredirect_urlmap
  • webapp-target-proxy -> webapp_urlmap

URL Maps

  • httpredirect_urlmap -> redirect_backend (8081 in the instance pool)
  • webapp_urlmap -> webapp_backend (8080 in the instance pool)

This does not work.

With this setup if I set the redirect_backend port to 8081 the webapp_backend port is also changed to 8081. Likewise if I set the webapp_backend port to 8080 then the redirect_backend port is set to 8080.

Is it possible to route traffic based on port to different backends? The option is their in the GUI, no validation errors, it feels like it should be possible but when a backend port is set all backends are then set to the same port?

I know putting HAProxy on the node is a solution and reverse proxy the microservices there but I'd rather have the Google Cloud Application Loadbalancer terminate SSL as using f1-micro instances.

1

1 Answers

5
votes

The key to do this is an easily missed snippet at https://cloud.google.com/compute/docs/load-balancing/http/backend-service#restrictions_and_guidance.

Your configuration will be simpler if you do not add the same instance group to two different backends. If you do add the same instance group to two backends:

...

If your instance group serves two or more ports for several backends respectively, you have to specify different port names in the instance group.

The initial setup is non trivial so below is a reference.

Based on the example in my config:

  • A managed instance group
    • Main webapp running on port 80
    • HTTP redirect service running on port 8081

Firewall

Ensure you have firewall rules allowing a healthcheck access to your service from Google:

gcloud compute firewall-rules create allow-http-from-lb \
  --description "Incoming http allowed from cloud loadbalancer." \
  --allow tcp:80
  --source-ranges "130.211.0.0/22"

gcloud compute firewall-rules create allow-http-redirect-from-lb \
  --description "Incoming http redirect service allowed from cloud loadbalancer." \
  --allow tcp:8081
  --source-ranges "130.211.0.0/22"

Healthcheck

Ensure you have healthchecks setup for the two services checking on the correct internal ports.

gcloud compute http-health-checks create webapp-healthcheck \
  --description "Main webapp healthcheck" \
  --port 80 \
  --request-path "/healthcheck"

gcloud compute http-health-checks create httpsredirect-service-healthcheck \
  --description "HTTP redirect service healthcheck" \
  --port 8081 \
  --request-path "/healthcheck"

Configure named ports

The looks to be the key if your instance group has several microservices running on different ports that you want to expose under a common loadbalancer.

Replace INSTANCE_GROUP_NAME, REGION and the named-ports with correct values for your services.

gcloud compute instance-groups set-named-ports INSTANCE_GROUP_NAME \
  --region=REGION \
  --named-ports "webapp:80,httpsredirectservice:8081"

Create loadbalancer backends

Ensure the --port-name matches the correct named port from the previous step.

gcloud compute backend-services create webapp-lb-backend \
  --http-health-check webapp-healthcheck \
  --protocol http \
  --description "Webapp load balancer backend" \
  --port-name webapp


gcloud compute backend-services create httpsredirect-lb-backend \
  --http-health-check webapp-healthcheck \
  --protocol http \
  --description "HTTP -> HTTPS redirect service load balancer backend" \
  --port-name httpsredirectservice

Create URL Maps for the two services

Ensure --default-service uses the configured values from the previous step.

gcloud compute url-maps create webapp-urlmap \
  --default-service webapp-lb-backend

gcloud compute url-maps create httpsredirect-urlmap \
  --default-service httpsredirect-lb-backend

Create Target Proxies

Target proxies are referenced by one or more global forwarding rules and route the incoming HTTP or HTTPS requests to a URL map.

We create a https target proxy for the webapp to terminate SSL at the load balancer.

gcloud compute target-https-proxies create webapp-target-proxy \
  --url-map webapp-urlmap \
  --ssl-certificate [SSL_CERTIFICATES]

The redirect service:

gcloud compute target-http-proxies create httpsredirect-target-proxy \
  --url-map httpsredirect-urlmap 

Global forwarding rules

The final step is to create the global forwarding rules

gcloud compute forwarding-rules create webapp-forwarding-rule
  --global \
  --address LB_STATIC_IP \
  --port-range 443 \
  --target-https-proxy webapp-target-proxy

gcloud compute forwarding-rules create httpsredirect-forwarding-rule
  --global \
  --address LB_STATIC_IP \
  --port-range 80 \
  --target-http-proxy httpsredirect-target-proxy

Issues I hit

  • Ensure the firewall is configured correctly to allow healthchecks and healthchecks are setup.
  • If get intermitent 502 errors check the loadbalencers in the cloud console report healthy instances

Other notes

  • Because two url maps are needed you are charged for two load balancers looking at my billing info. Port 80 and port 443 both use their own load balancer
  • It doesn't look like it's possible to use a network loadbalancer bother terminating SSL and serving HTTP as can be done on AWS