删除所有超过 4 周的 docker 镜像所需的简单脚本

Posted

技术标签:

【中文标题】删除所有超过 4 周的 docker 镜像所需的简单脚本【英文标题】:Simple script needed to delete all docker images older than 4 weeks 【发布时间】:2017-07-10 21:40:17 【问题描述】:

我知道以前有人问过类似的问题,但我找不到完全符合我需要的任何问题。我也在 Docker 社区论坛上问过,但没人能帮忙。

我无法访问新的docker image prune 命令,因为我还无法从当前版本 1.11.2 升级到最新的 1.13,但我需要一个可以在 cron 下运行的简单脚本来删除所有超过 1 个月大的图像,无论是否悬空。我不需要担心容器,因为这是来自仅存储图像的存储库。

如果 docker images 将“4 周”报告为“1 个月”,那就很简单了,我可以使用类似

docker images | grep " [months]* "

并将输出通过管道传送到docker rmi 命令。但是,由于它似乎在“数周”内报告最多 11 周,并且在图像 3 个月或更长时间后仅“数月”报告,我不能这样做。

docker images | grep " [months|weeks]* ago" | awk 'print $3,$4,$5'

会给我这个输出::

6828f152f9cc 2 weeks
52a7412befd3 2 weeks
04c2b29e5e08 2 weeks
cdfb37d22663 2 weeks
ca38a8cabb2b 3 weeks
8b043f2395ba 3 weeks
2aa8b20380a0 3 weeks
1ac7dcf35935 9 weeks
f80873c4845b 9 weeks
d5700d37ee95 9 weeks
594dc21de8de 9 weeks
0c9dacb7fa7c 10 weeks
11f3eec60e17 3 months
b13ebf1a4999 3 months
68b0d6a3be3b 7 months
baadc9c8b0ce 8 months
10eb0d6b2b99 9 months

...但我一直在试图弄清楚如何测试 $4,$5 以仅包含“月”或 >=“4 周”的任何内容,然后可以将其通过管道传输到 docker rmi 。任何人都可以提供一些可以做到这一点的简单代码的线索吗?

【问题讨论】:

我宁愿使用docker inspect $(docker images -q) 并找到必填字段 【参考方案1】:

只需awkneeded:

docker images |awk '$5=="months" || ($4>4 && $5=="weeks") print $3,$4,$5'

说明

如果第 5 个字段是“月”或等于“周”且第 4 个大于 4,则打印所需的列。

【讨论】:

【参考方案2】:

这是一个脚本,你可以把它写在你的 .bashrc 中

#!/bin/bash

max_week_size=4
docker images | awk 'NR>1 print $0' | while read line; do
    # echo $line
    id_img=$(echo $line | awk 'print $3')

    # if older then a month
    is_month=$(echo $line | grep 'month')
    if [ ! -z "$is_month" ]; then 
        echo $id_img
        docker rmi -f $id_img
        continue
    fi

    # remove older then 4 weeks
    num_week=$(echo $line | grep "week" | awk 'print $4')
    if [ ! -z "$num_week" ] && [ $num_week -ge $max_week_size ]; then 
        echo $id_img
        docker rmi -f $id_img
    fi
done

【讨论】:

【参考方案3】:

我个人更喜欢下面的bash函数:

docker_housekeeping() 

  # Collect list of images older than 4 weeks.
  OLD_IMAGES=$((docker images |
                grep -P "(months|[4-9] weeks|\d\d+ weeks)" |
                awk 'print $3'))

  # Remove old images.
  docker rmi $OLD_IMAGES[@]

您可以将其粘贴在您的 .bashrc 上,然后在每次想要进行清理时将其称为 docker_housekeeping

【讨论】:

【参考方案4】:

试试这个(仅使用awk):

docker images |awk 'if (($4 > 4 && $5 == "weeks") || ($4 > 1 && $5 == "months")) print $3,$4,$5'

我使用 if 语句和括号来确保执行顺序。

不需要grep

【讨论】:

感谢法哈德,但这没有用 - 它错过了 10 周前的图像。【参考方案5】:

您可以使用-f 标志添加过滤器。

查找超过 4 周的图像 ID。并执行以下命令

docker rmi $(docker images -q -f "before=<docker_image_id_older_than_4_weeks>")

【讨论】:

比其他答案简单得多。【参考方案6】:

你可以试试下面的脚本,我用的是下面的

#!/bin/bash

timestamp=$(date +%Y%m%d_%H%M%S)
log_path="`pwd`"
filename=docker_cleanup_$timestamp.log
log=$log_path/$filename


docker_space_before()
CURRENTSPACE=`docker system df`
echo "Current Docker Space:" >> $log
echo $CURRENTSPACE >>$log

docker_find ()
echo "#####################################################################" >> $log
echo "Finding images" >> $log
echo "#####################################################################" >> $log
REMOVEIMAGES=`docker images | grep " [days|months|weeks]* ago" | awk 'print $3'`

echo "Listing images that needs to be cleaned up" >> $log
echo $REMOVEIMAGES >>$log



docker_cleanup()
echo "#####################################################################" >> $log
echo "Cleaning images" >> $log
echo "#####################################################################" >> $log
docker rmi $REMOVEIMAGES


docker_space_after()
CURRENTSPACE=`docker system df`
echo "Current Docker Space, after clean up:" >> $log
echo $CURRENTSPACE >>$log

docker_space_before
docker_find
docker_cleanup
docker_space_after

现在这将通过记录空间信息进行清理

【讨论】:

以上是关于删除所有超过 4 周的 docker 镜像所需的简单脚本的主要内容,如果未能解决你的问题,请参考以下文章

用了一个月的Docker,我真的是爱了

docker学习

Docker基本实践

Docker基本实践

牛逼!下一代 Docker 镜像构建神器

Dockerfile最佳实践