DNS
lcp-compose
has an integrated DNS resolver that provides DNS records for the containers in the stack so that they can
be addressed by the containers hostname.
How it works
dns
infrastructure service is the first service an lcp-compose
stack should spin up. DNS service is provided by a
forked version of the resolvable service.
The forked resolvable differs from the original resolvable project in the following ways:
- Modernized the build toolchain, including migrating to
govendor
for 3rd-party dependencies - Allow container aliases to be registered as DNS A record along with hostnames
- Allow adding hostname/aliases to
/etc/host
as oppose to using a DNS resolver
Resolvable is a daemon that listens on the docker domain socket /var/run/docker.sock
for docker engine events. It also
requires the host's /etc/hosts
or /etc/resolv.conf
file being volume mapped into the container, so it can either register
itself as the nameserver (in /etc/resolv.conf
) or change the hosts in the hosts file (/etc/hosts
).
When a container run event is published, resolvable
will grab the container id, inspect on the container, and register
a DNS entry for the container's hostname and aliases. e.g., if the container has hostname orders
,
when the orders service is started, resolvable
will register the following names to the container's ip address:
orders
orders.docker
This allows the host machine the ability to address that container by the above names, e.g., curl http://orders
will
reach the orders container.
When a container is shutdown, a stop
event is published and resolvable will query its internal state for the registered
names by the container id, and remove the entries.
Limitations
Modifying /etc/resolv.conf
is subject to race-condition, i.e., if another process also happens to modify that file.
Modifying hosts file also has that limitation. Even though internally, resolvable
uses mutex to ensure single access
to either /etc/resolv.conf
or /etc/hosts
, it does not prevent an external process from modifying them.
Another caveat regarding inter-container communication: since docker-compose
creates a separate network for the containers
to be run in, containers created outside of the docker-compose network cannot communicate with the networks inside the
network unless you manually run container inside the created docker-compose network or use --net=host
option when
docker run
.
Future considerations
Consider using consul as registry and discovery service. Consul provides a DNS interface, as well
as API for service discovery. It's more versatile than the current resolvable
approach.