I don't understand how to ping a service running in Docker Swarm which is deployed in global mode. Let's say I have 2 nodes in my Swarm cluster (example below). I deploy some service in global mode, so 2 instances running on its own node. Both services expose the same port like in the example below.
version: '3.7'
services:
cadvisor:
image: google/cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- 8080:8080
networks:
- monitor-net
deploy:
mode: global
restart_policy:
condition: on-failure
networks:
monitor-net:
I run another container on the same network and I try to ping the services. Docker can resolve the service by its service name:
root@bdc091e9f4d1:/# ping cadvisor
PING cadvisor (10.0.16.165) 56(84) bytes of data.
64 bytes from 10.0.16.165 (10.0.16.165): icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from 10.0.16.165 (10.0.16.165): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from 10.0.16.165 (10.0.16.165): icmp_seq=3 ttl=64 time=0.044 ms
But it just chooses one of the services. How can I reach one from each node ? I tried to use the hostname
services:
cadvisor:
image: google/cadvisor
hostname: "{{.Node.Hostname}}.{{.Service.Name}}"
It sets the hostname
as expected. docker container inspect ...
"Config": {
"Hostname": "node01.mon_cadvisor",
"Domainname": "",
"User": "",
"AttachStdin": false,
If I ping node01.mon_cadvisor
, Docker doesn't seem to resolve the address of the service by its hostanme
So how to do it ?
What you observed is not limited to global mode deployments. A deployed service will default to use deploy.endpoint_mode: vip.
In endpoint_mode: vip the service will use a virtual ip. The service name will resolve to the ip of the virtual ip. The vip is responsible to balance traffic to the containers.
The only thing wrong in your "ping test" was the expectation. If you put the default vip behavior into account, it makes sense why you observed what you observed.
if you deploy your service with endpoint_mode: dnsrr name resolution will return the container ips in round robin mode. Even if you stick with endpoint_mode: vip, you can force dnsrr behavior by communicating to tasks.{servicename} instead of the servicename... in your case this would be tasks.cadvisor.