Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

FROM jgoodall/ubuntu-confd

MAINTAINER "John Goodall <jgoodall@ornl.gov>"
MAINTAINER ian@blenke.com

ENV DEBIAN_FRONTEND noninteractive

Expand All @@ -34,4 +34,4 @@ ADD supervisord.conf /etc/supervisor/supervisord.conf

EXPOSE 6000 6222

CMD ["/run.sh"]
CMD ["/run.sh"]
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<instance>`:

Expand All @@ -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=<host>:<port>` 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.
Expand Down
49 changes: 47 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,57 @@
#!/bin/sh

setkey () {
true
}
# Run docker run with -e ETCD_HOST=<ip>:<port>
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=<ip>:<port>
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 <<EOF > /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
/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
2 changes: 1 addition & 1 deletion supervisord.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down