Как удалить старые и неиспользуемые изображения Docker

при запуске Docker в течение длительного времени, есть много изображений в системе. Как удалить все неиспользуемые изображения Docker сразу, чтобы освободить хранилище?

кроме того, я также хочу удалить изображения, вытащенные несколько месяцев назад, которые имеют правильный TAG.

Итак, я не прошу удалять только не помеченные изображения. Я ищу способ удалить общие неиспользуемые изображения, которые включают в себя как untagged, так и другие изображения, такие как вытащенные месяцы назад с правильным TAG.

20 ответов


Обновление Сентября. 2016: Докер 1.13: PR 26108 и совершить 86de7c0 введите несколько новых команд, чтобы помочь облегчить визуализацию, сколько места данные docker daemon занимает на диске и позволяет легко очистить "ненужный" избыток.

docker system prune удалит все висячие данные (т. е. в порядке: контейнеры остановлены, Тома без контейнеров и изображения без контейнеров). Даже неиспользуемые данные, с -a выбор.

у вас также есть:

на неиспользованный картинки, используйте docker image prune -a (для удаления оборванных и ununsed images).
Предупреждение: 'неиспользованный 'означает" изображения, на которые не ссылается ни один контейнер": будьте осторожны перед использованием -a.

как поясняется в A L ' s ответ, docker system prune --all удалить все неиспользованный изображения не просто висячие... что может быть немного чересчур.

объединение docker xxx prune С --filter опции может быть отличным способом ограничить обрезку (docker SDK API 1.28 минимум, поэтому docker 17.04+)

поддерживаемые фильтры являются:

  • until (<timestamp>) - удалить только контейнеры, изображения и сети, созданные до заданной метки времени
  • label (label=<key>, label=<key>=<value>, label!=<key> или label!=<key>=<value>) - удаление только контейнеров, изображений, сетей и томов с помощью (или без в случае label!=... используется) указанные метки.

в разделе "обрезать изображения" для примера.


оригинальный ответ (Sep. 2016)

я обычно делаю:

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

у меня есть псевдоним для удаления этих [свесив изображений]13: drmi

на dangling=true фильтр находит неиспользуемые изображения

таким образом, любое промежуточное изображение, на которое больше не ссылается помеченное изображение, удаляется.

я делаю то же самое первый на вышла процессов (контейнеры)

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

As haridsv указывает в комментариях:

технически вы должны сначала очистить контейнеры перед очисткой изображений, так как это будет ловить больше висячих изображений и меньше ошибок.


Джесс Фрейзелл (jfrazelle) имеет функция bashrc:

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. Нетерпеливый может пропустить приглашение с :

docker system prune -f

нетерпеливый и бесшабашные можно дополнительно удалить "неиспользуемые изображения, а не только болтающиеся" с помощью -a, --all вариант:

docker system prune -af

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

обновление:

смотрите VonC это, который использует недавно добавил prune команды. Вот соответствующее удобство псевдонима оболочки:

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

вот они в удобной оболочке псевдоним:

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 images --no-trunc --format '{{.ID}} {{.CreatedSince}}' \
    | grep ' months' | awk '{ print  }' \
    | 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  }' | 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

если у вас есть настройки 1.13 или выше, вы можете просто использовать чернослив команды. Для вашего вопроса специально для удаления старых изображений вам нужен первый.

# 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

Я бы порекомендовал не привыкание к использованию


это сработало для меня:

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

другие ответы велики, в частности:

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

но мне нужно было что-то в середине двух команд, так что что нужно:

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


недавно я написал скрипт для решения этой проблемы на одном из моих серверов:

#!/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 ':' '{print ":"}!{print ":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 версии 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

все неиспользуемые контейнеры, изображения, сети и Тома будут удалены. Мы также можем сделать это, используя следующие команды, которые очищают отдельные компоненты:

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

вот скрипт для очистки изображений Docker и восстановления пространства.

#!/bin/bash -x
## Removing stopped container
docker ps -a | grep Exited | awk '{print }' | 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 }' | xargs docker rm
#docker ps -a | grep Exited | grep "weeks ago" | awk '{print }' | 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 }')

