ECS - communication between tasks - load-balancing

I am trying to deploy 2 containers on 2 different tasks (1 container per task), one is my frontend and the other is my backend server. I am trying to figure out how to configure the communication between them.
I saw that a load balancer in a service is a good option. However, should I configure load balancer for my front end server and another one for my backend? Meaning each time I have public-facing services and private services I need 2 load balancers?
I would like to only expose my front-end to the public internet and my backend will remain private (although I make API requests to the outside world - probably need to configure outbound route too?).
I would highly appreciate any information.

No you don't need a private LB for that. It is an option you can use but ECS has since introduced the concept of Service Discovery for back-end services. The idea is that your front end is exposed to your users via a standard LB (e.g. ALB) but services that are being called by the front end and that run behind the scene can be addressed using this service discovery mechanism (based on Route53/CloudMap).
You can see an example of this concept here. This CFN template gives you the details re how you can build this layout.

Related

Verify Load balancing Azure Container Service

I am using the Azure Container Service with Kubernetes orchestrator and have an app deployed on a cluster with 3 nodes. It has 5 replicas. How can I verify load balancing in action e.g. I want to be able to see that every time I hit the external IP I am being routed to perhaps a different node. Thanks.
The simplest solution is to connect (over ssh for example) to 3 nodes and run WinDump there. In order everything is working properly you will be able to see what happens on every node.
Also here is Microsoft documentation for testing a load balancer:
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/tutorial-load-balancer#test-load-balancer
The default Load Balancer which are available to your Windows Azure Web and Worker roles are software load balancers and not so much configurable however they do work in Round Robin setting. If you want to test this behavior this is what you need to do:
Create two (or more) instances of your service with RDP access
enabled so you can RDP to both instances
RDP to your both instances and run NETMON or any network monitor
solution in it.
Now access your Windows Azure web application from your desktop You
need to understand that when a network connection is made from your
desktop the connection is still alive based on network settings
(default 60 seconds) so you need to wait until default timeout is
passed to access your Windows Azure web application again.
When you will access your Windows Azure Web application again you can
verify that seconds time the request went to next instance. BE sure
to pass the connection timeout otherwise your request will be keep
handled by same instance.
Note: If you dont want to use RDP, you sure can also create a test ASP.NET page to write some special code based on your specific instance which will show you that this page is specific to certain instance. The best way to do is to read the Instance ID as below:
int instanceID = RoleEnvironment.CurrentRoleInstance.Id;
If you want to have more control over Windows Azure Load Balancing, i would suggest using the Windows Azure Traffic Manager which will help you to route the traffic to your site via Round-Robin, Performance or backup based scenario. More info on using Traffis Manager is in this article.

How to run an async WCF service in the cloud in a serverless, auto scaling manner

I need to run the services in a "auto-scaling" manner. ie. as load increases, I need it to create more of these services. I can use a cloud based load balancer to handle the routing of the messages from 1 to many instances.
Would hosting this in IIS (and somehow doing the port sharing etc) work?

Load Balancing with the WSHttp Binding: Do not use reliable sessions? WHY?

