I am running docker-compose with node:4.2.1-wheezy
and dnsdock
containers.
I have DOCKER_OPTS="--dns 172.17.42.1"
inside /etc/default/docker.
When I run node -e "require('dns').resolve('host_name_here')"
inside my node.js container the host is resolved correctly through the 172.17.42.1 dns server.
But when I run node -e "require('dns').lookup('host_name_here')"
it fails with ENOTFOUND
error.
And the problem is that http.request
uses dns.lookup
instead of dns.resolve
.
The docs say that dns.lookup
calls getaddrinfo
. And as far as I understand getaddrinfo
caches /etc/resolv.conf and maybe it caches empty /etc/resolv.conf (but cat /etc/resolv.conf
prints nameserver 172.17.42.1
).
I really have no idea how to resolve this issue. What can cause such behavior?
Update 1.
docker -v
Docker version 1.7.1, build 786b29d
docker-compose -v
docker-compose version: 1.4.2
Update 2.
I updated all things to the latest versions (docker 1.9.0, docker-compose 1.5.0 and node up to 5.0.0) but the issue still persists.
So this is the docker-compose.yml that reproduces the issue:
dnsdock:
image: tonistiigi/dnsdock
volumes:
- /var/run/docker.sock:/run/docker.sock
ports:
- "172.17.42.1:53:53/udp"
environment:
- DNSDOCK_ALIAS=dns.org
node:
image: node:5.0.0-wheezy
command: node -e "setTimeout(function () { var dns = require('dns'); dns.resolve('dns.org', console.log.bind(console, 'resolve')); dns.lookup('dns.org', console.log.bind(console, 'lookup')); }, 5000)"
dns: 172.17.42.1
You should replace 172.17.42.1
with IP of your docker0 interface. The setTimeout(..., 5000)
is needed because node
container may start before dnsdock
.
This is my docker-compose up
output:
Creating test_node_1
Creating test_dnsdock_1
Attaching to test_node_1, test_dnsdock_1
dnsdock_1 | 2015/11/07 09:29:44 Added service: 3653951cff40c06c04b9ab3f5d2fc94ccc19305eaac7ba1a545ce1dbab3e3e17 {test_dnsdock_1 dnsdock 172.17.42.3 -1 [dns.org]}
dnsdock_1 | 2015/11/07 09:29:44 Added service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140 {test_node_1 node 172.17.42.2 -1 []}
node_1 | resolve null [ '172.17.42.3' ]
node_1 | lookup { [Error: getaddrinfo ENOTFOUND dns.org]
node_1 | code: 'ENOTFOUND',
node_1 | errno: 'ENOTFOUND',
node_1 | syscall: 'getaddrinfo',
node_1 | hostname: 'dns.org' }
dnsdock_1 | 2015/11/07 09:29:49 Stopped service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140
test_node_1 exited with code 0
For a better dns lookup, you could consider using a network overlay, as presented in "Docker Overlay Networks: That was Easy"
It uses a KV (Key/Value) store bases on Consul, and a swarm cluster where you can register your nodes.
You can the build an overlay network
eval "$(docker-machine env --swarm c0-master)"
docker network create -d overlay myStack1
And use it to run an image:
docker run -d --name web --net myStack1 nginx
docker run -itd --name shell1 --net myStack1 alpine /bin/sh
Both of these containers will be attached to the same network, and be discoverable by container name (regardless of start order).
Further, when a container is restarted it will remain discoverable without cascading restarts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With