Why are backend ports automatically changing to be the same on a GCP load balancer? - google-cloud-platform

I have a cluster on GCP with multiple deployments on it.
The deployments are exposed with NodePort services.
I'm setting up a HTTP(S) load balancer with the aim of routing from frontend to backend services, one domain to one deployment.
The issue is that when I'm saving the load balancer the backend services I've defined are suddenly both pointing to the same port. Which results in both defined domains pointing to the same service.
https://i.imgur.com/q2tfbFY.png
This is how it's setup, with two backend services.
https://i.imgur.com/sBaRsdd.png
This is how the host and path rules are defined.
https://i.imgur.com/JGt7aco.png When editing the "Port numbers" in the "first-backend-service" and saving the load balancer, the port numbers in the "second-backend-service" will be changed to the same as was defined in the "first-backend-service".
I've tried using two load balancers, one for each service with the same result.

You might be using the same named port for all the backend services. The instance group comes with the default Named port. As your are using same name port, when you are changing it reverting back to the configured one.
You can configure your custom named port and map it to your desired port by selecting
Instance group --> details-->edit group
using 'add item' you can add port name and port number as per your requirement and later use it in the backend services. Edit the "Port name" and "Port numbers" numbers.
So for your scenario you can create different port name with different ports number in your instance group and apply one each to the backend services:
http1: 3000
http2: 3001

Related

AWS - ELB - Routing http/https traffic to a custom port of EC2 instance

I've an application up and running on and EC2 instance at port 5000. I've been trying to add either application load balancer or classic load balancer to route my traffic to this application.
Until at this point, the application is available over HTTP protocol at http://example.com:5000/.
So my question is, what steps I need to do to make this application available without typing the port number in the URL.
Please note that I want to have multiple instances of the app up and running at different ports and are mapped to different subdomains.
Thanks
So after spending couple of hours and going through the documentation again, this is how it worked for me.
Created an Application load balancer
Created a Target Group that listens on HTTP port 80.
In this target group, selected the ec2 instance and registered it on port 5000
In the load balancer section, added two listeners. One for HTTP and one for HTTPs. Added default action to forward all traffic to that Target Group that was created in step 2. and it all worked for me.
The important bit was to set up the Target Group in step 2 and 3 correctly. I was creating two target groups for http and https separately which was incorrect. I just had to creat one target group for http only.

Is it possible to run multiple web instance in the same AWS EC2?

Background
I have followed this tutorial https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-cli-tutorial-ec2.html, composed a docker compose file, made a website A (compose of 4 containers) up and run serving 1 of my client.
However, now I have another client which I need to host another web site website B using similar strategies as above.
Here is the current running service of ECS / EC2
and here are the containers up and running, serving website A now
Questions & concerns
The website A is now situated as 1 of a service in the EC2 under my only cluster, can I use the same EC2 instance and run website B (as another service of the EC2)?
If so, how are the ports / inbound / outbound traffic being managed? Now website A already occupies port 80, 443, 27017 and 3002 of the EC2 instance for inbound traffic, if website B's containers also run in the same EC2 instances, can I still use port 80, 443, 27017 and 3002 for website B. I have read the docs of ALB (Amazon Load Balancer), seems it can fulfill the requirement, am I at the right track?
And the domain name, through route 53, I have registered a domain www.websiteA.com to serve the 1st website, I have also registered another www.websiteB.com preparing to serve website B, in my case, I guess I need to configure the new domain B pointing to the same EC2 IP?
During my deployment of website B, I do not want to affect the availability of website A, can it be maintained during the process of deploying website B's containers?
I want to clear all the concepts before kick-starting to deploy the website B, appreciate for any help, thank you
Follow-up actions
I come up decided to use AWS application load balancer to solve my issue, and have the following configurations setup.
I first look into load balancer
And configured as follows
I setup a load balancer which listens for requests using HTTP protocol with incoming port 80, whenever there are users access the web server (i.e.: the frontend container), listener will forward that request to the target group (i.e.: http-port-80-access)
And here is the target group (http-port-80-access) which contains a registered target (currently my ec2 instance running the containers), the host port of the container is 32849 which in turn made used by the associated load balancer (web-access-load-balancer) for dynamic port mapping.
I have also configured 1 more rule on top of the default rule, whenever user access url of websiteA, load balancer will forward the request to the target group (http-port-80-access).
All things set, and the healthy test also passed. I then used the following ecs-cli compose service up command to wire up the load balancer with the service
ecs-cli compose --file ./docker-compose-aws-prod.yml --cluster my-ecs-cluster-name --ecs-profile my-ecs-profile --cluster-config my-cluster --project-name my-project --ecs-params ./ecs-params.yml service up --target-group-arn arn:aws:elasticloadbalancing:us-east-2:xxxxxxxxx:targetgroup/http-port-80-access/xxxxxxxx --container-name frontend --container-port 80
where frontend is the service name of the frontend container of website A
However, turn out when I access www.websiteA.com through browser, nothing but ERR_CONNECTION_REFUSED, accessing www.websiteA.com:32849 did accessible, but is not what I desired.
I am wondering which part I configured wrongly
If you are sending traffic directly to the instance then you would have to host on a different port. You should consider using an ALB, which would allow you to use dynamic ports in ECS. The ALB can accept traffic from ports 80 and 443 for different domains and route the traffic to different containers based on things like the domain.
The website A is now situated as 1 of a service in the EC2 under my only cluster, can I use the same EC2 instance and run website B (as another service of the EC2)?
Indeed. However - as you already found out, you have to split the traffic based on something (hostname, path,..). That's where the reverse-proxy comes in play (either managed - ALB, NLB or your own - nginx, haproxy,.. ) .
It's simple for the http traffic (based on the host)
If so, how are the ports / inbound / outbound traffic being managed? Now website A already occupies port 80, 443, 27017 and 3002 of the EC2 instance for inbound traffic, if website B's containers also run in the same EC2 instances, can I still use port 80, 443, 27017 and 3002 for website B.
assuming the ports 27017 and the 3002 are using own binary protocol (not http). You will have handle that.
You can in theory define the port mapping (map different public listening port to these custom ports), but then you need to either use NLB (network load balancer) or expose the ports on hosts public IP. In the latter case I'm not sure with ECS you can guarantee which IP is used (e.g. having multiple worker nodes)
I have read the docs of ALB (Amazon Load Balancer), seems it can fulfill the requirement, am I at the right track?
ALB is layer 7 reverse proxy (http), it is imho the best option for the web access, not for binary protocols.
, I guess I need to configure the new domain B pointing to the same EC2 IP?
that's the plan
During my deployment of website B, I do not want to affect the availability of website A, can it be maintained during the process of deploying website B's containers?
shouldn't be a problem
Run website B on different ports. To allow end users to interact with website B without specify port numbers use a reverse-proxy. See AWS CloudFront.

