如何删除旧的和未使用的Docker镜像

长时间运行docker时,系统中有很多图像。 如何一次性删除所有未使用的docker图像以释放存储空间?

另外,我也想删除几个月前拉的图片,里面有正确的TAG

所以,我不是要求只去除未标记的图像。 我正在寻找一种方法来删除一般未使用的图像,其中包括无标记和其他图像,如数月前正确的TAG

2016年9月更新Docker即将到来的Docker 1.13: PR 26108和提交86de7c0引入了一些新的命令来帮助可视化Docker守护进程数据在磁盘上占用多less空间,并允许轻松清除“不需要的”过量。

docker system prune将删除所有悬而未决的数据(即顺序:容器停止,容器没有容器和没有容器的图像)。 即使未使用的数据,与-a选项。

你也有:

  • docker container prune
  • docker image prune
  • docker network prune
  • docker volume prune

对于未使用的图像,请使用docker docker image prune -a (用于删除悬挂未被使用的图像)。
警告:“ 未使用 ”是指“未被任何容器引用的图像”:使用-a前要小心。


原文答复(2016年9月)

我通常做:

 docker rmi $(docker images --filter "dangling=true" -q --no-trunc) 

我有一个别名,以消除这些[晃来晃去的图像] 8 : drmi

dangling=truefilter查找未使用的图像

这样,任何不再被标记图像引用的中间图像都将被移除。

首先为退出的进程(容器)

 alias drmae='docker rm $(docker ps -qa --no-trunc --filter "status=exited")' 

正如haridsv 在评论中指出的那样:

从技术上讲, 在清理图像之前应该首先清理容器,因为这样可以捕捉更多的悬挂图像,减less错误


Jess Frazelle(jfrazelle)有bashrc的function :

 dcleanup(){ docker rm -v $(docker ps --filter status=exited -q 2>/dev/null) 2>/dev/null docker rmi $(docker images --filter dangling=true -q 2>/dev/null) 2>/dev/null } 

要删除旧图像,而不是“未引用的悬挂”图像,可以考虑docker-gc


一个简单的Docker容器和图像垃圾收集脚本。

  • 一个多小时前退出的容器被移除。
  • 之后不属于任何剩余容器的图像将被删除。

更新第二个(2017-07-08):

请再次参考VonC,使用更新的system prune 。 不耐烦的人可以用-f, --force选项跳过提示:

 docker system prune -f 

不耐烦和鲁莽可以删除“不使用的图像,不只是悬挂的”与-a, --all选项:

 docker system prune -af 

https://docs.docker.com/engine/reference/commandline/system_prune/

更新:

请参考使用最近添加的prune命令的VonC答案 。 这里是相应的shell别名方便程度:

 alias docker-clean=' \ docker container prune -f ; \ docker image prune -f ; \ docker network prune -f ; \ docker volume prune -f ' 

老答案:

删除已停止(已退出)的容器:

 $ docker ps --no-trunc -aqf "status=exited" | xargs docker rm 

删除未使用的(悬挂)图像:

 $ docker images --no-trunc -aqf "dangling=true" | xargs docker rmi 

如果您对于不可撤销的数据丢失 非常谨慎 ,那么您可以删除未使用(悬挂)的卷(v1.9及更高版本):

 $ docker volume ls -qf "dangling=true" | xargs docker volume rm 

在这里他们在一个方便的shell别名:

 alias docker-clean=' \ docker ps --no-trunc -aqf "status=exited" | xargs docker rm ; \ docker images --no-trunc -aqf "dangling=true" | xargs docker rmi ; \ docker volume ls -qf "dangling=true" | xargs docker volume rm' 

参考文献:

  • docker ps -f
  • docker rm
  • docker images -f
  • docker rmi
  • Docker v1.9.0发行说明
  • docker volume ls
  • docker volume rm

要移除超过一个月的旧标记图像,请执行以下操作:

 $ docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \ | grep ' months' | awk '{ print $1 }' \ | xargs --no-run-if-empty docker rmi 

