From 78e3341de6d53886207aeb2500243adc15eb27d5 Mon Sep 17 00:00:00 2001 From: Jeff Lindsay Date: Mon, 1 Sep 2014 17:28:16 -0500 Subject: [PATCH] adding health check stuff for docker world --- Dockerfile | 5 +++++ README.md | 28 ++++++++++++++++++++++++++-- check-cmd | 13 +++++++++++++ check-http | 23 +++++++++++++++++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100755 check-cmd create mode 100755 check-http diff --git a/Dockerfile b/Dockerfile index 027672b..0e506ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,17 @@ RUN cd /bin && unzip /tmp/consul.zip && chmod +x /bin/consul && rm /tmp/consul.z ADD https://dl.bintray.com/mitchellh/consul/0.3.1_web_ui.zip /tmp/webui.zip RUN cd /tmp && unzip /tmp/webui.zip && mv dist /ui && rm /tmp/webui.zip +ADD https://get.docker.io/builds/Linux/x86_64/docker-1.2.0 /bin/docker +RUN chmod +x /bin/docker + RUN opkg-install curl bash ADD ./config /config/ ONBUILD ADD ./config /config/ ADD ./start /bin/start +ADD ./check-http /bin/check-http +ADD ./check-cmd /bin/check-cmd EXPOSE 8300 8301 8301/udp 8302 8302/udp 8400 8500 53/udp VOLUME ["/data"] diff --git a/README.md b/README.md index 409e1a4..a745ae0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This project is a Docker container for [Consul](http://www.consul.io/). It's a s ## Getting the container -The container is very small (26MB virtual, based on [Busybox](https://github.com/progrium/busybox)) and available on the Docker Index: +The container is very small (50MB virtual, based on [Busybox](https://github.com/progrium/busybox)) and available on the Docker Index: $ docker pull progrium/consul @@ -108,7 +108,7 @@ And the third host with an IP of 10.0.1.3: That's it! Once this last node connects, it will bootstrap into a cluster. You now have a working cluster running in production on a private network. -## Opinionated Configuration +## Special Features #### Runner command @@ -154,6 +154,30 @@ To use this convenience, you simply wrap the `cmd:run` output in a subshell. Run $ $(docker run --rm progrium/consul cmd:run 127.0.0.1 -it) +#### Health checking with Docker + +Consul lets you specify a shell script to run for health checks, similar to Nagios. As a container, those scripts run inside this container environment which is a minimal Busybox environment with bash and curl. For some, this is fairly limiting, so I've added some built-in convenience scripts to properly do health checking in a Docker system. + +These all require you to mount the Docker socket with `-v /var/run/docker.sock:/var/run/docker.sock` when you run the Consul container. + +##### Using check-http + + check-http [curl-args...] + +This utility performs `curl` based HTTP health checking given a container ID or name, an internal port (what the service is actually listening on inside the container) and a path. You can optionally provide extra arguments to `curl`. + +The HTTP request is done in a separate ephemeral container that is attached to the target container's network namespace. The utility automatically determines the internal Docker IP to run the request against. A successful request will output the response headers into Consul. An unsuccessful request will output the reason the request failed and set the check to critical. By default, `curl` runs with `--retry 2` to cover local transient errors. + +##### Using check-cmd + + check-cmd + +This utility performs the specified command in a separate ephemeral container based on the target container's image that is attached to that container's network namespace. Very often, this is expected to be a health check script, but can be anything that can be run as a command on this container image. For convenience, an environment variable `SERVICE_ADDR` is set with the internal Docker IP and port specified here. + +##### Using docker + +The above health check utilities require the Docker binary, so it's already built-in to the container. If neither of the above fit your needs, and the container environment is too limiting, you can perform Docker operations directly to perform a containerized health check. + #### DNS This container was designed assuming you'll be using it for DNS on your other containers. So it listens on port 53 inside the container to be more compatible and accessible via linking. It also has DNS recursive queries enabled, using the Google 8.8.8.8 nameserver. diff --git a/check-cmd b/check-cmd new file mode 100755 index 0000000..f4540e5 --- /dev/null +++ b/check-cmd @@ -0,0 +1,13 @@ +#!/bin/bash + +main() { + local container_id="$1"; shift + local port="$1"; shift + local cmd="$@" + + local image="$(docker inspect -f "{{.Config.Image}}" $container_id)" + local ip="$(docker inspect -f "{{.NetworkSettings.IPAddress}}" $container_id)" + docker run --rm --net container:$container_id -e "SERVICE_ADDR=$ip:$port" $image "$cmd" +} + +main $@ \ No newline at end of file diff --git a/check-http b/check-http new file mode 100755 index 0000000..8497937 --- /dev/null +++ b/check-http @@ -0,0 +1,23 @@ +#!/bin/bash + +readonly IMAGE="progrium/consul" + +main() { + local container_id="$1"; shift + local port="$1"; shift + local path="$1"; shift + local opts="$@" + + local ip="$(docker inspect -f "{{.NetworkSettings.IPAddress}}" $container_id)" + local curl_cmd="curl \ + --silent \ + --show-error \ + --fail \ + --dump-header /dev/stderr \ + --retry 2 \ + $opts \ + http://$ip:$port$path > /dev/null" + docker run --rm --net container:$container_id --entrypoint "/bin/bash" $IMAGE -c "$curl_cmd" +} + +main $@ \ No newline at end of file