Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aacebedo/dnsdock
DNS service discovery for Docker containers
https://github.com/aacebedo/dnsdock
Last synced: 5 days ago
JSON representation
DNS service discovery for Docker containers
- Host: GitHub
- URL: https://github.com/aacebedo/dnsdock
- Owner: aacebedo
- License: mit
- Created: 2014-08-20T18:22:31.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2024-06-06T19:38:38.000Z (5 months ago)
- Last Synced: 2024-08-01T12:23:46.333Z (3 months ago)
- Language: Go
- Size: 1.39 MB
- Stars: 604
- Watchers: 22
- Forks: 92
- Open Issues: 17
-
Metadata Files:
- Readme: readme.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-starred - aacebedo/dnsdock - DNS service discovery for Docker containers (others)
README
![Build Status](https://github.com/aacebedo/dnsdock/actions/workflows/main.yml/badge.svg)
## dnsdock
DNS server for automatic docker container discovery. Simplified version of
[crosbymichael/skydock](https://github.com/crsbymichael/skydock).This project was initially created and maintained by [tonistiigi](https://github.com/tonistiigi).
#### Differences from skydock
- *No raft / simple in-memory storage* - Does not use any distributed storage
and is meant to be used only inside single host. This means no ever-growing
log files and memory leakage. AFAIK skydock currently does not have a state
machine so the raft log always keeps growing and you have to recreate the
server periodically if you wish to run it for a long period of time. Also the
startup is very slow because it has to read in all the previous log files.- *No TTL heartbeat* - Skydock sends heartbeats for every container that reset
the DNS TTL value. In production this has not turned out to be reliable. What
makes this worse it that if a heartbeat has been missed, skydock does not
recover until you restart it. Dnsdock uses static TTL that does not count down.
You can override it for a container and also change it without
restarting(before updates). In most cases you would want to use TTL=0 anyway.- *No dependency to other container* - Dnsdock does not use a separate DNS
server but has one built in. Linking to another container makes recovery from
crash much harder. For example skydock does not recover from skydns crash even
if the crashed container is restarted.- A records only for now.
- No support for Javascript plugins.
- There’s a slight difference in a way image names are extracted from a
container. Skydock uses the last tag set on image while dnsdock uses the
specific tag that was used when the container was created. This means that if a
new version of an image comes out and untags the image that your container
still uses, the DNS requests for this old container still work.#### Build
There are two ways to build the tool
##### Building with devbox:
Install [devbox](https://www.jetpack.io/devbox) on your host and execute the following commands:
```
$> devbox run test
$> devbox run --env GOARCH=[amd64|arm] build
```##### Building using a devcontainer:
Install [VSCode devcontainer
extension](https://code.visualstudio.com/docs/devcontainers/containers)
or [devpod](https://www.devpod.io) and execute the following commands:
```
$> go get ./...
$> mkdir -p build && GOARCH=[amd64|arm] go build -o build/dnsdock ./cmd/dnsdock
```#### Usage
Dnsdock connects to Docker Remote API and keeps an up to date list of running
containers. If a DNS request matches some of the containers their local IP
addresses are returned.Format for a request matching a container is:
`....`.- `environment` and `domain` are static suffixes that are set on startup. Defaults to `docker`.
- `image-name` is last part of the image tag used when starting the container.
- `container-name` alphanumerical part of container name.You can always leave out parts from the left side. If multiple containers match
then they are all returned. Wildcard requests are also supported.```
> dig *.docker
...
;; ANSWER SECTION:
docker. 0 IN A 172.17.0.5
docker. 0 IN A 172.17.0.3
docker. 0 IN A 172.17.0.2
docker. 0 IN A 172.17.0.7> dig redis.docker
...
;; ANSWER SECTION:
redis.docker. 0 IN A 172.17.0.3
redis.docker. 0 IN A 172.17.0.2> dig redis1.redis.docker
...
;; ANSWER SECTION:
redis1.redis.docker. 0 IN A 172.17.0.2> dig redis1.*.docker
...
;; ANSWER SECTION:
redis1.*.docker. 0 IN A 172.17.0.2
```##### OSX Usage
Original tutorial: http://www.asbjornenge.com/wwc/vagrant_skydocking.html
If you use docker on OSX via Vagrant you can do this to make your containers
discoverable from your main machine.In your Vagrantfile add the following to let your virtual machine accept
packets for other IPs:```ruby
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
end
```Then route traffic that matches you containers to your virtual machine internal IP:
```
sudo route -n add -net 172.17.0.0
```Finally, to make OSX use dnsdock for requests that match your domain suffix
create a file with your domain ending under `/etc/resolver` (for example
`/etc/resolver/myprojectname.docker`) and set its contents to `nameserver
172.17.0.1`.##### coreos-vagrant usage
You can autostart the dnsdock service in the `user-data` file of coreos-vagrant.
Everytime you `vagrant up` this CoreOs vagrant instance the dnsdock service
will be running and start discovering your other services.Add the following snippet under the `units` part:
```
- name: dnsdock.service
enable: true
command: start
content: |
[Unit]
Description=dnsdock
After=docker.service
Requires=docker.service[Service]
EnvironmentFile=/etc/environment
ExecStartPre=/bin/sh -c '/usr/bin/docker rm -f dnsdock || ls > /dev/null'
ExecStartPre=/bin/sh -c '/usr/bin/docker pull aacebedo/dnsdock'
ExecStart=/usr/bin/docker run -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p ${COREOS_PRIVATE_IPV4}:53:53/udp aacebedo/dnsdock
ExecStop=/bin/sh -c '/usr/bin/docker stop dnsdock || ls > /dev/null'
```##### Container images usage
DNSDock is also available as [official docker images](https://hub.docker.com/r/aacebedo/dnsdock).
There are several images for different processor architectures:
- amd64
- armSimply add the architecture to the requested tag.
#### Setup
DNS listening port needs to be bound to the *docker0* inferface so that its
available to all containers. To avoid this IP changing during host restart add
it to the docker default options.- If you use systemd (present on Fedora and recent Ubuntu versions), edit
`/lib/systemd/system/docker.service` and add the options to the command you
will see in the `ExecStart` section, the run `sudo systemctl daemon-reload`.
- If you do not, Open file `/etc/default/docker` and add `--bip=172.17.0.1/24
--dns=172.17.0.1` to `DOCKER_OPTS` variable.Restart docker daemon after you have done that (`sudo service docker restart`).
Now you only need to run the dnsdock container:
```
docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dnsdock -p 172.17.0.1:53:53/udp aacebedo/dnsdock [--opts]
```- `-d` starts container as daemon
- `-v /var/run/docker.sock:/var/run/docker.sock` shares the docker socket to
the container so that dnsdock can connect to the Docker API.
- `-p 172.17.0.1:53:53/udp` exposes the default DNS port to the docker0 bridge interface.Additional configuration options to dnsdock command:
```
--dns=":53": Listen DNS requests on this address
--docker="unix://var/run/docker.sock": Path to the docker socket
--domain="docker": Domain that is appended to all requests
--environment="": Optional context before domain suffix
--help: Show this message
--http=":80": Listen HTTP requests on this address
--nameserver="8.8.8.8:53": DNS server for unmatched requests
--ttl=0: TTL for matched requests
--verbose: Verbose output
--tlsverify: enable mutual TLS between dnsdock and Docker
--tlscacert="$HOME/.docker/ca.pem": Path to CA certificate
--tlscert="$HOME/.docker/cert.pem": Path to client certificate
--tlskey="$HOME/.docker/key.pem": Path to client certificate private key
--all: Process all container even if they are stopped
--forcettl: Change TTL value of responses coming from remote servers
```If you also want to let the host machine discover the containers add `nameserver 172.17.0.1` to your `/etc/resolv.conf`.
##### SELinux and Fedora / RHEL / CentOS
Mounting docker daemon’s unix socket may not work with default configuration on
these platforms. Please use [selin-dockersock](https://github.com/dpw/selinux-dockersock) to fix this.
More information in [#11](https://github.com/aacebedo/dnsdock/issues/11).##### TLS Authentication
Instead of connecting to the Docker daemon’s UNIX socket, you may prefer to
connect via a TLS-protected TCP socket (for example, if you are running Swarm).
The `-tlsverify` option enables TLS, and the three additional options
(`-tlscacert`, `-tlscert` and `-tlskey`) must also be specified. Alternatively,
you may set the `DOCKER_TLS_VERIFY` environment variable to a non-empty value
and the `DOCKER_CERTS` to a directory containing files named `ca.pem`,
`cert.pem` and `key.pem`.You may build this into your own container with this example Dockerfile:
```
FROM aacebedo/dnsdockENV DOCKER_TLS_VERIFY 1
ENV DOCKER_CERTS /certsCMD ["-docker=tcp://172.17.0.1:2376"]
```Use a volume (`-v /path/to/certs:/certs`) to give the container access to the
certificate files, or build the certificates into the image if you have access
to a secure private image registry.##### HTTP Server
For easy overview and manual control dnsdock also includes HTTP server that
lets you configure the server using a JSON API.```
# show all active services
curl http://dnsdock.docker/services# show a service
curl http://dnsdock.docker/services/serviceid# add new service manually
curl http://dnsdock.docker/services/newid -X PUT --data-ascii '{"name": "foo", "image": "bar", "ip": "192.168.0.3", "ttl": 30}'# remove a service
curl http://dnsdock.docker/services/serviceid -X DELETE# change a property of an existing service
curl http://dnsdock.docker/services/serviceid -X PATCH --data-ascii '{"ttl": 0}'# set new default TTL value
curl http://dnsdock.docker/set/ttl -X PUT --data-ascii '10'
```##### Overrides from ENV metadata (DEPRECATED)
If you wish to fine tune the DNS response addresses you can define specific
environment variables during container startup. This overrides the default
matching scheme from container and image name.Supported ENV variables are `DNSDOCK_NAME`, `DNSDOCK_IMAGE`, `DNSDOCK_ALIAS`, `DNSDOCK_TTL`.
```
docker run -e DNSDOCK_NAME=master -e DNSDOCK_IMAGE=mysql -e DNSDOCK_TTL=10 \
--name mymysql mysqlimage
# matches master.mysql.docker
``````
docker run -e DNSDOCK_ALIAS=db.docker,sql.docker -e DNSDOCK_TTL=10 \
--name mymysql mysqlimage
# matches db.docker and sql.docker
```##### Overrides with docker labels
If you wish to fine tune the DNS response addresses you can define specific labels during
container creation. This overrides the default matching scheme from container and image name.Supported labels are `com.dnsdock.ignore`, `com.dnsdock.alias`, `com.dnsdock.name`, `com.dnsdock.tags`, `com.dnsdock.image`,
`com.dnsdock.ttl`, `com.dnsdock.region`, and `com.dnsdock.ip_addr````
docker run -l com.dnsdock.name=master -l com.dnsdocker.image=mysql -l com.dnsdock.ttl=10 \
--name mymysql mysqlimage
# matches master.mysql.docker
``````
docker run -l com.dnsdock.alias=db.docker,sql.docker -l com.dnsdock.ttl=10 \
--name mymysql mysqlimage
# matches db.docker and sql.docker
```Service metadata syntax by [progrium/registrator](https://github.com/progrium/registrator) is also supported.
```
docker run -l com.dnsdock.tags=master -l com.dnsdock.name=mysql -l com.dnsdock.region=us2 \
--name mymysql mysqlimage
# matches master.mysql.us2.docker
```If you want dnsdock to skip processing a specific container set its
`com.dnsdock.ignore` label.You can force the value of the IP address returned in the DNS record with the
`com.dnsdock.ip_addr` label. This can be useful if you have a reverse proxy such as traefik in a container with mapped port and you want to redirect your clients to the front server instead of an internal docker container ip address.---
#### Lots of code in this repo is directly influenced by skydns and skydock. Many thanks to the authors of these projects.