Last active
March 29, 2016 18:37
-
-
Save ake-persson/2b8495e7ecf221ec682ab8c8cf850d38 to your computer and use it in GitHub Desktop.
Docker garbage collection based on when an image was cached/downloaded
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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