10

I have one Java based web application which is deployed in jboss-10.1.0(wildfly). I am using docker swarm mode(docker version 1.12.1) to scale my application everything works perfectly but the only issue I am facing is session management.

Now let's take scenario.

I have two instance is running for my application(i.e. App1 and App2).I am using default load balancer provided by docker swarm mode with nginx to redirect my application from chintan.test.com:9080 to chintan.test.com:80 so that I don't need to write down port with my url and I am able to access directly with this URL chintan.test.com.

Now the default load balancer is using RR(Round-Robin algorithm) to serve my web request.So first time I visit the chintan.test.com it goes to App1 instance and display login page I login with credentials and everything works perfectly after few minutes it's switch to App2 and again the login page comes.

Is there any way or tools(should be Open-source) through which I handle sessions ? So at least I login to App1 and stick to App1 until I logout.

Thank you!

chintan thakar
  • 1,440
  • 1
  • 15
  • 25
  • 1
    I highly recommend you to do not have stateful applications if you want to scale as you are doing. It's a better solution to store your sessions in a separated component. – Robert Jun 08 '17 at 14:22

3 Answers3

3

Tried using Nginx and HA-Proxy but none of them seems to be work well in SWARM mode. Then I used Traefik in Docker Swarm and it did the trick for me.The only constraint is that Traefik should run on manager node as it needs to be aware of new worker nodes being added or removed. It doesn't require restart also even if you scale up service, add nodes etc.

I have tested the configuration with Docker compose version 3 which is the latest and deployed using Docker stack deploy.Step by step instructions are over here

To start off you need to create a docker-compose.yml (version 3) and add the load balancer Traefik Image. This is how it looks like

   loadbalancer:
image: traefik
command: --docker \
  --docker.swarmmode \
  --docker.watch \
  --web \
  --loglevel=DEBUG
ports:
  - 80:80
  - 9090:8080
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
deploy:
  restart_policy:
    condition: any
  mode: replicated
  replicas: 1
  update_config:
    delay: 2s
  placement:
     constraints: [node.role == manager]

and then the Image for which you need session stickiness

whoami:
image: tutum/hello-world
networks:
  - net
ports:
  - "80"
deploy:
  restart_policy:
    condition: any
  mode: replicated
  replicas: 5
  placement:
    constraints: [node.role == worker]
  update_config:
    delay: 2s
  labels:
    - "traefik.docker.network=test_net"
    - "traefik.port=80"
    - "traefik.frontend.rule=PathPrefix:/hello;"
    - "traefik.backend.loadbalancer.sticky=true"

You can follow this link for a detailed explanation.

Abhishek Galoda
  • 2,753
  • 24
  • 38
  • Sticky sessions don't currently work in traefik with swarm mode: https://github.com/containous/traefik/issues/1024 – BMitch Jun 07 '17 at 09:20
  • I have tested it and it worked for me..Look at their official documentation https://docs.traefik.io/user-guide/swarm-mode/ I have even done the screen capture and uploaded a video. https://www.youtube.com/watch?v=LBG0gnxe7Xc – Abhishek Galoda Jun 08 '17 at 08:31
  • Traefik is no longer doing the http layer load balancing, but docker will do the tcp layer round robin on the next tcp connection. The reason this looks like this works is because the browser keeps the tcp connections open between requests. Curl is a better testing tool for this. https://forums.docker.com/t/swarm-is-not-round-robin-routing-requests/18483/6 – BMitch Jun 08 '17 at 09:25
  • 1
    Traefik uses a cookie name "Traefik_backend" to keep the container IP address and then behind the scenes, I guess it keeps sending the user to the same container over a browser. You are right it won't work on curl as no cookies will be invoked but then we will be selling things to users over browsers and not curl. :P – Abhishek Galoda Jun 08 '17 at 13:22
1

Docker swarm does not currently support sticky sessions, round robin is the only way to reach services by their exposed ports.

To implement sticky sessions, you would need to implement a reverse proxy inside of docker that supports sticky sessions and communicates directly to the containers by their container id (rather than doing a DNS lookup on the service name which would again go to the round robin load balancer). Implementing that load balancer would also require you to implement your own service discovery tool so that it knows which containers are available.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Thank you for answer @bmitch !! Can you please suggest which reverse proxy should I use for sticky session inside my docker swarm to communicate directly to my containers ? – chintan thakar Apr 14 '17 at 07:32
  • Someone wrote an article directly answering Chintan's question and addressing BMitch's comment (the article literally quotes it): http://www.littlebigextra.com/how-to-maintain-session-persistence-sticky-session-in-docker-swarm-with-multiple-containers/ – charlie arehart Feb 17 '21 at 21:00
1

I think the best way to implement sticky sessions in a scaled environment is through database sessions storage. This will untie your application to specific nodes.

I think this is an easier and more cost-effective setup than relying on Docker Enterprise Sticky sessions (https://docs.docker.com/datacenter/ucp/2.2/guides/user/services/use-domain-names-to-access-services/#sticky-sessions).

Of course, this imply a couple of application adjustments like:

  • minimise sessions requests for performances reasons (in particular for anonymous users to avoid DoS)
  • I would store session data in a separate database (not the main application database)
  • Session data should be removed after some time, so you should have some job deleting old session data regularly
  • Etc.

This technique may also provide other benefits:

  • May improve security if you also match user IP's/user agent
  • May improve performances (because a database will be able to avoid disks accesses)

Hope this will help.

Vincent Pazeller
  • 1,448
  • 18
  • 28