10

I'm playing with deploying services in a Docker Swarm. I'm having trouble letting a container consistently connect to a container on a different node.

Let's say I'm building a GlusterFS pool; I need to open a terminal in each container and add the gluster daemon to the pool. How do I refer to other containers in the pool? Currently I'm using an IP address, but what if a container dies and is recreated? As far as I know there's no guarantee that the new container will have the same IP address. I could use the embedded DNS server to refer to the other containers, but I can only seem to resolve container names and container IDs to IP addresses, and both of those will change if a container dies and is recreated, so there's no point.

Shouldn't I be able to resolve the hostnames of the other containers to their IP addresses? I assumed it would, but it doesn't.

Are there any solutions to my conundrum? (I get the sense that I might be going about using services all wrong, and that in this case I should manually create a container on each node.)

Hubro
  • 6,016

1 Answers1

10

Depending on your exact situation, you have to use different solutions:

Intra-service hostname resolution

Problem: You have multiple containers (/replicas) of the same service serviceX, e.g.:

  • container a1b3d130275a with hostname serviceX.1.nq4rjbae
  • container 65040b1cada6 with hostname serviceX.2.m9wl1f1r
  • container 944704427b9e with hostname serviceX.3.3d08baql

Now, you want to retrieve the hostname of the second (serviceX.2.m9wl1f1r) and the third (serviceX.3.3d08baql) container from within container one ( serviceX.1.nq4rjbae).

Docker provides a solution called container discovery using a DNS query against tasks.$serviceName, e.g.:

nslookup tasks.serviceX
[...]
Name:      tasks.serviceX
Address 1: 10.0.0.205 a1b3d130275a  (<- resolved locally by /etc/hosts)
Address 2: 10.0.0.206 serviceX.2.m9wl1f1r
Address 3: 10.0.0.207 serviceX.3.3d08baql

There are also discussions on making serviceX.{1,2,3} resolvable and therefore creating predictable hostnames.¹ ² ³ ⁴ But by now, none of these is implemented, so this solution only works at runtime.

Note: Setting the hostname using the template feature (like docker service create ... --hostname {{.Service.Name}}.{{.Task.Slot}}) would make the hostnames locally predicatable, but they won't be resolvable by other containers.

Inter-service hostname resolution

Problem: You have mutliple containers of the different services serviceX, serviceY. But only one container per service, e.g.:

  • container a1b3d130275a with hostname serviceX.1.nq4rjbae
  • container 65040b1cada6 with hostname serviceY.2.m9wl1f1r

And you want to connect to a container of another service (serviceX) from one service (serviceY) and vice versa. You only have to use the --name parameter:

docker service create --name=serviceX serviceX
docker service create --name=serviceY serviceY

And you can rely that container a1b3d130275a will be resolvable by hostname serviceX and container 65040b1cada6 by hostname serviceY.

Reference:

Murmel
  • 1,325