We have WCF service X: deployed on server A and Server B, host address:
http://127.0.0.1:8777/ServiceX/
And we load balance the two servers. We accesss the service via http://myappserver/ServiceX
We need to use per-session mode, and we set [reliable sessions] as true:
We don't find any issue till now based on testing. But the below linked MSDN article says that Do not use reliable sessions for Load Balancing with the WSHttp Binding? Please can someone give more details? Thanks a lot.
WCF Load Balancing http://msdn.microsoft.com/en-us/library/ms730128.aspx
Reliable Messaging means all your messages from your established client reach the same endpoint behind any intermediaries like routers and load balancers.
Load balancing means your calls will be distributed across all nodes as the load balancer sees fit.
Those two goals are mutually exclusive. You can have one or the other, not both.
I have not had time to try this myself yet, but I found this old blog entry (https://blogs.msdn.microsoft.com/drnick/2007/07/13/sticky-sessions/):
This division according to groups would allow a feature like reliable messaging to work because the same server would be used to process all of the messages in the reliable session. The feature that this division method represents is typically called “sticky sessions” or some other phrase for affinitization in the load balancer.
Given that you mention that your firewall supports sticky sessions, I suspect/hope you will be fine.

Can Cloudbees instances within an app communicate directly?

I am looking to build an Akka-based application in the cloud, for a garage startup that I'm bootstrapping; by the nature of the app, it's semi-stateful, with as much as possible cached in RAM for performance. (It'll be tolerant of being shut down and restarted periodically, but we want to mostly operate via cached information inside the Actors.)
The architecture is designed for a cluster of servers, communicating between them as necessary so that a user session on node A can query a middleware Actor on node B when appropriate. So my question is, how hard is that in CloudBees?
My understand from this page is that there is no automatic directory service to manage this sort of intra-cluster communication yet, but I can probably live with that -- worse comes to worst, I should be able to manage discovery via the DB, with each node registering itself when it comes up and opening up many-to-many communications with the others.
What I want to check, though, is that this communication is straightforward. Does each node have a reliable local IP that it can advertise for others to contact it on, that is at least stable during this run of the application? Or is there another/better way for a node to advertise its address to the rest of the nodes running this app?
(I assume that the nodes of an app all share the same DB instance.)
Any guidance here would be greatly appreciated. I'd like to choose a hosting provider soon, and keep returning to CloudBees as the most promising-looking of the options...
There are no limitations currently on instances communicating with each other - the trick is in discovering membership. There is an api that will be shortly be released that will allow you to track membership - but for now, the following may work:
To get the port, look at the file names in $PWD/.genapp/ports (as applications can have multiple ports) - (eg System.getenv("PWD") + ".genapp/ports" - list the files in that directory - generally will be just 1 - the file name is the port). There are other ways - for example the "sun.java.command" system property on JVM apps too.
The hostname can be obtained via the usual means (eg InetAddress.getLocalHost().getHostName()): this host
name will be the private name - ie it will resolve to a private IP -
good for node to node communication.
Public IP/hostname: perform a HTTP get (from the server) to the following URL:
http://instance-data/latest/meta-data/public-hostname (will only
return the public IP on the server side of course).
(see http://developer-blog.cloudbees.com/2012/11/finding-port-or-address-of-your.html)
You can then, as you say, on startup, register the appropriate port/private hostname with a DB, and then read that on each node to "seed" the cluster (akka doesn't have to know about all members - just enough seeds) I would think a 2 phase startup: 1: register host/port, 2, look for other members, add them as seed members to the local Akka configuration (may need to periodically do the same for a while, as other nodes startup - to ensure it is seeded enough)
From my reading of Akka setup here: http://doc.akka.io/docs/akka/snapshot/scala/remoting.html
It looks like you can specify the port - so if possible, I would set that to be the app_port environment variable - that means each node can communicate via the private hostname with that port. However, http traffic will also be routed to it - can akka handle this as well - or does it need to have a discrete port for akka and another for any http interface?

WCF Intermediary to enable calls between 2 endpoints behind routers without router configuration

I'm developing a synchronization service using WCF and Sync Framework, and I have it working when the endpoints can communicate directly.
The next step I need to implement is to synchronize 2 endpoints where they both are behind routers and the router ip is changing constantly. I am thinking about a publicly available intermediary that should forward the calls between the 2 endpoints. My biggest problem is that I cannot rely on the users to configure the port forwarding on routers so I cannot directly open a connection from the other endpoint or the intermediary.
My idea is based on FogCreek's CoPilot, and other remote assistance solutions (LogMeIn, TeamViewer, etc) which works without any router configuration.
How would you implement it?
You need something like relay in Azure. I would try implement it this way:
Your intermediary will provide two operations:
Push - client will call this operation when publishing new data for synchronization. Data will be stored on service until other client downloads them.
Pull - client will call this operation regulary to download any published data stored on intermediary.
Routers with changing IP should not be a problem, because client will be always initiating connection.
If you are not limited to HTTP protocol you can implement this with Net.Tcp binding and use duplex communication. In such case your intermediary will be able to forward synchronized data immediately. But this solution can have additional complexity when dealing with sessions and connections.