CoursesDocker in depthOrchestration with Swarm

Overlay networks & the routing mesh

Cross-node networking and load balancing.

Advanced12 min · lesson 19 of 30

Services on different nodes talk over an overlay network — a software-defined network spanning the whole swarm via VXLAN encapsulation, so a container on node-1 reaches one on node-2 as if they shared a LAN. You create an overlay on a manager and attach services to it; the swarm extends it to every node that runs a task on it. Add --attachable if you also want standalone containers to join it for debugging.

terminal
$ docker network create -d overlay --attachable appnet
$ docker service create --name api --network appnet registry.internal/api:1.0
$ docker service create --name web --network appnet -p 80:80 registry.internal/web:1.0
# web reaches api by name across nodes: http://api:8080

The routing mesh

When you publish a service port in the default (ingress) mode, the swarm sets up the routing mesh: that port is open on every node, and a request to it on any node — even one running no task for that service — is forwarded to a healthy task somewhere in the swarm. So you can point a plain external load balancer at all node IPs and never track which node hosts which replica.

The routing mesh
1client / LB
hits any node:port
2ingress network
the mesh receives it
3load balance
pick a healthy task
4task
on whichever node it lives
Publish once, reach it on every node; the mesh routes to a running replica wherever it is.

Scenario: bypass the mesh for source IP

A service needs the client’s real source IP (for rate-limiting or logging), but the routing mesh NATs it away. Publish in host mode instead: the port binds directly on the node running the task, preserving the source IP — at the cost of the mesh’s any-node convenience, so you front it with a load balancer that targets only the nodes actually running the task.

terminal
# ingress (default): any node answers, source IP is NATed
$ docker service create --name web --publish published=80,target=80 web:1.0
# host mode: binds on the task’s node only, real client IP preserved
$ docker service create --name web --publish mode=host,published=80,target=80 web:1.0

Internal load balancing and DNS modes

Inside the swarm each service gets a stable virtual IP (VIP); resolving the service name returns the VIP, and the swarm load-balances connections across the healthy tasks behind it — callers use one name and never track task IPs. If you need clients to see the individual task IPs instead (some stateful protocols, custom load balancing), switch the endpoint mode to dnsrr and DNS returns each task address directly.

terminal
$ docker service create --name api --endpoint-mode vip --network appnet api:1.0 # default: one VIP, LB behind it
$ docker service create --name db --endpoint-mode dnsrr --network appnet db:1.0 # DNS returns each task IP
Overlay needs the right ports open between nodes
Swarm overlay networking requires specific ports between every pair of nodes: 2377/tcp for cluster management, 7946/tcp+udp for node discovery, and 4789/udp for the VXLAN data plane. A swarm that forms fine but whose services cannot reach each other across nodes is almost always a firewall blocking 4789/udp or 7946.