请注意,它将无法删除容器使用的图像,在存储库中引用,有依赖的子图像…这可能是你想要的。 否则只需添加-f标志。

/etc/cron.daily/docker-gc脚本示例:

 #!/bin/sh -e # Delete all stopped containers (including data-only containers). docker ps -a -q --no-trunc --filter "status=exited" | xargs --no-run-if-empty docker rm -v # Delete all tagged images more than a month old # (will fail to remove images still used). docker images --no-trunc --format '{{.ID}} {{.CreatedSince}}' | grep ' months' | awk '{ print $1 }' | xargs --no-run-if-empty docker rmi || true # Delete all 'untagged/dangling' (<none>) images # Those are used for Docker caching mechanism. docker images -q --no-trunc --filter dangling=true | xargs --no-run-if-empty docker rmi # Delete all dangling volumes. docker volume ls -qf dangling=true | xargs --no-run-if-empty docker volume rm 

假设你有docker 1.13或者更高版本,你可以使用prune命令。 对于专门为删除旧图像的问题,您需要第一个。

 # Remove unused images docker image prune # Remove stopped containers. docker container prune # Remove unused volumes docker volume prune # Remove unused networks docker network prune # Command to run all prunes: docker system prune 

我会build议不习惯使用docker system prune命令。 我估计用户会意外删除他们不想要的东西。 就个人而言,我将主要使用docker image prunedocker container prune命令。

这对我工作:

 docker rmi $(docker images | grep "^<none>" | awk "{print $3}") 

我最近写了一个脚本来解决这个在我的服务器之一:

 #!/bin/bash # Remove all the dangling images DANGLING_IMAGES=$(docker images -qf "dangling=true") if [[ -n $DANGLING_IMAGES ]]; then docker rmi "$DANGLING_IMAGES" fi # Get all the images currently in use USED_IMAGES=($( \ docker ps -a --format '{{.Image}}' | \ sort -u | \ uniq | \ awk -F ':' '$2{print $1":"$2}!$2{print $1":latest"}' \ )) # Get all the images currently available ALL_IMAGES=($( \ docker images --format '{{.Repository}}:{{.Tag}}' | \ sort -u \ )) # Remove the unused images for i in "${ALL_IMAGES[@]}"; do UNUSED=true for j in "${USED_IMAGES[@]}"; do if [[ "$i" == "$j" ]]; then UNUSED=false fi done if [[ "$UNUSED" == true ]]; then docker rmi "$i" fi done 

直到现在(docker version 1.12),我们使用下面的命令删除所有正在运行的容器。 另外,如果我们要删除卷,我们可以使用下面的命令手动使用它的相应标签-v。

删除所有已退出的容器

 docker rm $(docker ps -q -f status=exited) 

删除所有已停止的容器

 docker rm $(docker ps -a -q) 

删除所有正在运行和停止的容器

 docker stop $(docker ps -a -q) docker rm $(docker ps -a -q) 

删除所有容器,没有任何标准

 docker container rm $(docker container ps -aq) 

但是,在1.13及以上版本中,为了完整的系统和清理,我们可以直接使用下面的命令:

 docker system prune 

所有未使用的容器,图像,networking和卷将被删除。 我们也可以使用以下命令清理各个组件:

 docker container prune docker image prune docker network prune docker volume prune 
 docker rm `docker ps -aq` 

要么

 docker rm $(docker ps -q -f status=exited) 

