aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKelley Spoon <kelley.spoon@linaro.org>2018-03-02 18:25:22 -0600
committerKelley Spoon <kelley.spoon@linaro.org>2018-03-07 03:34:57 -0600
commit07b8429f06f87b27771d9375764a293c319be761 (patch)
treed301f79bfcb23447f53c0eab8e277e0fb0007854
parent0994aba3a4a5901d70e5439e70715b68c2c56786 (diff)
Dockerfile: Add hostsdns to replace devdns
This change introduces a new image "hostsdns". By mounting the host's docker.sock and /etc/hosts file in the hostdns container, host entries for other containers are added and removed automatically. The "linarodev" compose file has been updated to use "hostsdns" and to remove all traces of custom networking, and the README has been updated with current instructions. Change-Id: I5d929bc5098187e621c3022f69ded6a6b2b75f98
-rwxr-xr-xbuild.sh1
-rw-r--r--hostsdns/Dockerfile25
-rwxr-xr-xhostsdns/event-watcher.py105
-rw-r--r--linarodev/README19
-rw-r--r--linarodev/daemon.json3
-rw-r--r--linarodev/linaro_dev.yml41
6 files changed, 151 insertions, 43 deletions
diff --git a/build.sh b/build.sh
index cee08a7..6c1a2fb 100755
--- a/build.sh
+++ b/build.sh
@@ -2,6 +2,7 @@ docker build -t ansible/baseimage:14.04 -f Dockerfile_trusty . &
docker build -t ansible/baseimage:16.04 -f Dockerfile_xenial . &
docker build -t linaro/login-proxy -f Dockerfile_login_proxy . &
(cd devdns; docker build -t linaro/devdns -f Dockerfile . ) &
+(cd hostsdns; docker build -t linaro/hostsdns -f Dockerfile . ) &
wait
echo "Build complete"
diff --git a/hostsdns/Dockerfile b/hostsdns/Dockerfile
new file mode 100644
index 0000000..6f5a399
--- /dev/null
+++ b/hostsdns/Dockerfile
@@ -0,0 +1,25 @@
+FROM python:2.7.14-alpine3.7
+
+RUN apk add --no-cache bash wget
+
+RUN mkdir /app
+RUN pip install docker
+ADD event-watcher.py /app/event-watcher.py
+RUN chmod 755 /app/event-watcher.py
+
+WORKDIR /app
+ENTRYPOINT ["/app/event-watcher.py" ]
+
+# Create a container that automatically updates
+# the /etc/hosts file on the hosting server when
+# a new container is stopped or started.
+#
+# Requires start with following params:
+# -v /var/run/docker.sock:/var/run/docker.sock
+# -v /etc/hosts:/tmp/hosts
+# The user executing the docker run command must
+# also have read/write perms on /etc/hosts
+#
+# Any container startd with a -e ALIAS arg will have that
+# alias associated with it's IP address. Specify multiple
+# hostnames with comma separated list.
diff --git a/hostsdns/event-watcher.py b/hostsdns/event-watcher.py
new file mode 100755
index 0000000..b51ec76
--- /dev/null
+++ b/hostsdns/event-watcher.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import docker
+import json
+import re
+
+if os.path.exists("/.dockerenv"):
+ print "Found /.dockerenv... reading from /tmp/hosts"
+ HOSTS_FILE="/tmp/hosts"
+else:
+ print "No /.dockerenv found... reading from /etc/hosts"
+ HOSTS_FILE="/etc/hosts"
+
+if os.environ.get("DOCKER_HOST"):
+ client = docker.from_env()
+else:
+ try:
+ client = docker.DockerClient(base_url='unix://var/run/docker.sock')
+ except:
+ print "Sorry, I can't find a dockerd to connect to."
+ sys.exit(1)
+
+def get_ip(c):
+ try:
+ networks = c.attrs.get("NetworkSettings").get("Networks")
+
+ for n in networks:
+ ip = networks[n]["IPAddress"]
+ if ip is not None:
+ return ip
+ except:
+ return None
+
+def get_aliases(c):
+ aliases = []
+ try:
+ envs = c.attrs.get("Config").get("Env")
+
+ for e in envs:
+ m = re.match('ALIAS=(?P<aliases>.*)', e)
+ if m:
+ for a in m.group('aliases').split(','):
+ aliases.append(a)
+ return aliases
+ except KeyError as e:
+ return None
+
+def event_remove(event):
+ container = client.containers.get(event.get("id"))
+ container_remove(container.name)
+
+def event_add(event):
+ container = client.containers.get(event.get("id"))
+ container_add(container.name)
+
+def container_add(name):
+ try:
+ container = client.containers.get(name)
+ except:
+ return
+
+ container_remove(container.name)
+ ip = get_ip(container)
+ if ip:
+ entry = "%s %s" % (ip, container.name)
+ aliases = get_aliases(container)
+ if aliases:
+ entry += " %s" % ' '.join(aliases)
+
+ open(HOSTS_FILE, 'a').write(entry+'\n')
+ print "Added: %s" % entry
+
+def container_remove(name):
+ if name is None and len(name) > 0:
+ return
+ entry = "(.*)\s+%s(.*)" % (name)
+
+ lines = open(HOSTS_FILE, 'r').readlines()
+ outfile = open(HOSTS_FILE, 'w')
+
+ for line in lines:
+ if re.match(entry, line) is None:
+ outfile.write(line)
+ outfile.close()
+
+ print "removed entry for pattern %s" % name
+
+
+### Let's start doing something useful.
+# first, we catch up with any existing containers that are already deployed.
+for container in client.containers.list():
+ container_add(container.name)
+
+# calling events will basically poll forever, so after this we're
+# essentially in not-quite-a-daemon mode
+for event_json in client.events():
+ print "SAW: %s" % str(event_json)
+ event = json.loads(str(event_json))
+
+ if event.get("status") == "start":
+ event_add(event)
+ elif event.get("status") == "kill":
+ event_remove(event)
diff --git a/linarodev/README b/linarodev/README
index 1c7c719..25ea1a9 100644
--- a/linarodev/README
+++ b/linarodev/README
@@ -12,27 +12,16 @@ and save as "environment_vars.sh".
Then run these commands:
-sudo cp daemon.json /etc/docker/daemon.json && sudo systemctl restart docker
source environment_vars.sh
docker-compose -f linaro_dev.yml up
Notes
-----
-The "daemon.json" file will set your internal docker DNS for all
-containers to use those nameservers. If you would like for your
-host system to also use the DNS aliases, add the following line
-to /etc/resolvconf/resolv.conf.d/head:
-
-nameserver 172.12.1.254
-
-And run:
-
-sudo resolvconf -u
-
-The default network is hardcoded to use "172.12.1.0/24" and the
-dnsdev container is hardcoded to use 172.12.1.254. If you need
-to adjust these, they're in the linaro_dev.yml file.
+hostsdns will need read/write permissions on the host's /etc/hosts
+file in order to make changes. You should either only run
+`docker-compose` as root, or ensure that the user you're running
+has rw access on /etc/hosts.
login-proxy will currently fail silently. Looking into making
the entire compose up fail if it doesn't start.
diff --git a/linarodev/daemon.json b/linarodev/daemon.json
deleted file mode 100644
index 58a65ff..0000000
--- a/linarodev/daemon.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "dns": ["172.12.1.254","8.8.8.8","8.8.4.4"]
-}
diff --git a/linarodev/linaro_dev.yml b/linarodev/linaro_dev.yml
index 53ffab1..6351960 100644
--- a/linarodev/linaro_dev.yml
+++ b/linarodev/linaro_dev.yml
@@ -1,31 +1,32 @@
---
version: '3.2'
+#NOTE: this mounts the host's /etc/hosts in the container
+# Be sure you are running as a user who has write
+# access to that file
services:
- devdns:
- image: linaro/devdns
- container_name: devdns
- build: ../devdns
- networks:
- default:
- ipv4_address: 172.12.1.254
- hostname: devdns
+ hostsdns:
+ image: linaro/hostsdns
+ container_name: hostsdns
+ network_mode: bridge
+ build:
+ context: ../hostsdns
+ dockerfile: Dockerfile
volumes:
- - type: bind
- source: /var/run/docker.sock
- target: /tmp/docker.sock
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /etc/hosts:/tmp/hosts
login-proxy:
image: linaro/login-proxy
container_name: login-proxy
+ network_mode: bridge
build:
context: ..
dockerfile: Dockerfile_login_proxy
environment:
- SSH_USER=${SSH_USER:?Please set SSH_USER env var}
- ALIAS=login.linaro.org
- hostname: login
- domainname: linaro.dev
+ hostname: login-proxy
volumes:
- type: bind
source: ${SSH_KEY_PATH:?Please set SSH_KEY_PATH env var}
@@ -36,20 +37,10 @@ services:
trusty-base:
image: ansible/baseimage:14.04
+ network_mode: bridge
container_name: trusty-base
+ environment:
build:
context: ..
dockerfile: Dockerfile_trusty
hostname: trusty
- domainname: linaro.dev
-
-networks:
- default:
- driver: bridge
- driver_opts:
- com.docker.network.bridge.name: linaro_dev
- ipam:
- driver: default
- config:
- -
- subnet: 172.12.1.0/24