## Removing weeks old images

docker images | grep "weeks ago" | awk '{print }' | 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 занимают место, это не повлияет на вашу систему, поскольку она будет использовать другое место монтирования.

исходный пост: управление изображениями Docker на локальном диске


Если вы хотите удалить изображения вытащил 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

docker rm `docker ps -aq`

или

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

чтобы удалить помеченные изображения, у которых нет контейнера, вам придется использовать небольшой скрипт:

#!/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 ;}'); 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

Как удалить помеченное изображение

  1. docker rmi тег первый

  2. docker rmi изображение.

    # Это можно сделать в одном вызове docker rmi, например: # docker rmi

(это работает ноябрь 2016, 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  ":"  }' )
IDS=$(echo "$IMAGESINFO" | awk '{ print  }' )
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

docker system prune -a

(вас попросят подтвердить команду. Использовать -f чтобы заставить бежать, если вы знаете, что делаете.)


@VonC уже дал очень хороший ответ, но для полноты картины вот небольшой скрипт я использую - -, а также ядерное оружие любое поручение Докер процессов, если у вас есть:

#!/bin/bash

imgs=$(docker images | awk '/<none>/ { print  }')
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

Я использую эту команду:

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 недель назад.


удалите старые контейнеры несколько недель назад.

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

удалить старые изображения несколько недель назад. Быть осторожным. Это удалит базовые изображения, которые были созданы несколько недель назад, но которые могут использоваться вашими новыми изображениями.

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


Если вы хотите автоматически / периодически очищать выходящие контейнеры и удалять изображения и Тома, которые не используются запущенным контейнером, вы можете загрузить изображение 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


иногда я сталкивался с проблемами, когда Docker будет выделять и продолжать использовать дисковое пространство, даже если пространство не выделено какому-либо конкретному образу или существующему контейнеру. Последний способ, которым я случайно сгенерировал эту проблему, - это использование" docker-engine "centos build вместо "docker" в RHEL 7.1. Кажется, что иногда очистка контейнера не завершена успешно, а затем пространство никогда не используется повторно. Когда диск 80GB, который я выделил как / был заполнен /var / lib / docker files мне пришлось придумать творческий способ решения проблемы.

вот что я придумал. Сначала, чтобы разрешить полную ошибку диска:

  1. стоп докер: systemctl стоп докер
  2. выделен новый диск, установленный как say/mnt / docker .
  3. переместите все файлы в /var/lib /docker в/mnt / docker . Я использовал команду: при помощи rsync -aPHSx --удалить-источник-файлы /var/lib в/докер/ /шоссе/докер/
  4. установите новый диск на /var / lib / docker.

на данный момент у меня больше не было полной ошибки диска, но я все еще тратил огромное количество места. Следующие шаги-позаботиться об этом.

  1. запустить Docker: systemctl запустить docker

  2. сохранить все изображения: docker save $(docker images |sed-e '/^/d'- e '/^репозиторий/d' - e 's,[ ][ ],:,'- e 's, [ ].,,') > /root/docker.img

  3. удалить докер.

  4. стереть все в/var/lib / docker: rm-rf/var/lib/docker / [cdintv]*

  5. переустановить docker

  6. включить docker: systemctl включить docker

  7. запустить docker: systemctl запустить docker

  8. восстановление изображений: докер нагрузки

  9. запустите все постоянные контейнеры, которые вам нужны.

этот сбросил использование диска с 67 ГБ для docker до 6 ГБ для docker.

Я не рекомендую его для ежедневного использования. Но полезно запускать, когда кажется, что docker потерял след используемого дискового пространства из-за ошибок программного обеспечения или неожиданных перезагрузок.


есть плагин sparrow docker-удалить-висячие-изображения вы можете использовать для очистки остановленных контейнеров и неиспользуемых (болтающихся) изображений:

$ sparrow plg run docker-remove-dangling-images

он работает как для Linux, так и для ОС Windows.