这是一个脚本来清理docker图像和回收空间。

  #!/bin/bash -x ##Removing stopped container docker ps -a | grep Exited | awk '{print $1}' | xargs docker rm ##If you do not want to remove all container you can have filter for days and weeks old like below #docker ps -a | grep Exited | grep "days ago" | awk '{print $1}' | xargs docker rm #docker ps -a | grep Exited | grep "weeks ago" | awk '{print $1}' | xargs docker rm ##Removing Dangling images ##There are the layers images which are being created during building docker image. This is a great way to recover the spaces used by old and unused layers. docker rmi $(docker images -f "dangling=true" -q) ##Removing images of perticular pattern For example ##Here i am removing images which has SNAPSHOT with it. docker rmi $(docker images | grep SNAPSHOT | awk '{print $3}') ##Removing Weeks old images docker images | grep "weeks ago" | awk '{print $3}' | xargs docker rmi ##Similarly You can remove days, months old images too. 

原始脚本

https://github.com/vishalvsh1/docker-image-cleanup

通常docker保持与图像构build和图层有关的所有临时文件

在/ var / lib中/泊坞窗

该path通常位于根分区“/”的系统本地。

您可以挂载更大的磁盘空间,并将/ var / lib / docker的内容移动到新的挂载位置并build立sym链接。 这样,即使docker图像占用空间,也不会影响您的系统,因为它将使用其他安装位置。

Original Post – http://www.scmtechblog.net/2016/06/clean-up-docker-images-from-local-to.html

我正在使用这个命令:

 export BEFORE_DATETIME=$(date --date='10 weeks ago' +"%Y-%m-%dT%H:%M:%S.%NZ") docker images -q | while read IMAGE_ID; do export IMAGE_CTIME=$(docker inspect --format='{{.Created}}' --type=image ${IMAGE_ID}) if [[ "${BEFORE_DATETIME}" > "${IMAGE_CTIME}" ]]; then echo "Removing ${IMAGE_ID}, ${BEFORE_DATETIME} is earlier then ${IMAGE_CTIME}" docker rmi -f ${IMAGE_ID}; fi; done 

这将移除10个星期前创build时间更长的所有图像。

如何删除标记的图像

  1. docker首先rmi的标签

  2. dockerrmi的形象。

    #可以在一个docker rmi调用中完成例如:#docker rmi <repo:tag> <imageid>

(这个工程2016年11月,Docker版本1.12.2)

例如

 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE usrxx/the-application 16112805 011fd5bf45a2 12 hours ago 5.753 GB usryy/the-application vx.xx.xx 5af809583b9c 3 days ago 5.743 GB usrzz/the-application vx.xx.xx eef00ce9b81f 10 days ago 5.747 GB usrAA/the-application vx.xx.xx 422ba91c71bb 3 weeks ago 5.722 GB usrBB/the-application v1.00.18 a877aec95006 3 months ago 5.589 GB $ docker rmi usrxx/the-application:16112805 && docker rmi 011fd5bf45a2 $ docker rmi usryy/the-application:vx.xx.xx && docker rmi 5af809583b9c $ docker rmi usrzz/the-application:vx.xx.xx eef00ce9b81f $ docker rmi usrAA/the-application:vx.xx.xx 422ba91c71bb $ docker rmi usrBB/the-application:v1.00.18 a877aec95006 

例如脚本删除超过2周的任何东西。

 IMAGESINFO=$(docker images --no-trunc --format '{{.ID}} {{.Repository}} {{.Tag}} {{.CreatedSince}}' |grep -E " (weeks|months|years)") TAGS=$(echo "$IMAGESINFO" | awk '{ print $2 ":" $3 }' ) IDS=$(echo "$IMAGESINFO" | awk '{ print $1 }' ) echo remove old images TAGS=$TAGS IDS=$IDS for t in $TAGS; do docker rmi $t; done for i in $IDS; do docker rmi $i; done 

@VonC已经给出了一个非常好的答案,但是为了完整起见,这里有一个我一直在使用的小脚本,

 #!/bin/bash imgs=$(docker images | awk '/<none>/ { print $3 }') if [ "${imgs}" != "" ]; then echo docker rmi ${imgs} docker rmi ${imgs} else echo "No images to remove" fi procs=$(docker ps -a -q --no-trunc) if [ "${procs}" != "" ]; then echo docker rm ${procs} docker rm ${procs} else echo "No processes to purge" fi 

