diff --git a/Dockerfile b/Dockerfile index 7078bb1..a23d996 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,63 @@ -FROM memcached:latest +FROM memcached:1.4-alpine +# Build-time metadata as defined at http://label-schema.org +# with added usage described in https://microbadger.com/#/labels +ARG BUILD_DATE +ARG VCS_REF +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.docker.dockerfile="/Dockerfile" \ + org.label-schema.name="Autopilot Pattern Memcached" \ + org.label-schema.url="https://github.com/autopilotpattern/memcached" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-type="Git" \ + org.label-schema.vcs-url="https://github.com/autopilotpattern/memcached" + +# Reset to root user to do some installs USER root -RUN apt-get update \ - && apt-get install -y \ - netcat \ - curl -# Install ContainerPilot +# Install packages +RUN apk update && apk add \ + bash \ + curl \ + netcat-openbsd \ + && rm -rf /var/cache/apk/* + +# Add ContainerPilot and its configuration # Releases at https://github.com/joyent/containerpilot/releases -ENV CONTAINERPILOT_VER 2.0.1 -RUN export CONTAINERPILOT_CHECKSUM=a4dd6bc001c82210b5c33ec2aa82d7ce83245154 \ - && curl -Lso /tmp/containerpilot.tar.gz \ - "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VER}/containerpilot-${CONTAINERPILOT_VER}.tar.gz" \ +ENV CONTAINERPILOT_VER 2.3.0 +ENV CONTAINERPILOT file:///etc/containerpilot.json + +RUN export CONTAINERPILOT_CHECKSUM=ec9dbedaca9f4a7a50762f50768cbc42879c7208 \ + && curl --retry 7 --fail -Lso /tmp/containerpilot.tar.gz \ + "https://github.com/joyent/containerpilot/releases/download/${CONTAINERPILOT_VER}/containerpilot-${CONTAINERPILOT_VER}.tar.gz" \ && echo "${CONTAINERPILOT_CHECKSUM} /tmp/containerpilot.tar.gz" | sha1sum -c \ && tar zxf /tmp/containerpilot.tar.gz -C /usr/local/bin \ && rm /tmp/containerpilot.tar.gz -# Add ContainerPilot configuration -COPY etc/containerpilot.json /etc/containerpilot.json -ENV CONTAINERPILOT file:///etc/containerpilot.json +# The our helper/glue scripts and configuration for this specific app +COPY bin /usr/local/bin +COPY etc /etc + +# Install Consul +# Releases at https://releases.hashicorp.com/consul +RUN export CONSUL_VERSION=0.6.4 \ + && export CONSUL_CHECKSUM=abdf0e1856292468e2c9971420d73b805e93888e006c76324ae39416edcf0627 \ + && curl --retry 7 --fail -vo /tmp/consul.zip "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" \ + && echo "${CONSUL_CHECKSUM} /tmp/consul.zip" | sha256sum -c \ + && unzip /tmp/consul -d /usr/local/bin \ + && rm /tmp/consul.zip \ + && mkdir /config -# reset entrypoint from base image +# Create empty directories for Consul config and data +RUN mkdir -p /etc/consul \ + && chown -R memcache /etc/consul \ + && mkdir -p /var/lib/consul \ + && chown -R memcache /var/lib/consul + +# Reset entrypoint from base image ENTRYPOINT [] + +# Reset to memcache user to, um, run memcache USER memcache CMD ["/usr/local/bin/containerpilot", \ "memcached", \ diff --git a/README.md b/README.md index 116dfdc..26a8b93 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [![DockerPulls](https://img.shields.io/docker/pulls/autopilotpattern/memcached.svg)](https://registry.hub.docker.com/u/autopilotpattern/memcached/) [![DockerStars](https://img.shields.io/docker/stars/autopilotpattern/memcached.svg)](https://registry.hub.docker.com/u/autopilotpattern/memcached/) -[![ImageLayers](https://badge.imagelayers.io/autopilotpattern/memcached:latest.svg)](https://imagelayers.io/?images=autopilotpattern/memcached:latest) -[![Join the chat at https://gitter.im/autopilotpattern/general](https://badges.gitter.im/autopilotpattern/general.svg)](https://gitter.im/autopilotpattern/general) +[![MicroBadger version](https://images.microbadger.com/badges/version/autopilotpattern/memcached.svg)](http://microbadger.com/#/images/autopilotpattern/memcached) +[![MicroBadger commit](https://images.microbadger.com/badges/commit/autopilotpattern/memcached.svg)](http://microbadger.com/#/images/autopilotpattern/memcached) ### Usage Include this image in your Docker Compose project, query Consul for it's IP address and use it in your configurations, easily done via [Consul-Template](https://github.com/hashicorp/consul-template). The default ContainerPilot configuration talks to Consul and assumes the IP address to access consule is passed to the container in an envrionment varible, $CONSUL @@ -33,3 +33,12 @@ $memcached_servers = array( ); {{ end }} ``` + +### Building + +This image implements [microbadger.com](https://microbadger.com/#/labels) label schema, but those labels require additional build args: + +``` +docker build --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VCS_REF=`git rev-parse --short HEAD` . +``` \ No newline at end of file diff --git a/bin/sensor.sh b/bin/sensor.sh new file mode 100755 index 0000000..5d707a4 --- /dev/null +++ b/bin/sensor.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e + +help() { + echo 'Uses cli tools free and top to determine current CPU and memory usage' + echo 'for the telemetry service.' +} + +# count of memcached evictions +evictions() { + (>&2 echo "evictions check fired") + local evictions=$(echo -e 'stats\nquit' | nc 127.0.0.1 11211 | awk '/evictions/{print $3}') + echo ${evictions} +} + +# memory usage in percent +sys_memory() { + # awk oneliner to get memory usage + # free -m | awk 'NR==2{printf "Memory Usage: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }' + # output: + # Memory Usage: 15804/15959MB (99.03%) + (>&2 echo "sys memory check fired") + local memory=$(free -m | awk 'NR==2{printf "%.2f", $3*100/$2 }') + echo ${memory} +} + +# cpu load +sys_cpu() { + # oneliner to display cpu load + # top -bn1 | grep load | awk '{printf "CPU Load: %.2f\n", $(NF-2)}' + (>&2 echo "sys cpu check fired") + local cpuload=$(top -bn1 | grep load | awk '{printf "%.2f", $(NF-2)}') + echo ${cpuload} +} + +cmd=$1 +if [ ! -z "$cmd" ]; then + shift 1 + $cmd "$@" + exit +fi + +help diff --git a/etc/containerpilot.json b/etc/containerpilot.json index f95fbce..c1ca1f5 100644 --- a/etc/containerpilot.json +++ b/etc/containerpilot.json @@ -1,5 +1,5 @@ { - "consul": "{{ .CONSUL }}:8500", + "consul": "{{ if .CONSUL_AGENT }}localhost{{ else }}{{ .CONSUL }}{{ end }}:8500", "services": [ { "name": "memcached", @@ -8,5 +8,42 @@ "poll": 10, "ttl": 25 } - ] + ], + "coprocesses": [{{ if .CONSUL_AGENT }} + { + "command": ["/usr/local/bin/consul", "agent", + "-data-dir=/var/lib/consul", + "-config-dir=/etc/consul", + "-rejoin", + "-retry-join", "{{ .CONSUL }}", + "-retry-max", "10", + "-retry-interval", "10s"], + "restarts": "unlimited" + }{{ end }}], + "telemetry": { + "port": 9090, + "sensors": [ + { + "name": "memcached_evictions", + "help": "count of keys evicted due to memory exhaustion", + "type": "gauge", + "poll": 5, + "check": ["/usr/local/bin/sensor.sh", "evictions"] + }, + { + "name": "memcached_sys_memory_percent", + "help": "percentage of memory used", + "type": "gauge", + "poll": 5, + "check": ["/usr/local/bin/sensor.sh", "sys_memory"] + }, + { + "name": "memcached_sys_cpu_load", + "help": "cpu load", + "type": "gauge", + "poll": 5, + "check": ["/usr/local/bin/sensor.sh", "sys_cpu"] + } + ] + } }