5

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.)

  • Are you trying to resolve hostnames for a situation like container A of service X + container B of service Y or for container A of service X + container B of service X? So are you talking about replicas which should be able to connect to each other using their hostnames or is your question about two different services which have to connect to each other? Later should easily be achievable by using the --name option of docker service create – Murmel Jan 30 '18 at 17:26
6

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:

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.