We want to know what algorithm the Docker mesh uses to route requests to containers. Here's why:
We deploy our applications to self-hosted docker swarms. We use the docker routing mesh to direct traffic to the individual nodes, like this:
- internet ->
- firewall ->
- load director (nginx) ->
- nginx "least connection" routing to three swarm managers ->
- docker mesh ->
- Any of the six app containers running on three different non-manager docker nodes
Our developers suspect that the docker mesh is routing traffic round robin, which could result in some app containers being overloaded with slow requests while other containers are under-utilized. If the devs are right, we should not use the docker mesh and instead should use the load director to direct traffic to the individual containers using a smarter algorithm than round robin.
On the other hand, if the docker mesh is keeping track of how many requests are in flight to each container and delivering traffic to the container with the fewest requests, then we do not need to do the work of bypassing the docker mesh.
The question
What algorithm does the docker mesh use to direct traffic to available containers? Is it simple round robin?
Our nginx config
Our nginx receives traffic from the internet and proxies it to the docker mesh on any of the three docker manager nodes:
upstream document_service {
least_conn;
server dockermgr1.nosuchdomain:8402;
server dockermgr2.nosuchdomain:8402;
server dockermgr3.nosuchdomain:8402;
}
server {
...
proxy_pass http://document_service;
Our docker-compose config
The docker-compose file configures the service to have six replicas on the three docker runner nodes:
version: "3.4"
services:
documentsservice:
image: ${IMAGE_LOCATION}documents_service/documentsservice:prod-${COMPOSE_BUILD_TAG:-latest}
container_name: documentsservice
ports:
- "8402:80"
...
deploy:
replicas: 6
placement:
constraints: [node.role != manager]
resources:
limits:
memory: 1024MB
update_config:
parallelism: 1
order: start-first
failure_action: continue
Versions
- docker-ce 5:19.03.12~3-0~debian-buster
- nginx-full 1.14.2-2+deb10u4
- docker-compose: 1.27.4
Mesh routing is most likely round robin only
I took a dive into the docker source. I found references to various routing methods, but the only one that appears to be used is round robin. I also found a question on the docker forum that seems to confirm that mesh routing is round-robin only.
Examining the source
In vendor/github.com/moby/ipvs/constants.go is this interesting list of routing strategies:
However the only one of these constants that is every used is RoundRobin:
Although this was a very cursory look at the source, I found no obvious means of configuring the routing mode to be anything other than RoundRobin.
A related question on the docker forums
A question on the docker forum seems to confirm that the only routing method available to the mesh is round robin:
https://forums.docker.com/t/configure-swarm-mode-routing-mesh-load-balancing-method/75413
The answer was: