Skip to content

Instantly share code, notes, and snippets.

@ake-persson
Last active March 29, 2016 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ake-persson/2b8495e7ecf221ec682ab8c8cf850d38 to your computer and use it in GitHub Desktop.
Save ake-persson/2b8495e7ecf221ec682ab8c8cf850d38 to your computer and use it in GitHub Desktop.
Docker garbage collection based on when an image was cached/downloaded
#!/bin/bash
# Root used by Docker runtime
ROOT="/var/lib/docker"
# Device for Docker root
#ROOT_DEV="/dev/vg_root/lv_var"
ROOT_DEV=$(df -T ${ROOT} | awk '/dev/ { print $1 }')
# Docker thinpool device
# POOL_DEV="/dev/vg_root/docker-pool"
POOL_LV=$(lvs --read-only | awk '/docker/ { print $1 }')
POOL_VG=$(lvs --read-only | awk '/docker/ { print $2 }')
POOL_DEV="/dev/${POOL_VG}/${POOL_LV}"
# Cleanup images older then x sec.
OLDER_THEN=$((7 * 24 * 60 * 60)) # 1 week
# High-water mark
HWMARK="90"
# Cleanup images older then x sec. once high-water mark is reached
HWMARK_OLDER_THEN=$((24 * 60 * 60)) # 1 day
NOW=$(date -u +"%s")
# Parse date to sec.
parse_date() {
echo $(date -u --date "${1}" "+%s")
}
# Time since in sec.
time_since() {
before=$(parse_date "${1}")
echo $((${NOW} - ${before}))
}
# Human readable time
time_hr() {
local T=${1}
local D=$((T/60/60/24))
local H=$((T/60/60%24))
local M=$((T/60%60))
local S=$((T%60))
(( $D > 0 )) && printf '%d days ' $D
(( $H > 0 )) && printf '%d hours ' $H
(( $M > 0 )) && printf '%d minutes ' $M
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and '
printf '%d seconds\n' $S
}
# Cleanup images older then x sec.
gc_images_older_then() {
local older_then=${1}
images=""
short_images=""
for id in $(docker images -q --no-trunc); do
inode=$(stat --format '%i' ${ROOT}/devicemapper/metadata/${id})
ctime=$(debugfs -R "stat <${inode}>" ${ROOT_DEV} 2>/dev/null | awk -F '-- ' '/ctime:/ { print $2 }')
elapsed=$(time_since "${ctime}")
short_id=${id:0:12}
[[ ${elapsed} > ${older_then} ]] && images="${images} ${id}" && short_images="${short_images} ${short_id}"
echo -n "."
done
echo
if [ -n "${images}" ]; then
log "Cleanup images older then $(time_hr ${older_then}), image id(s): ${short_images}"
docker rmi $images
fi
}
# Log to syslog
log() {
logger -s -t $(basename $0) $1
}
log "Started"
# Cleanup stopped containers
containers=$(docker ps -a -q -f "status=exited")
if [ -n "${containers}" ]; then
log "Cleanup stopped container id(s): ${containers}"
docker rm $containers
fi
# Cleanup dangling images
images=$(docker images -q --filter "dangling=true")
if [ -n "${images}" ]; then
log "Cleanup dangling image id(s): ${images}"
docker rmi $images
fi
# Cleanup images older then x sec.
gc_images_older_then ${OLDER_THEN}
usage=$(lvs ${POOL_DEV} | tail -1 | awk '{ print $5 }')
if [[ ${usage%.*} -lt 90 ]]; then
log "Done"
exit 0
fi
log "High-water mark ${HWMARK}% for docker-pool reached"
# Cleanup images older then x sec.
gc_images_older_then ${HWMARK_OLDER_THEN}
usage=$(lvs ${POOL_DEV} | tail -1 | awk '{ print $5 }')
if [[ ${usage%.*} -lt 90 ]]; then
log "Done"
exit 0
fi
log "Still reaching high-water mark ${HWMARK}%"
# Cleanup all cached images
images=$(docker images -q)
if [ -n "${images}" ]; then
log "Cleanup all cached image id(s): ${images}"
docker rmi $images
fi
log "Done"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment