1

We have a multiservice architecture consisting of HAProxy front end ( we can change this to another proxy if required), a mongodb database, and multiple instances of a backend app running under Docker Swarm.

Once an initial request is routed to an instance ( container ) of the backend app we would like all future requests from mobile clients to be routed to the same instance. The backend app uses TCP sockets to communicate with a VoIP PBX.

Ideally we would like to control the number of instances of the backend app using the replicas key in the docker-compose file. However if a container died and was recreated we would require mobile clients continue routing to the same container. The reason for this is each container is holding state info.

Is this possible with Docker swarm? We are thinking each instance of the backend app when created gets an identifier which is then used to do some sort of path based routing.

tech74
  • 1,609
  • 1
  • 20
  • 39
  • Do you want that clients to stick to the same backend instance or that ALL clients should be routed to a single instance? For example do you want that clients A and B should be routed to instance 1 and clients B and C to instance 2? – Constantin Galbenu Oct 17 '18 at 06:36
  • Hi Constantin Thanks for the reply. If client A got routed to instance 1 on first request by the load balancer we want client A to stick to instance 1. if client B got routed to instance 2 it should stick with instance 2. The clients are iOS and Android apps and are using https requests using API calls not browser. – tech74 Oct 17 '18 at 08:17
  • Do the clients have the possibility of storing cookies? – Constantin Galbenu Oct 17 '18 at 08:26
  • Yes, its a mobile app so it can store data for any length of time. – tech74 Oct 17 '18 at 08:28

1 Answers1

1

HAproxy has what you need. This article explains all.

As a conclusion of the article, you may choose from two solutions: IP source affinity to server and Application layer persistence. The latter solution is stronger/better than the first but it requires cookies.

Here is an extras from the article:

IP source affinity to server

An easy way to maintain affinity between a user and a server is to use user’s IP address: this is called Source IP affinity. There are a lot of issues doing that and I’m not going to detail them right now (TODO++: an other article to write). The only thing you have to know is that source IP affinity is the latest method to use when you want to “stick” a user to a server. Well, it’s true that it will solve our issue as long as the user use a single IP address or he never change his IP address during the session.

Application layer persistence

Since a web application server has to identify each users individually, to avoid serving content from a user to an other one, we may use this information, or at least try to reproduce the same behavior in the load-balancer to maintain persistence between a user and a server. The information we’ll use is the Session Cookie, either set by the load-balancer itself or using one set up by the application server.

What is the difference between Persistence and Affinity

Affinity: this is when we use an information from a layer below the application layer to maintain a client request to a single server

Persistence: this is when we use Application layer information to stick a client to a single server

sticky session: a sticky session is a session maintained by persistence

The main advantage of the persistence over affinity is that it’s much more accurate, but sometimes, Persistence is not doable, so we must rely on affinity.

Using persistence, we mean that we’re 100% sure that a user will get redirected to a single server. Using affinity, we mean that the user may be redirected to the same server…

Affinity configuration in HAProxy / Aloha load-balancer

The configuration below shows how to do affinity within HAProxy, based on client IP information:

frontend ft_web
  bind 0.0.0.0:80
  default_backend bk_web
backend bk_web
  balance source
  hash-type consistent # optional
  server s1 192.168.10.11:80 check
  server s2 192.168.10.21:80 check

Session cookie setup by the Load-Balancer The configuration below shows how to configure HAProxy / Aloha load balancer to inject a cookie in the client browser:

frontend ft_web
  bind 0.0.0.0:80
  default_backend bk_web
backend bk_web
  balance roundrobin
  cookie SERVERID insert indirect nocache
  server s1 192.168.10.11:80 check cookie s1
  server s2 192.168.10.21:80 check cookie s2
Constantin Galbenu
  • 16,951
  • 3
  • 38
  • 54
  • Hi Constantin Thanks for this. We can't use IP affinity method as mobile app can change IP address all time and we want to maintain this 'stickiness' across multiple opens and closes of the app, so the mobile device may connect to different IP networks. – tech74 Oct 17 '18 at 08:42
  • @tech74 Ok, then use a Session cookie – Constantin Galbenu Oct 17 '18 at 08:43
  • The session cookie method is more promising but our mobile apps use https API calls not browser, so how is cookie injected into a browser when there isn't one. Would we receive the cookie from the first request and insert into all subsequent API calls? – tech74 Oct 17 '18 at 08:44
  • @tech74 yes, exactly I'm almost sure that your programming language/framework lets you do that. – Constantin Galbenu Oct 17 '18 at 08:47
  • OK great. One final thing, if the backend Docker container restarts for whatever reason, we plan for it to reread the database to retrieve its state. But how will requests be routed to the newly created container which may be on a different machine. Is there a way of relating a Docker container Id to the session cookie – tech74 Oct 17 '18 at 08:51
  • @tech74 Haproxy sends the requests to the right container **if it has the same IP/DNS name**. But if the container is down for too long then the clients will get redirected to another container – Constantin Galbenu Oct 17 '18 at 09:11
  • Ok so it looks like we just need containers to keep DNS name across restarts – tech74 Oct 17 '18 at 09:27