如果你想删除X个月前的图片,你可以尝试下面的例子:3个月前创build的imagess:

 three_months_old_images=`docker images | grep -vi "<none>" | tr -s ' ' | cut -d" " -f3,4,5,6 | grep "3 months ago" | cut -d" " -f1` docker rmi $three_months_old_images 

要删除没有容器运行的标记图像,您将不得不使用一个小脚本:

 #!/bin/bash # remove not running containers docker rm $(docker ps -f "status=exited" -q) declare -A used_images # collect images which has running container for image in $(docker ps | awk 'NR>1 {print $2;}'); do id=$(docker inspect --format="{{.Id}}" $image); used_images[$id]=$image; done # loop over images, delete those without a container for id in $(docker images --no-trunc -q); do if [ -z ${used_images[$id]} ]; then echo "images is NOT in use: $id" docker rmi $id else echo "images is in use: ${used_images[$id]}" fi done 

几个星期前去掉旧的容器。

docker rm $(docker ps -a | grep "weeks" | awk '{ print $1; }')

几星期前删除旧图像。 小心。 这将删除几周前创build的基础图像,但您的新图像可能正在使用。

docker rmi $(docker images | grep 'weeks' | awk '{ print $3; }')

docker system prune -a

(你会被要求确认命令,如果你知道你在做什么,用-f强制运行。

偶尔我会遇到Docker将分配并继续使用磁盘空间的问题,即使空间未分配给任何特定映像或现有容器。 我不小心产生这个问题的最新方式是在RHEL 7.1中使用“docker-engine”centos构build而不是“docker”。 似乎发生的情况是,有时候容器清理工作没有成功完成,那么这个空间就不会被重复使用。 当我分配给/的80GB驱动器被填充了/ var / lib / docker文件时,我不得不想出一个创造性的方式来解决这个问题。

这是我想出来的。 首先解决磁盘满错误:

  1. 停泊docker:systemctl停泊docker
  2. 分配一个新的驱动器挂载为/ mnt / docker。
  3. 将/ var / lib / docker中的所有文件移动到/ mnt / docker。 我使用了以下命令:rsync -aPHSx –remove-source-files / var / lib / docker / / mnt / docker /
  4. 将新驱动器挂载到/ var / lib / docker。

在这一点上,我不再有磁盘满错误,但我仍然在浪费大量的空间。 接下来的步骤是照顾这一点。

  1. 启动Docker:systemctl启动docker

  2. 保存所有图像:docker save $(docker images | sed -e'/ ^ / d'-e'/ ^ REPOSITORY / d'-e's,[] [] ,:,'-e's,[ ]。 ''>> /root/docker.img

  3. 卸载docker。

  4. 清除/ var / lib / docker中的所有内容:rm -rf / var / lib / docker / [cdintv] *

  5. 重新安装docker

  6. 启用docker:systemctl启用docker

  7. 启动docker:systemctl start docker

  8. 还原图像:docker load </root/docker.img

  9. 启动你需要运行的任何持久容器。

这使我的磁盘使用率从docker的67 GB下降到docker的6 GB。

我不build议这个日常使用。 但是看起来像docker已经丢失了用过的磁盘空间跟踪软件错误或意外的重新启动时运行它是有用的。

如果您希望自动/定期清理已退出的容器,并删除正在运行的容器未使用的图像和卷​​,则可以下载此图像融水/docker清理。

赶紧跑:

 docker run -d -v /var/run/docker.sock:/var/run/docker.sock:rw -v /var/lib/docker:/var/lib/docker:rw --restart=unless-stopped meltwater/docker-cleanup:latest 

它默认每30分钟运行一次。 但是,您可以通过在几秒钟内使用此标志来设置延迟时间(DELAY_TIME = 1800选项)

更多细节: https : //github.com/meltwater/docker-cleanup/blob/master/README.md