So I have a docker engine (version 1.12.6, build 78d1802) running in an Ubuntu host.
I created initiated a swarm using
docker swarm init --advertise-addr 192.168.1.2
I have a locally prebuilt image using which I create a service called nodeapp as follows
docker service create --name nodeapp --publish 3000:3000 --replicas 2 node-app-image
Now when I type curl localhost:3000
I get the expected proper response and everything works up to this point.
This document and many others I referred seem to suggest that docker v1.12.x has inbuilt load balancing / routing via either DNS or VIP methods.
So I'm trying to access my service via service name or virtual ip as follows
curl nodeapp:3000
to which I get curl: (6) Could not resolve host: nodeapp
and
curl 10.255.0.6:3000
to which I get curl: (7) Failed to connect to 10.255.0.6 port 3000: Connection timed out
Note that I used the following command to obtain the virtual ip
docker service inspect --format {{.Endpoint.VirtualIPs}} nodeapp
which yields [{boq3g7s47w47q2ej56li9s3dw 10.255.0.6/16}]
Why can't I access my service using the VIP or Service Name even though I can access it using localhost:3000?
From this page:
By default, when you create a service attached to a network, the swarm assigns the service a VIP. The VIP maps to a DNS alias based upon the service name. Containers on the network share DNS mappings for the service via gossip so any container on the network can access the service via its service name.
So it appears that dns resolution will only work between containers, and not on the host (by default at least, I assume there would be a way to configure the dns on the host to resolve these services).
For example, create a service running nginx:
docker service create \
--replicas 3 \
--name my-web \
--network my-network \
nginx
View the service:
$ docker service ps my-web
NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
my-web.1.63s86gf6a0ms34mvboniev7bs nginx node1 Running Running 58 seconds ago
my-web.2.6b3q2qbjveo4zauc6xig7au10 nginx node2 Running Running 58 seconds ago
my-web.3.66u2hcrz0miqpc8h0y0f3v7aw nginx node3 Running Running about a minute ago
Create a new service/container:
$ docker service create \
--name my-busybox \
--network my-network \
busybox \
sleep 3000
View the container:
$ docker service ps my-busybox
NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
my-busybox.1.1dok2cmx2mln5hbqve8ilnair busybox node1 Running Running 5 seconds ago
Enter the container:
$ docker exec -it my-busybox.1.1dok2cmx2mln5hbqve8ilnair /bin/sh
From within the container, you can resolve the nginx service:
$ nslookup my-web
Server: 127.0.0.11
Address 1: 127.0.0.11
Name: my-web
Address 1: 10.0.9.2 ip-10-0-9-2.us-west-2.compute.internal