Can Docker Swarm use layer 4 (TCP) load balancing with HAproxy or NGINX load balancer instead of using ingress load balancing?
You can use the long syntax for port publishing by explicitlity setting the mode: host
(which override the detault mode: ingress
).
ports:
- target: 80
published: 8080
protocol: tcp
mode: host
This will bypass ingress for the published port (=host port) and the service endpoint, which depending on the endpoint_mode is either a vip ip that balances amongst all healthy target containers or a dnsrr multivalue dns response with the ip of all healty target containers.
Note: as a result the host port will only be bound on the nodes that match the placement constraint of the deployed service (=where a task is actualy running!). Make sure to use node labels and placement constraints that target the node labels, preferably with deploy.mode: global
.
Thank you for your reply…
I’ve tried, but it doesn’t work. Can you help me?
This is what I’ve tried
docker service create --name nginx-Service --mode replicated --replicas 4 --replicas-max-per-node 2 --constraint 'node.role==worker' --network lb-net --endpoint-mode dnsrr nginx:1.23`
haproxy.cfg
global
log fd@2 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
stats socket /var/lib/haproxy/stats expose-fd listeners
master-worker
resolvers docker
nameserver dns1 127.0.0.11:53
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold other 10s
hold refused 10s
hold nx 10s
hold timeout 10s
hold valid 10s
hold obsolete 10s
defaults
timeout connect 10s
timeout client 30s
timeout server 30s
log global
mode tcp
frontend fe_web
bind *:8085
use_backend stat if { path -i /my-stats }
default_backend be_ng_service
backend be_ng_service
balance roundrobin
server-template ng- 4 nginx-Service:80 check resolvers docker init-addr libc,none
backend be_ng_service_wrong_case
balance roundrobin
server-template ng- 4 nginx-service:80 check resolvers docker init-addr libc,none
backend stat
stats enable
stats uri /my-stats
stats refresh 15s
stats show-legends
stats show-node
docker service create --mode global --constraint 'node.role==manager' --name haproxy-lb --network lb-net --publish published=8085,target=80,protocol=tcp,mode=host --mount type=bind,src="$(pwd)"/haproxy-lb/,dst=/etc/haproxy/,ro=true --dns=127.0.0.11 haproxytech/haproxy-debian:2.0
Please wrap you code in Preformated Text block (</> icon) for a better readability.
I am not sure what the objective of your first command is, but at least for me it does not allign with the goal to bypass the ingress routing mesh.
I can not say anything about the haproxy config - never used it and I have no need to use it. I leave this one to someone else to validate.
Your last command on the other hand translates the suggested docker compose v3 elements to docker service create
(not sure if the syntax is correct, as I don’t use swarm without docker stack deploy
) arguments.
Are you sure the mount makes sense? A bind is local to a node - therefore the folder and its content must exist on every node a service task can potentialy be scheduled to. If it’s just about the haproxy conf, then please use docker config
instead, which will be available on all swarm nodes.Note: configs are immutable, if you need to update their config you will have to modify the name and refer to the new config.
May I ask why you feel the need for --dns=127.0.0.11
?