We have a Java application server running in a container with 2 replicas. Container network stack is Traefik. Additionally we have Apache HTTP Server with GSSAPI module for Kerberos SSO authentication.
Traefik is configured this way:
services:
app:
...
deploy:
mode: replicated
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-public"
- "traefik.http.routers.app.entrypoints=web"
- "traefik.http.routers.app.rule=Host(`www.example.com`) && PathPrefix(`/`)"
- "traefik.http.services.app.loadbalancer.server.port=8080"
- "traefik.http.services.app.loadBalancer.sticky.cookie"
- "traefik.http.services.app.loadBalancer.sticky.cookie.name=AppCookie"
apache:
...
deploy:
mode: replicated
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik-public"
- "traefik.http.routers.apache.entrypoints=web"
- "traefik.http.routers.apache.rule=Host(`www.example.com`) && Path(`/LogIn.form`)"
- "traefik.http.services.apache.loadbalancer.server.port=80"
- "traefik.http.services.apache.loadbalancer.server.port=8080"
- "traefik.http.services.apache.loadBalancer.sticky.cookie"
- "traefik.http.services.apache.loadBalancer.sticky.cookie.name=AppCookie"
Auth mechanism expected to work like this:
- Client access application first time.
- With no session exists application server redirect client to "/LogIn.form".
- Apache receives request for "/LogIn.form" and make GSSAPI negotiation with client.
- Apache proxies authorized request to application server adding X-Remote-User header.
- Application server reply through Apache adding its own JSESSION cookie redirecting to its own application web context.
- Client access application with JSESSION cookie staying authorized within session.
This mechanism works well if Apache can access the same application server the client does. In Kubernetes multiple containers in one pod share network addresses, so Apache proxy login page to http://localhost:8080 and that work as a charm. But Docker Swarm environment is different and I wonder if there is a way to point Apache to the same host it was redirected from.
Which of this approaches can work:
- Since application server is limited to one on the node we can pair Apache instances to application server instances if there is a way to call application server on the same node. Is there any?
- Maybe we can get something from sticky cookie of Traefik to know what host initially was called.
- Maybe Apache can set something to call correct application server via Traefik?
2
Answers
I found the answer in JSESSION cookie which contain internal server name after period.
This make Apache cluster-aware and let it follow the initial host providing JSESSION. Apache now may not be paired to Application container and can always find original Application in cluster environment.
Yes, use a load balancer facing the clients. Load balancers have a feature called "stickiness," which allows a client to connect to the same front end in case of a disconnect.
NGINX might be a good solution. It has a load-balancing capability with an option called Enabling Session Persistence. There are plenty of vendors that provide virtual or physical load balancers with paid maintenance and support for on-premises solutions.
Most cloud providers also have session persistence with their load balancers if this is a cloud solution.