diff --git a/Dockerfile b/Dockerfile index 8099848..2b4bf3e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ FROM jgoodall/ubuntu-confd -MAINTAINER "John Goodall " +MAINTAINER ian@blenke.com ENV DEBIAN_FRONTEND noninteractive @@ -34,4 +34,4 @@ ADD supervisord.conf /etc/supervisor/supervisord.conf EXPOSE 6000 6222 -CMD ["/run.sh"] \ No newline at end of file +CMD ["/run.sh"] diff --git a/README.md b/README.md index 2b7a3af..64e49f8 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,11 @@ Docker image of [twemproxy](https://github.com/twitter/twemproxy) proxy server i ## Overview -The container reads the redis server information from [etcd](https://github.com/coreos/etcd). The twemproxy container will use [confd](https://github.com/kelseyhightower/confd) to watch the `/services/redis` path. It exposes port 6000, so map that when you do `docker run`. +If available, the container will poll the redis server information from [etcd](https://github.com/coreos/etcd) or [consul](https://consul.io). + +If `ETCD_HOST` or `CONSUL_HOST` are present, the twemproxy container will use [confd](https://github.com/kelseyhightower/confd) to watch the `/services/redis` path. It exposes port 6000, so map that when you do `docker run`. + +If you pass a different `PORT` environment variable than 6000, that will be used to populate the `/services/twemproxy/port` path in `etcd` or `consul`, and twemproxy will listen on that port. When you start your redis containers, put their connection information into `etcd` in the `/services/redis/`: @@ -18,6 +22,27 @@ You also need to set the port that you want twemproxy to run on: Finally, define the `etcd` peer `confd` should use as an [environment variable](https://docs.docker.com/reference/run/#env-environment-variables) using `-e ETCD_HOST=:` when you do the `docker run` to start the container. +If you are running a coreos fleet for docker, you should be able to use the etcd on the docker0 interface on each host by specifying: + + ETCD_HOST=172.17.42.1 + +If you spin up a cluster of [docker-consul](https://github.com/progrium/docker-consul), the `CONSUL_HTTP_PORT` (default 8500) will be used to detect a consul server: + + CONSUL_PORT_8500_TCP_ADDR=10.10.100.10 + +This will automatically set the `CONSUL_HOST` at the IP address pointed to above, allowing for an automatic consul linkage discovery. + +Neither etcd nor consul is required for this docker image to function. + +If there are any environment variables for [docker linked containers](https://docs.docker.com/userguide/dockerlinks/) on the `REDIS_PORT` (default 6379). You can set this simulate this linkage manually by setting the environment variables: + + REDIS1_PORT_6379_TCP_ADDR=10.10.100.11 + REDIS2_PORT_6379_TCP_ADDR=10.10.100.12 + +If you redefine the `REDIS_PORT` environment variable, be sure to update the port 6379 references in the above variables as well for proper linked container detection. + +On startup, a twemproxy yaml config file will be created pointing to them, and etcd or consul will be automatically populated as well. This means you can use environment variables and avoid having to use etcdctl manually to register new redis servers if you wish. + ## Usage You may want to customize the twemproxy configuration in `confd/templates/twemproxy.tmpl` - particularly the `hash_tag` option. diff --git a/run.sh b/run.sh index cd6072f..78611d0 100644 --- a/run.sh +++ b/run.sh @@ -1,12 +1,57 @@ #!/bin/sh +setkey () { + true +} # Run docker run with -e ETCD_HOST=: if [ -n "${ETCD_HOST:+x}" ]; then mv /etc/supervisor/supervisord.conf /tmp/supervisord.conf - sed -e "/confd -node/s/127.0.0.1:4001/${ETCD_HOST}/" /tmp/supervisord.conf > /etc/supervisor/supervisord.conf + sed -e "/confd -node/s/127.0.0.1:4001/${ETCD_HOST}/" -e 's/autostart=false/autostart=true/' /tmp/supervisord.conf > /etc/supervisor/supervisord.conf + setkey () { + curl -X PUT -d value="$2" -L "http://${ETCD_HOST}/v2/keys/$1" + } + curl -L "http://${ETCD_HOST}/v2/keys/services/twemproxy" -XPUT -d dir=true + curl -L "http://${ETCD_HOST}/v2/keys/services/redis" -XPUT -d dir=true +fi +# Auto-detect a consul linked container +for var in $(env | cut -d= -f1 | grep -e "_PORT_${CONSUL_HTTP_PORT:-8500}_TCP_ADDR"); do + export CONSUL_HOST=$(eval echo \$${var}) +done +# Run docker run with -e CONSUL_HOST=: +if [ -n "${CONSUL_HOST}" ]; then + mv /etc/supervisor/supervisord.conf /tmp/supervisord.conf + sed -e "s/confd -node=\"http://127.0.0.1:4001\"/-consul -consul-addr ${CONSUL_HOST}/" -e 's/autostart=false/autostart=true/' /tmp/supervisord.conf > /etc/supervisor/supervisord.conf + setkey () { + curl -X PUT -d "$2" "http://${CONSUL_HOST}:${CONSUL_HTTP_PORT:-8500}/v1/kv/$1" + } +fi + +# Remember the port this twemproxy will be using +setkey services/twemproxy/port "${PORT:-6000}" + +# Are there any linked containers? +if [ -n "$(env | cut -d= -f1 | grep -e _PORT_${REDIS_PORT:-6379}_TCP_ADDR)" ]; then + cat < /twemproxy.yaml +situ: + listen: 0.0.0.0:${PORT:-6000} + hash: fnv1a_64 + hash_tag: "P:" + distribution: ketama + auto_eject_hosts: false + timeout: 1000 + redis: true + servers: +EOF + for var in $(env | cut -d= -f1 | grep -e "_PORT_${REDIS_PORT:-6379}_TCP_ADDR"); do + addr=$(eval echo \$${var}) + port=${REDIS_PORT:-6379} + echo " - ${addr}:${port}:1" >> /twemproxy.yaml + key=$(echo $var | sed -e 's/_PORT.*$//') + setkey "services/redis/${key}" "${addr}:${port}" + done fi # for debugging cat /etc/supervisor/supervisord.conf -/usr/bin/supervisord -c /etc/supervisor/supervisord.conf \ No newline at end of file +/usr/bin/supervisord -c /etc/supervisor/supervisord.conf diff --git a/supervisord.conf b/supervisord.conf index b44bdb7..5b40c40 100644 --- a/supervisord.conf +++ b/supervisord.conf @@ -5,7 +5,7 @@ nodaemon = true command=/confd -node="http://127.0.0.1:4001" -verbose=true -debug=true priority=10 numprocs=1 -autostart=true +autostart=false autorestart=true stdout_events_enabled=true stderr_events_enabled=true