how to set ports for GCP load balancer

Three of Node.js web server are all listing on port 3000, how can I set port configuration(backend and frontend) for load balancer?
I set backend port 3000, frontend 80, but it's not working. I tried to use iptable to redirect 80 to 3000 in the instance, it didn't work. How can I set the load balancer ports?
Did you set url_map to direct traffic to different backend services?
You mentioned that there were three web servers, were they served as an identical service? If not, you need to define them separately. One backend service for one web server. For example, set webserver A as backend service A, and webserver B as backend service B ... etc.
You could define port for each backend service, which is about which port you would like the traffic to be directed from instance group to each instance.
Simply speaking, if three web servers are all different, you need to...
Define three ports for three web servers on the instance group
Set corresponding firewall-rules to open required ports on each instance
Run your web server on each instance on specified ports
map the traffic to correct backend server with url-map
default front end with 80 port should work okay, if needed, you could build a 443 front end to provide HTTPS with automatically renewed SSL by Google
Above mentioned steps you could easily find on Google Cloud Console.
If you would like to know how each component on GCP LB in detail, you could refer to this article
- you could only read the concept of how instance and instance group and backend service connect from each other.

How to make a specific port publicly available within AWS

I have my React website hosted in AWS on https using a classic load balancer and cloudfront but I now need to have port 1234 opened as well. When I currently browse my domain with port 1234 the page cannot be displayed. The reason I want port 1234 opened as this is where my nodeJs web server is running for React to communicate with.
I tried adding port 1234 into my load balancer listener settings although it made no difference. It's noticeable the load balancer health check panel seems to only have one value which is currently HTTP:80/index.html. I assume the load balancer can listen to port 80 and 1234 (even though it can only perform a health check on one port number)?
Do I need to use action groups or something else to open up the port? Please help, any advice much appreciated.
Many thanks,
Load balancer settings
Infrastructure
I am using the following
EC2 (free tier) with the two code projects installed (React website and node server on the same machine in different directories)
Certificate created (using Certificate Manager)
I have created a CloudFront Distribution and verified it using email. My certificate was selected in the cloud front as the customer SSL certificate
I have a classic load balancer (instance points to my only EC2) and the status is InService. When I visit the load balancer DNS name value I see my React website. The load balancer listens to HTTP port 80. I've added port 1234 but this didn't help
Note:
Please note this project is to learn AWS, React and NodeJs so if things are strange please indicate
EC2 instance screenshot
Security group screenshot
Load balancer screenshot
Target group screenshot
An attempt to register a target group
Thank you for having clarified your architecture.
I woud keep CloudFront out of the game now and be sure your setup works with just the load balancer. When everything will be configured correctly, you can easily add Cloudfront as a next step. In general, for all things in IT, it is easier to build a simple system that is working and increase complexity one step at a time rather than debugging a complex system that does not work.
The idea is to have an Application Load Balancer with two listeners, one for the web (TCP 80) and one for the API (TCP 123). The ALB will have two target groups (one for each port on your EC2 instance) and you will create Listeners rules to forward the correct port to the correct target groups. Please read "Application Load Balancer components" to understand how ALBs work.
Here are a couple of thing to check
be sure you have two listeners and two target group on your Application Load Balancer
the load balancer must be in a security group allowing TCP 80 and TCP 1234 from anywhere (0.0.0.0/0) (let's say SG-001)
the EC2 instance must be in a security group allowing TCP connections on port 1234 (for the API) and 80 (for the web site) only from source SG-001 (just the load balancer)
After having written all this, I realise you are using Classic Load Balancer. This should work as well, just be sure your EC2 instance has the correct security group (two rules, one for each port)

Google Cloud Load Balancer different ports

Under Load Balancer,
I have two domains
www.xyz.com
search.xyz.com
and on Google cloud (one of the VM), I have apache running on port 80, and nodejs running on 8080.
I want to create two backends to the same group with different ports (one of them to apache and on of them to nodejs),
if host name matches forward to different backend
for eg.
www.xyz.com should goto backend host port 80
search.xyz.com should goto backend host port 8080
I tried added backends in console, however it keeps overwriting other.
I had the same issue and solved it by using different port names for the service.
This issue is described in detail in the Load Balancer documentation, under Restrictions and guidance for instance groups:
If your instance group serves two or more ports for several backends respectively, you have to specify different port names in the instance group.
It's easy to overlook, but when you create a backend service, you're asked to name the port. The good news is that you can rename the port easily.