Как удалить старые и неиспользуемые изображения Docker
При длительном запуске Docker в системе много образов. Как я могу безопасно удалить все неиспользуемые образы Docker, чтобы освободить хранилище?
Кроме того, я также хочу удалить изображения, извлеченные несколько месяцев назад, которые имеют правильные TAG
,
Поэтому я не прошу удалять только непомеченные изображения. Я ищу способ удаления общих неиспользуемых изображений, который включает в себя как непомеченные, так и другие изображения, такие как извлеченные несколько месяцев назад с правильным TAG
,
32 ответа
Обновление, сентябрь 2016 г.: Docker 1.13: PR 26108 и commit 86de7c0 вводят несколько новых команд, чтобы упростить визуализацию того, сколько места занимают данные демона docker на диске и что позволяет легко очистить "ненужный" избыток.
docker system prune
удалит ВСЕ свисающие данные (т.е. по порядку: контейнеры остановлены, тома без контейнеров и изображения без контейнеров). Даже неиспользованные данные, с -a
вариант.
У вас также есть:
docker container prune
docker image prune
docker network prune
docker volume prune
Для неиспользуемых изображений используйте docker image prune -a
(для удаления висячих и ненужных изображений).
Предупреждение: " не используется " означает "изображения, на которые не ссылается ни один контейнер": будьте осторожны перед использованием -a
,
Как показано в ответе A L, 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!=...
используется) указанные метки.
См. " Обрезать изображения " для примера.
Оригинальный ответ (сентябрь 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")'
Как отмечает 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
, Нетерпеливый может пропустить подсказку с -f, --force
опция:
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
Если вы проявили крайнюю осторожность в отношении безвозвратной потери данных, вы можете удалить неиспользуемые (висячие) тома (версии 1.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 ps -f
docker rm
docker images -f
docker rmi
- Замечания к выпуску Docker v1.9.0
docker volume ls
docker volume rm
Другие ответы великолепны, а именно:
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/
Чтобы удалить старые помеченные изображения, возраст которых превышает месяц:
$ 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
Следующая команда удалит изображения старше 48 часов.
$ docker image prune --all --filter until=48h
Предполагая, что у вас Docker 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 system prune
команда. Я считаю, что пользователи будут случайно удалять вещи, которые они не имеют в виду. Лично я собираюсь в основном использовать docker image prune
а также docker container prune
команды.
До сих пор (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 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 и восстановления пространства.
#!/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 / Библиотека / Докер
Этот путь является локальным для системы, обычно в корневом разделе "/".
Вы можете смонтировать большее дисковое пространство и переместить содержимое /var/lib/docker
к новому месту монтирования и сделайте символическую ссылку.
Таким образом, даже если образы Docker занимают место, это не повлияет на вашу систему, так как будет использоваться другое место монтирования.
Исходное сообщение: Управление образами Docker на локальном диске.
Я использую эту команду:
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 system prune -af --volumes
Если вы хотите удалить изображения, извлеченные 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 system prune -a
(Вам будет предложено подтвердить команду. Использование -f
заставить бежать, если знаешь, что делаешь.)
Поскольку у вас уже давно работает докер, место могут занимать различные элементы, а не только изображения. Чтобы узнать, что использует пространство:docker system df
см. документы
В моем случае большая часть была использована «Кэшом сборки», чтобы удалить его:docker builder prune
см. документы
@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
Первый забег docker images
чтобы увидеть список изображений и скопировать IMAGE HASH ID в буфер обмена.
Пробег docker rmi -f <Image>
Запомнить вариант -f
принудительное удаление.
docker rm `docker ps -aq`
или же
docker rm $(docker ps -q -f status=exited)
Удалите старые контейнеры несколько недель назад.
docker rm $(docker ps -a | grep "weeks" | awk '{ print $1; }')
Удалить старые изображения недель назад. Быть осторожен. Это удалит базовые изображения, которые были созданы несколько недель назад, но которые могут использовать ваши новые изображения.
docker rmi $(docker images | grep 'weeks' | awk '{ print $3; }')
Как удалить помеченное изображение
Докер RMI тег первым
Докер 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 $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
docker rm $(docker ps -faq)
docker rmi $(docker ps -faq)
-f force
-a all
-q in the mode
Чтобы удалить помеченные изображения, на которых не запущен контейнер, вам нужно будет использовать небольшой скрипт:
#!/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 выделяет и продолжает использовать дисковое пространство, даже если пространство не выделено для какого-либо конкретного образа или существующего контейнера. Последний случай, когда я сгенерировал эту проблему, случайно использовал сборку centos "docker-engine" вместо "docker" в RHEL 7.1. Кажется, что иногда случается, что очистка контейнера не завершается успешно, и тогда пространство никогда не используется повторно. Когда 80-гигабайтный диск, который я выделил как / был заполнен файлами /var/lib/docker, мне пришлось придумать творческий способ решить эту проблему.
Вот что я придумал. Сначала устраните ошибку переполнения диска:
- Остановить докер: systemctl остановить докер
- Выделен новый диск, смонтированный как скажем / 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 | sed -e '/ ^ / d' -e '/ ^ REPOSITORY / d' -e 's, [] [],:,' -e 's, [ ].,, ')> /root/docker.img
Удалить докер.
Стереть все в /var/lib/docker: rm -rf /var/lib/docker/[cdintv]*
Переустановите докер
Включить докер: systemctl включить докер
Запустить докер: systemctl запустить докер
Восстановление изображений: загрузка докера
Запустите все постоянные контейнеры, которые вам нужны.
Это уменьшило использование моего диска с 67 ГБ для докера до 6 ГБ для докера.
Я не рекомендую это для повседневного использования. Но полезно запускать, когда похоже, что докер потерял счет использованного дискового пространства из-за программных ошибок или неожиданных перезагрузок.
Если вы хотите автоматически / периодически очищать закрытые контейнеры и удалять изображения и тома, которые не используются запущенным контейнером, вы можете загрузить изображение 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 system prune
удалит:
- все остановленные контейнеры
- все сети, не используемые хотя бы одним контейнером
- все висящие изображения
- весь кеш сборки
docker system prune -a
сделает то же самое, но в дополнение к удалению всех висящих изображений, он удалит более широко:
- все изображения без связанного с ними хотя бы одного контейнера
Что такое висячие изображения?
Образы Docker состоят из нескольких слоев, которые помещаются в родительский «слой контейнера», когда общий образ контейнера генерируется из Dockerfile. Висячие изображения — это слои, которые не имеют отношения к каким-либо другим изображениям с тегами и, следовательно, никогда не будут использоваться в каких-либо новых создаваемых контейнерах. Они больше не служат цели и занимают место на диске.
Например, висячее изображение может быть создано с помощью следующего процесса:
Соберите именованный образ из Dockerfile без указания тега:
FROM ubuntu:latest
CMD ["echo", "Hello World"]
docker build -t my-image
docker images
REPOSITORY TAG IMAGE ID
my-image latest 7ed6e7202eca <--- created, not dangling
ubuntu latest 825d55fb6340
Обновите Dockerfile:
FROM ubuntu:latest
CMD ["echo", "Hello, World!"]
Восстановите изображение, повторно используя предыдущее имя, без указания тега:
docker build -t my-image
docker images
REPOSITORY TAG IMAGE ID
my-image latest da6e74196f66 <--- replacement layer
<none> <none> 7ed6e7202eca <--- previous layer, now dangling
ubuntu latest 825d55fb6340
Сборка создала новыйmy-image
слой. Как мы видим, слой, который был изначально создан, все еще существует, но его имя и тег установлены на<none>:<none>
. Этот слой никогда не сможет быть связан с каким-либо слоем контейнера докеров, что означает, что он «висит».
Что такое изображения без связанного с ними хотя бы одного контейнера?
Неиспользуемый образ означает, что он не был назначен или использован в контейнере. Например,docker ps -a
перечислит все ваши запущенные и остановленные контейнеры. Любое изображение, используемое любым из этих контейнеров, является «используемым изображением».
При запуске docker system prune -a он удалит как неиспользуемые, так и оборванные образы. Любое изображение с хотя бы одним контейнером, связанным с ним, не будет затронуто.
Если вы создаете эти обрезанные образы самостоятельно (из некоторых других, более старых базовых образов), будьте осторожны с принятыми решениями, указанными выше, на основе docker image prune
, поскольку команда тупая и попытается удалить также все зависимости, необходимые для ваших последних изображений (команду, вероятно, следует переименовать в docker image*s* prune
).
Решение, которое я придумал для конвейеров сборки изображений докеров (где есть ежедневные сборки, а теги = даты находятся в YYYYMMDD
формат) это:
# carefully narrow down the image to be deleted (to avoid removing useful static stuff like base images)
my_deleted_image=mirekphd/ml-cpu-py37-vsc-cust
# define the monitored image (tested for obsolescence), which will be usually the same as deleted one, unless deleting some very infrequently built image which requires a separate "clock"
monitored_image=mirekphd/ml-cache
# calculate the oldest acceptable tag (date)
date_week_ago=$(date -d "last week" '+%Y%m%d')
# get the IDs of obsolete tags of our deleted image
# note we use monitored_image to test for obsolescence
my_deleted_image_obsolete_tag_ids=$(docker images --filter="before=$monitored_image:$date_week_ago" | grep $my_deleted_image | awk '{print $3}')
# remove the obsolete tags of the deleted image
# (note it typically has to be forced using -f switch)
docker rmi -f $my_deleted_image_obsolete_tag_ids
Если у вас их много, удалить их может быть очень утомительно, но, к счастью для нас, в Docker есть несколько команд, которые помогут нам устранить зависшие образы. В более старых версиях Docker (и это работает и сегодня) вы можете удалить оборванные изображения самостоятельно, запустив
docker rmi -f $(docker images -f "dangling=true" -q)
.
Я обычно делаю
docker rm -f $(docker ps -a -q)
и
docker system prune
очистить все болтающиеся емкости.
[РЕШЕНО] вам нужно следить за этими темами на форумах докеров ЭТО
Еще одно решение для удаления всех контейнеров:
docker ps -a | cut -d ' ' -f 1 | xargs docker rm
cut -d ' ' -f 1
возвращает идентификаторы всех контейнеров.