Background
We're trying to run a test suite against a fairly complex application stack in a docker-compose setup. So far, everything is working nicely. However, we'd like to make sure we're not missing any external dependencies or accidentally poking anything we shouldn't (such as production systems).
This seems like what the internal network option is basically for.
Problem
When using internal: true on the compose network, the containers are not able to access any outside hosts as expected. So far, so good. The problem is that attemps to resolve hostnames that don't exist inside the composed network take a long time to timeout. A gethostbyname() call can take up to 40 seconds to fail which breaks the application stack in all kinds of ways.
I'd like to be able to configure the DNS setup in the network to simply give me an immediate NXDOMAIN for any name that isn't a container in the network, but so far I haven't found any indication that this is even possible. This seems like an obvious use-case and I have a hard time believing I'm the first to hit this problem...
I've googled high and low and gone over whatever documentation I could find but so far, no luck.
Minimal Test Setup
Given a docker-compose.yml:
version: '3'
networks:
default:
internal: true
services:
foo:
image: debian:latest
command: /bin/sleep 1000000000
bar:
build:
context: ./bar
command: /bin/true
And bar/Dockerfile:
FROM debian:latest
RUN apt-get update && apt-get install -y dnsutils bind9-host netcat-openbsd
Then:
$ docker-compose up -d
Creating network "foo_default" with the default driver
Creating foo_bar_1 ... done
Creating foo_foo_1 ... done
$ docker-compose run bar bash
root@f7f6bf6b65d4:/# time nslookup foo
Server: 127.0.0.11
Address: 127.0.0.11#53
Non-authoritative answer:
Name: foo
Address: 192.168.96.3
real 0m0.010s
user 0m0.004s
sys 0m0.000s
root@f7f6bf6b65d4:/#
Instant answer. So far, so good.
But:
root@f7f6bf6b65d4:/# time nslookup foo.example.com 127.0.0.11
;; connection timed out; no servers could be reached
real 0m15.009s
user 0m0.004s
sys 0m0.004s
root@f7f6bf6b65d4:/#
Bad. Was hoping for an instant NXDOMAIN response.
Even worse:
root@f7f6bf6b65d4:/# time getent hosts foo.example.com
real 0m40.034s
user 0m0.000s
sys 0m0.000s
root@f7f6bf6b65d4:/#
As mentioned, this breaks our stack in a bunch of ways and slows down test runs a lot.
For reference, the container's /etc/resolv.conf is:
nameserver 127.0.0.11
options ndots:0
And /etc/nssswitch.conf is:
passwd: compat
group: compat
shadow: compat
gshadow: files
hosts: files dns
networks: files
protocols: db files
services: db files
ethers: db files
rpc: db files
netgroup: nis