From 7457fc50713ac893ead64720a608032cf08428ef Mon Sep 17 00:00:00 2001 From: oxynaut Date: Fri, 6 Mar 2020 16:47:11 +0100 Subject: [PATCH] Add ability to use TCP sockets (TLS only) --- README.md | 17 +++++++++++++++++ docker-entrypoint | 36 +++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ffaab78..708a580 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ This container is a stand-in till there is native support for `--exit-on-unhealt [![](https://images.microbadger.com/badges/version/willfarrell/autoheal.svg)](http://microbadger.com/images/willfarrell/autoheal "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/image/willfarrell/autoheal.svg)](http://microbadger.com/images/willfarrell/autoheal "Get your own image badge on microbadger.com") ## How to use +### UNIX socket passthrough ```bash docker run -d \ --name autoheal \ @@ -18,6 +19,16 @@ docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ willfarrell/autoheal ``` +### TCP socket +```bash +docker run -d \ + --name autoheal \ + --restart=always \ + -e AUTOHEAL_CONTAINER_LABEL=all \ + -e DOCKER_SOCK=tcp://HOST:PORT \ + -v /path/to/certs/:/certs/:ro \ + willfarrell/autoheal +``` a) Apply the label `autoheal=true` to your container to have it watched. b) Set ENV `AUTOHEAL_CONTAINER_LABEL=all` to watch all running containers. @@ -25,6 +36,12 @@ b) Set ENV `AUTOHEAL_CONTAINER_LABEL=all` to watch all running containers. c) Set ENV `AUTOHEAL_CONTAINER_LABEL` to existing label name that has the value `true`. Note: You must apply `HEALTHCHECK` to your docker images first. See https://docs.docker.com/engine/reference/builder/#healthcheck for details. +See https://docs.docker.com/engine/security/https/ for how to configure TCP with mTLS + +The certificates, and keys need these names: +* ca.pem +* client-cert.pem +* client-key.pem ## ENV Defaults ``` diff --git a/docker-entrypoint b/docker-entrypoint index 67f092d..2651600 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -4,27 +4,49 @@ set -e set -o pipefail DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock} +UNIX_SOCK="" CURL_TIMEOUT=${CURL_TIMEOUT:-30} +# only use unix domain socket if no TCP endpoint is defined +case "${DOCKER_SOCK}" in + "tcp://"*) HTTP_ENDPOINT="$(echo ${DOCKER_SOCK} | sed 's#tcp://#https://#')" + CA="--cacert /certs/ca.pem" + CLIENT_KEY="--key /certs/client-key.pem" + CLIENT_CERT="--cert /certs/client-cert.pem" + ;; + *) HTTP_ENDPOINT="http://localhost" + UNIX_SOCK="--unix-socket ${DOCKER_SOCK}" + ;; +esac + # SIGTERM-handler term_handler() { exit 143; # 128 + 15 -- SIGTERM } docker_curl() { - curl --max-time "${CURL_TIMEOUT}" --no-buffer -s --unix-socket "${DOCKER_SOCK}" "$@" || return 1 + curl --max-time "${CURL_TIMEOUT}" --no-buffer -s \ + ${CA} ${CLIENT_KEY} ${CLIENT_CERT} \ + ${UNIX_SOCK} \ + "$@" || return 1 return 0 } trap 'kill ${!}; term_handler' SIGTERM if [ "$1" = 'healthcheck' ]; then - docker_curl --fail http://localhost/_ping + docker_curl --fail "${HTTP_ENDPOINT}/_ping" exit $? fi -if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then - +if [ "$1" = 'autoheal' ]; then + if [ ! -x $UNIX_SOCK ]; then + if [ ! -e "${DOCKER_SOCK}" ]; then + echo "${DOCKER_SOCK} not found" + exit 1 + fi + fi + # https://docs.docker.com/engine/api/v1.25/ # Set container selector @@ -40,8 +62,8 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then while true; do sleep ${AUTOHEAL_INTERVAL:=5} - - apiUrl="http://localhost/containers/json?filters=\{\"health\":\[\"unhealthy\"\]${labelFilter}\}" + + apiUrl="${HTTP_ENDPOINT}/containers/json?filters=\{\"health\":\[\"unhealthy\"\]${labelFilter}\}" stopTimeout=".Labels[\"autoheal.stop.timeout\"] // ${AUTOHEAL_DEFAULT_STOP_TIMEOUT:-10}" docker_curl "$apiUrl" | \ jq -r "foreach .[] as \$CONTAINER([];[]; \$CONTAINER | .Id, .Names[0], $stopTimeout )" | \ @@ -52,7 +74,7 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then echo "$DATE Container name of ($CONTAINER_SHORT_ID) is null, which implies container does not exist - don't restart" else echo "$DATE Container ${CONTAINER_NAME} ($CONTAINER_SHORT_ID) found to be unhealthy - Restarting container now with ${TIMEOUT}s timeout" - docker_curl -f -XPOST "http://localhost/containers/${CONTAINER_ID}/restart?t=${TIMEOUT}" \ + docker_curl -f -XPOST "${HTTP_ENDPOINT}/containers/${CONTAINER_ID}/restart?t=${TIMEOUT}" \ || echo "$DATE Restarting container $CONTAINER_SHORT_ID failed" fi done