PCF - exposing routes of each application instance - cloud-foundry

I have a manifest.yml as follows
applications:
- MY-APP
instances:3
...
PCF starts application correctly with 3 instances which are hidden after one static route my-app.<pcfhost>.com. Is there a way to expose routes of each application instance with manifest.yml properties? e.g. my-app-1.<pcfhost>.com, my-app-2.<pcfhost>.com, my-app-3.<pcfhost>.com

If you deploy your app to Cloud Foundry and scale it to three instances, a component called Route-Emitter that watches the Diego runtime service would discover there are three instances of an application, the IP and ports for these instances, and the route for this app (e.g. myapp.cf.com). Route-Emitter sends a registration message to NATS, and Gorouter receives the registration message (it is subscribed to NATS). Requests for myapp.cf.com will now be load balanced across the three instances of your application. Router uses a basic round-robin approach to load balancing between application instances, and this algorithm can not be directly modified.
If you are using Cloud Foundry, this is all taken care of for you automatically. Thus you cannot assign the routes to each instance.
You can reach individual instances of an application using the X-Cf-App-Instance header: https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#surgical-routing

Related

Fargate - How do I make an API call to another container within the same task definition

When developing locally, I run docker-compose, where I have two services Service1 and Service2. Service2 depends on Service1. When I deploy them to ECS, I create them within one task definition and provide JSON array of container definitions to spin them up.
When I run them locally, within docker-compose, from Service2 I can call http://Service1:8080/v1/graphql (since they're in docker-compose together I can call it by the service name) ... however, when I deploy to ECS and I make that same API call, I get a 404.
Based on this: Docker links with awsvpc network mode I've also tried http://localhost:8080/v1/graphql ... I'd appreciate any help!
I'd try service discovery as mentioned here:
Amazon ECS now includes integrated service discovery. This makes it possible for an ECS service to automatically register itself with a predictable and friendly DNS name in Amazon Route 53. As your services scale up or down in response to load or container health, the Route 53 hosted zone is kept up to date, allowing other services to lookup where they need to make connections based on the state of each service.
See an example here.

Polyglot and Client Side Load Balancing

With the Cloud Foundry Feature, "Polyglot" for integrated Service Discovery and direct communication between service containers through the internal routes, How does the Load Balancing work? Is Cloud Foundry taking care of the Load Balancing? Is there a way to utilize Client Side Load Balancing, something like Ribbon on top of this Polyglot enabled communication?
When you are using container to container networking...
If you connect directly to IP addresses, no load balancing is done.
If you use the platform's DNS based polyglot service discovery, then you will get limited load balancing via round-robin DNS.
With the polyglot service discovery feature, DNS responses are rotated so that IPs are listed in different orders in the response. You can observe/validate this by doing the following:
Map an internal route to an app
Scale the same app up to have two or more instances
Run cf ssh into any app container
Inside the container, run dig <internal-route>
Repeat the last step any number of times. You should see the response from DNS come back with IP addresses in a different order (they are rotated).
That said, there is nothing to stop you from using a different form of load balancing be that a reverse proxy app you have deployed or something client side like Ribbon.

How to expose just one microservice from kubernetes cluster outside for existing load balancer and other services - only within cluster

