首页 文章

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

提问于
浏览
524

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

另外,我还想删除几个月前拉出的图片,这些图片有正确的 TAG .

所以,我在寻找一种方法来删除一般未使用的图像,其中包括未标记的图像和其他图像,例如几个月前拉出正确 TAG .

20 回答

  • 2

    @VonC已经给出了一个非常好的答案,但是为了完整性,这里有一个我一直在使用的小脚本---如果你有一些东西,它还会破坏任何差事Docker进程:

    #!/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
    
  • 2

    要删除超过一个月的 old tagged 图像:

    $ 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
    
  • 7

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

    这就是我想出的 . 首先解决磁盘已满错误:

    • 停止docker:systemctl停止docker

    • 分配了一个新的驱动器作为say / mnt / docker安装 .

    • 将/ var / lib / docker中的所有文件移动到/ mnt / docker . 我使用命令:rsync -aPHSx --remove-source-files / var / lib / docker / / mnt / docker /

    • 将新驱动器挂载到/ var / lib / docker .

    此时我不再有磁盘完全错误,但我仍然浪费了大量的空间 . 接下来的步骤是要处理这个问题 .

    • 启动Docker:systemctl启动docker

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

    • 卸载docker .

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

    • 重新安装docker

    • 启用docker:systemctl enable docker

    • 启动docker:systemctl启动docker

    • 恢复图像:docker load </root/docker.img

    • 启动您需要运行的任何持久性容器 .

    这使我的磁盘使用率从docker的67 GB减少到docker的6 GB .

    我不建议日常使用 . 但是,当看起来docker已经丢失了使用过的磁盘空间来处理软件错误或意外重启时运行是很有用的 .

  • 10

    我正在使用此命令:

    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周前的所有图像 .

  • 44

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

    赶紧跑:

    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

  • 11

    这对我有用:

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

    其他答案很棒,具体来说:

    docker system prune # doesn't clean out old images
    docker system prune --all # cleans out too much
    

    但是我在两个命令的中间需要一些东西,所以我需要 filter 选项:

    docker image prune --all --filter "until=4320h" # delete images older than 6 months ago; 4320h = 24 hour/day * 30 days/month * 6 months
    

    希望有所帮助:)

    供参考:https://docs.docker.com/config/pruning/#prune-images

  • 2

    假设你有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
    

    我建议 not 习惯使用 docker system prune 命令 . 我估计用户会不小心删除他们主要使用 docker image prunedocker container prune 命令的内容 .

  • 2

    到目前为止(Docker版本1.12),我们使用以下命令删除所有正在运行的容器 . 此外,如果我们要删除卷,我们可以使用以下命令中的相应标记-v手动执行此操作 .

    Delete all Exited Containers

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

    Delete all Stopped Containers

    docker rm $(docker ps -a -q)
    

    Delete All Running and Stopped Containers

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

    Remove all containers, without any criteria

    docker container rm $(docker container ps -aq)
    

    但是,在1.13及更高版本中,对于完整的系统和清理,我们可以直接使用以下命令:

    docker system prune
    

    所有未使用的容器,图像,网络和卷都将被删除 . 我们也可以使用以下清理单个组件的命令来执行此操作:

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

    docker system prune -a

    (系统会要求您确认该命令 . 如果您知道自己在做什么,请使用 -f 强行运行 . )

  • 0

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

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

    docker system prune -f
    

    不耐烦和鲁莽可以使用 -a, --all 选项另外删除"unused images not just the dangling ones":

    docker system prune -af
    

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

    更新:

    请参阅VonC's answer,它使用最近添加的 prune 命令 . 这是相应的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
    

    如果您对 irrevocable data loss 行使 extreme caution ,那么您可以删除未使用的(悬空)卷(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'
    

    参考文献:

  • 0

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

    #!/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
    
  • 2

    How to remove a tagged image

    • docker rmi首先是标签

    • docker rmi图片 .

    #可以在一个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
    
  • 1070

    几个星期前删除旧容器 .

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

    几周前删除旧图像 . 小心 . 这将删除几周前创建但您的新图像可能正在使用的基本图像 .

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

  • 16

    如果要删除X个月前提取的图像,可以尝试以下示例删除三个月前创建的图像:

    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
    
  • 7

    麻雀插件docker-remove-dangling-images可以用来清理已停止的容器和未使用的(悬空)图像:

    $ sparrow plg run docker-remove-dangling-images

    它适用于Linux和Windows操作系统 .

  • 5

    这是一个清理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 a 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 a 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会保留与图像构建和图层相关的所有临时文件

    /var/lib/docker

    此路径是系统的本地路径,通常位于根分区 "/" .

    您可以安装更大的磁盘空间并将 /var/lib/docker 的内容移动到新的安装位置并创建符号链接 .

    这样,即使Docker镜像占用空间,它也不会影响您的系统,因为它将使用其他一些安装位置 .

    原帖:Manage Docker images on local disk

  • 3
    docker rm `docker ps -aq`
    

    要么

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

    2016年9月更新:Docker 1.13:PR 26108commit 86de7c0引入了一些新命令,以帮助显示Docker守护程序数据在磁盘上占用的空间,并允许轻松清理"unneeded"多余的空间 .

    docker system prune将删除所有悬空数据(即按顺序:容器停止,没有容器的卷和没有容器的图像) . 即使是未使用的数据,也可以使用 -a 选项 .

    你还有:

    对于未使用的图像,请使用 docker image prune -a (用于删除悬空和未图像的图像) .
    警告:'unused'表示"images not referenced by any container":在使用 -a 之前要小心 .

    A Lanswer所示, docker system prune --all 将删除所有未使用的图像,而不仅仅是悬空图像...这可能有点太多了 .

    docker xxx prune--filter option相结合可能是限制修剪的好方法(docker SDK API 1.28 minimum, so docker 17.04+

    目前支持的过滤器是:

    • until (<timestamp>) - 仅删除在给定时间戳之前创建的容器,图像和网络

    • labellabel=<key>label=<key>=<value>label!=<key>label!=<key>=<value> ) - 仅使用(或不使用 label!=... )指定的标签移除容器,图像,网络和卷 .

    有关示例,请参阅“Prune images” .


    原始答案(2016年9月)

    我经常这样做:

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

    我有alias for removing those [dangling images] 13drmi

    dangling = true过滤器查找未使用的图像

    这样,删除了标记图像不再引用的任何中间图像 .

    我为exited processes (containers)做同样的 first

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

    正如haridsv指出in the comments

    从技术上讲,您应该先清理容器,然后再清理图像,因为这会捕获更多悬空图像并减少错误 .


    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
    }
    

    要删除旧图像,而不仅仅是"unreferenced-dangling"图像,您可以考虑docker-gc


    一个简单的Docker容器和图像垃圾收集脚本 . 退出一个多小时前的容器将被删除 . 删除之后不属于任何剩余容器的图像 .

  • 2

    我最近在我的一台服务器上写了一个脚本来解决这个问题:

    #!/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
    

相关问题