Hello and thanks in advance.
First I want to provide some context to make answering my question easier.
We are using Google Cloud.
We got to a situation when our needs to be able to deploy updates easily for various parts of application bumped into our monolith architectures limitations.
Our app is not super big, but it already has 2 physical services - backend (scope being updated), and caching server which caches data and makes search in a mongo-like way over data from Google Datastore.
We have 2 options here.
"plugins" - like nanoservices running within same process which are developed in a way that these nanoservices do not know they are on the same process, all they know is a set of "plugins shell API" injected at activation of a nanoservice code. This shell gives the nanoservice access to a database, logging, configuration, routes registration, control events like refresh pages map and some metadata like website root url and root of static content deployed as supply stuff for a service version. Like https://static.server.com/deployments/foo/v2
standard microservices on kubernetes where same API mentioned exposed to each service via "shell client" package deployed as part of container image.
In short, this is a common "infrastructure vs library" dilemma, often mentioned in articles about microservices i read.
For library approach I have some vision already on how to implement all that including hot modules replacement without stopping server but the more i read about kubernetes the stronger I feel that I am inventing kubernetes (or similar) wheel.
How I imagine that:
1) there is a router service which is single service exposed outside from the cluster. When a page is requested, and this service attached to the load balancer we already have as backend.
It will handle authentication/authorization of outside requests, and pick the page to be rendered or API endpoint to be invoked. When a page requested, the related template is loaded, and data for pre-rendering is picked by calling related endpoint exposed by module service. When public API endpoint is picked, the matching service endpoint is called.
There are few services, including:
caching service (that service which deployed now at separate servers group, and what
updates service, which process the module services version switch and provides API to do so via some UI for admins.
modules services (one per modules). Each module exposes endpoints for providing preloaded pages data, endpoint to give list of pages routes to be registered, API endpoints implementations, and endpoint to list exposed API routes to be invoked through router service.
router service which process external requests and dispatch them across other services when appropriate using cached routes map, updated in case if one of internal services broadcasts pages map refresh event, e. g. updates service.
What is stopping me from starting to use kubernetes right away is the lack of knowledge about how to implement the following scenarios:
1) only 1 microservice must be exposed outside cluster, the "routing service".
2) reuse builtin services discovery etc to communicate with services within cluster like caching server.
3) Cluster's router service would be attached to cloud load balancer we already have as a backend.
In my opinion, you should have a look at NGINX Ingress Controller to build your routing scheme, more information you can find here and here.
EDIT In addition, you can try some other ingress controllers and among them Istio and Traefik definitely worth your attention as alternative solutions to NGINX Ingress Controller.

Cloud Foundry load balancing instances

I have a java servlet app (.war). The app itself is stateless and does only computations. It exposes its functionality via a REST API (implemented using Jersey 2). I am deploying the app on Cloud Foundry with several instances, the result however is that all requests are forwarded to ONLY 1 instance and its always the same one.
The app has a route and I am able to send requests to a particular instance using the X-CF-APP-INSTANCE header, but I would like my instances to balance themselves.
According to Cloud Foundry docs the gorouter should use a round-robin strategy when choosing which instance should serve the request. Am I missing something in the configuration or has anyone experienced behavior like this?
The problem between the two apps was using Jersey's Client with http connection pool (PoolingHttpClientConnectionManager). I created the Client object once at the start as a Spring Bean and have it configured to take free connections from the pool. Removing the pool from the ClientConfig and using freshly created Client objects resulted in the requests being properly load balanced.

Setting up multiple EC2 instances and multiple subdomain under one parent domain in AWS Route 53

I am developing a set of frontend webapps (for instance vaadin or angular) and backend RESTful services. Each frontend webapp will consume one or more of these backend services. I want both webapps and services to be secured over https.
Now, I want to register a single domain, say mydomain.com, and deploy the backend services such that they are available at
service1.api.mydomain.com, service2.api.mydomain.com etc. The frontend apps should be available at webapp1.mydomain.com, webapp2.mydomain.com etc.
I need to be able to setup two or more EC2 instances for the services, and the same for the webapps. For instance, service1 may be running instance A, service2 on instance B, and webapp1 on instance C, and webapp2 on instance D.
How do I configure this setup in AWS Route 53?
Since there is a limit to the max number of Elastic IPs (max 5) that can be allocated for one AWS account, I suppose separate public IPs for all the EC2 instances is not a solution, since I will be having more than 5 such subdomains.
I hope you can provide a practical example configuration with two services and two webapps.
You can submit a request to get the Elastic IP (EIP) limit increased for your account. Small increases (e.g. from 5 to 10) should be fairly quick and easy to obtain. Larger increases should be obtainable if you can justify it to AWS support.
https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-vpc
If you're open to using path-based routing instead of subdomain based (e.g. mydomain.com/app1 and mydomain.com/app1/api) or a mix of the two (e.g. app1.mydomain.com and app1.mydomain.com/api), you could look at using an Application Load Balancer (ALB). You would need one ALB per subdomain used.
http://docs.aws.amazon.com/elasticloadbalancing/latest/application/tutorial-load-balancer-routing.html
Note: I expect subdomain-based routing to be available with the ALB in the future, but it hasn't been released yet.
ALBs could be cheaper than using Classic Elastic Load Balancers (ELBs), but if you're not using the load balancing functionality at all, EIPs may be your best bet since they're free when attached to a running instance.