1. Введение
В предыдущей статье мы объяснили разницу между образами Docker и контейнерами Docker. Вкратце: изображение похоже на класс Java, а контейнеры — на объекты Java.
В этом уроке мы рассмотрим различные способы удаления образов Docker.
2. Зачем удалять образы Docker?
Docker Engine хранит образы и запускает контейнеры. Для этой цели Docker Engine резервирует определенный объем дискового пространства в качестве «пула хранения» для образов, контейнеров и всего остального (например, глобальных томов или сетей Docker).
Как только этот пул хранения заполняется, Docker Engine перестает работать: мы больше не можем создавать или загружать новые образы, а наши контейнеры перестают работать.
Образы Docker занимают большую часть пула хранения Docker Engine . Поэтому мы удаляем образы Docker, чтобы поддерживать работу Docker .
Мы также удаляем изображения, чтобы наш Docker Engine оставался организованным и чистым . Например, мы можем легко создать десятки изображений во время разработки, которые вскоре нам больше не понадобятся. Или мы загружаем некоторые образы программного обеспечения для тестирования, от которых мы можем избавиться позже.
Мы можем легко удалить образ Docker, который мы вытащили из репозитория Docker : если он нам когда-нибудь снова понадобится, мы просто вытащим его из репозитория еще раз.
Но мы должны быть осторожны с образами Docker, которые мы создали сами: после удаления наши собственные образы пропадают, если мы их не сохранили! Мы можем сохранять образы Docker, отправляя их в репозиторий или экспортируя в файл TAR .
3. Загрузка образов бета-версии PostgreSQL 13
PostgreSQL — это реляционная база данных с открытым исходным кодом. В качестве примеров мы будем использовать первые два образа Docker бета-версии PostgreSQL 13 . Эти два изображения относительно небольшие, поэтому мы можем быстро их загрузить. И поскольку это бета-версии программного обеспечения, их еще нет в нашем Docker Engine.
Мы будем использовать образ бета-версии 2 для создания контейнера. Мы не будем использовать образ бета-версии 1 напрямую.
Но прежде чем мы загрузим эти два образа, давайте сначала проверим, сколько места образы Docker занимают в пуле хранения:
docker system df --format 'table {{.Type}}\t{{.TotalCount}}\t{{.Size}}'
Вот результат тестовой машины. Первая строка показывает, что наши 71 образ Docker используют 7,8 ГБ:
TYPE TOTAL SIZE
Images 71 7.813GB
Containers 1 359.1MB
Local Volumes 203 14.54GB
Build Cache 770 31.54GB
Теперь мы загружаем два образа PostgreSQL и перепроверяем пул хранения Docker:
docker pull postgres:13-beta1-alpine
docker pull postgres:13-beta2-alpine
docker system df --format 'table {{.Type}}\t{{.TotalCount}}\t{{.Size}}'
Как и ожидалось, количество образов увеличилось с 71 до 73. А общий размер образа увеличился с 7,8 ГБ до 8,1 ГБ.
Мы просто покажем первую строку для краткости:
TYPE TOTAL SIZE
Images 73 8.119GB
4. Удаление одного изображения
Запустим контейнер с образом PostgreSQL 13 beta 2. Мы установили secr3t
в качестве пароля для пользователя root базы данных, потому что без него контейнер PostgreSQL не запустится:
docker run -d -e POSTGRES_PASSWORD=secr3t postgres:13-beta2-alpine
docker ps --format 'table {{.ID}}\t{{.Image}}\t{{.Status}}'
Вот работающий контейнер на тестовой машине:
CONTAINER ID IMAGE STATUS
527bfd4cfb89 postgres:13-beta2-alpine Up Less than a second
Теперь давайте удалим образ PostgreSQL 13 beta 2. Мы используем docker image rm
для удаления образа Docker . Эта команда удаляет одно или несколько изображений:
docker image rm postgres:13-beta2-alpine
Эта команда завершается ошибкой, потому что работающий контейнер все еще использует этот образ:
Error response from daemon: conflict: unable to remove repository reference "postgres:13-beta2-alpine" (must force) - container 527bfd4cfb89 is using its referenced image cac2ee40fa5a
Итак, давайте остановим этот запущенный контейнер, используя его идентификатор, который мы получили от docker ps
:
docker container stop 527bfd4cfb89
Теперь мы снова пытаемся удалить образ — и получаем то же сообщение об ошибке: Мы не можем удалить образ, используемый контейнером, работающим или нет .
Итак, убираем контейнер. Затем мы можем, наконец, удалить изображение:
docker container rm 527bfd4cfb89
docker image rm postgres:13-beta2-alpine
Docker Engine распечатывает сведения об удалении образа:
Untagged: postgres:13-beta2-alpine
Untagged: postgres@sha256:b3a4ebdb37b892696a7bd7e05763b938345f29a7327fc17049c7148c03ff6a92
removed: sha256:cac2ee40fa5a40f0abe53e0138033fe7a9bcee28e7fb6c9eaac4d3a2076b1a86
removed: sha256:6a14bab707274a8007da33fe08ea56a921f356263d8fd5e599273c7ee4880170
removed: sha256:5e6ef40b9f6f8802452dbca622e498caa460736d890ca20011e7c79de02adf28
removed: sha256:dbd38ed4b347c7f3c81328742a1ddeb1872ad52ac3b1db034e41aa71c0d55a75
removed: sha256:23639f6bd6ab4b786e23d9d7c02a66db6d55035ab3ad8f7ecdb9b1ad6efeec74
removed: sha256:8294c0a7818c9a435b8908a3bcccbc2171c5cefa7f4f378ad23f40e28ad2f843
Docker system df
подтверждает удаление: количество образов уменьшилось с 73 до 72. А общий размер образа увеличился с 8,1 ГБ до 8,0 ГБ:
TYPE TOTAL SIZE
Images 72 7.966GB
5. Удаление нескольких изображений по имени
Давайте снова загрузим образ PostgreSQL 13 beta 2, который мы только что удалили в предыдущем разделе:
docker pull postgres:13-beta2-alpine
Теперь мы хотим удалить как образ бета-версии 1, так и образ бета-версии 2 по имени. Пока мы использовали только изображение бета-версии 2. Как упоминалось ранее, мы не используем образ бета-версии 1 напрямую, поэтому мы можем просто удалить его сейчас.
К сожалению, docker image rm
не предлагает фильтр для удаления по имени. Вместо этого мы объединим команды Linux для удаления нескольких изображений по имени .
Мы будем ссылаться на образы по репозиторию и тегу, как в команде docker pull
: репозиторий — postgres
, метки — 13-beta1-alpine
и 13-beta2-alpine
.
Итак, чтобы удалить несколько изображений по имени, нам нужно:
- Список всех изображений по репозиторию и тегу, например,
postgres:13-beta2-alpine
- Затем отфильтруйте эти выходные строки с помощью регулярного выражения с помощью команды
grep
:^postgres:13-beta
- И, наконец, передайте эти строки команде docker
image rm .
Давайте начнем собирать их вместе. Чтобы проверить правильность, давайте запустим только первые две из этих частей:
docker image ls --format '{{.Repository}}:{{.Tag}}' | grep '^postgres:13-beta'
И на нашей тестовой машине получаем:
postgres:13-beta2-alpine
postgres:13-beta1-alpine
Теперь, учитывая это, мы можем добавить его в нашу команду rm образа docker
:
docker image rm $(docker image ls --format '{{.Repository}}:{{.Tag}}' | grep '^postgres:13-beta')
Как и прежде, мы можем удалять образы только в том случае, если ни один контейнер, работающий или остановленный, их не использует. Затем мы видим те же детали удаления изображения, что и в предыдущем разделе. И docker system df
показывает, что мы вернулись к 71 образу размером 7,8 ГБ на тестовой машине:
TYPE TOTAL SIZE
Images 71 7.813GB
Эта команда удаления изображения работает в терминале на Linux и Mac. В Windows для этого требуется «Терминал быстрого запуска Docker» из Docker Toolbox . В будущем более поздняя версия Docker Desktop для Windows может работать с этой командой Linux и в Windows 10 .
6. Удаление изображений по размеру
Отличный способ сэкономить место на диске — сначала удалить самые большие образы Docker.
Теперь docker image ls
также не может сортировать по размеру. Итак, мы перечисляем все изображения и сортируем вывод с помощью команды sort
для просмотра изображений по размеру :
docker image ls | sort -k7 -h -r
который на нашей тестовой машине выводит:
collabora/code 4.2.5.3 8ae6850294e5 3 weeks ago 1.28GB
nextcloud 19.0.1-apache 25b6e2f7e916 6 days ago 752MB
nextcloud latest 6375cff75f7b 5 weeks ago 750MB
nextcloud 19.0.0-apache 5c44e8445287 7 days ago 750MB
Затем мы вручную просматриваем, чтобы найти то, что мы хотим удалить. Идентификатор в третьем столбце легче скопировать и вставить, чем репозиторий и тег в первом и втором столбцах. Docker позволяет удалять несколько образов за один раз.
Допустим, мы хотим удалить nextcloud:latest
и nextcloud:19.0.0-apache
. Проще говоря, мы можем просмотреть их соответствующие идентификаторы в нашей таблице и перечислить их в нашей команде rm образа docker
:
docker image rm 6375cff75f7b 5c44e8445287
Как и прежде, мы можем удалять только изображения, не используемые каким-либо контейнером, и видеть обычные сведения об удалении изображений. Теперь на нашей тестовой машине осталось 69 изображений размером 7,1 ГБ:
TYPE TOTAL SIZE
Images 69 7.128GB
7. Удаление изображений по дате создания
Docker может удалять образы по дате их создания . Для этого мы будем использовать новую команду docker image prune
. В отличие от docker image rm
, он предназначен для удаления нескольких образов или даже всех образов.
Теперь давайте удалим все изображения, созданные до 7 июля 2020 года:
docker image prune -a --force --filter "until=2020-07-07T00:00:00"
Мы по-прежнему можем удалять только изображения, не используемые каким-либо контейнером, и мы по-прежнему видим обычные сведения об удалении изображений. Эта команда удалила два образа на тестовой машине, поэтому у нас 67 образов и 5,7 ГБ на тестовой машине:
TYPE TOTAL SIZE
Images 67 5.686GB
Другой способ удалить изображения по дате их создания — указать временной интервал вместо даты отсечки. Допустим, мы хотели удалить все изображения старше недели:
docker image prune -a --force --filter "until=168h"
Обратите внимание, что опция фильтра Docker требует от нас конвертировать этот промежуток времени в часы.
8. Обрезка контейнеров и образов
docker image prune
— массовое удаление неиспользуемых образов . Он идет рука об руку с docker container prune
, который массово удаляет остановленные контейнеры . Начнем с последней команды:
docker container prune
Это печатает предупреждающее сообщение. Мы должны ввести y
и нажать Enter
, чтобы продолжить:
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
removed Containers:
1c3be3eba8837323820ecac5b82e84ab65ad6d24a259374d354fd561254fd12f
Total reclaimed space: 359.1MB
Таким образом, на тестовой машине был удален один остановленный контейнер.
Теперь нам нужно кратко обсудить отношения изображений. Наши образы Docker расширяют другие образы, чтобы получить их функциональность, так же как классы Java расширяют другие классы Java.
Давайте посмотрим на верхнюю часть Dockerfile для образа PostgreSQL beta 2 , чтобы увидеть, какой образ он расширяет:
FROM alpine:3.12
Таким образом, образ бета-версии 2 использует alpine:3.12
. Вот почему Docker неявно загрузил alpine:3.12
, когда мы сначала вытащили образ бета-версии 2. Мы не видим эти неявно загруженные образы с помощью docker image ls
.
Теперь предположим, что мы удалили образ PostgreSQL 13 beta 2. Если бы ни один другой образ Docker не расширял alpine:3.12
, то Docker считал бы alpine:3.12
так называемым «висячим образом»: когда-то неявно загруженным образом, который теперь больше не нужен. docker image prune
удаляет эти висячие образы:
docker image prune
Эта команда также требует от нас ввести y
и нажать Enter
, чтобы продолжить:
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
На тестовой машине это не удаляло никаких изображений.
docker image prune -a
удаляет все образы, не используемые контейнерами . Итак , если у нас нет контейнеров (работающих или нет), это удалит все образы Docker ! Это действительно опасная команда:
docker image prune -a
На тестовой машине это удалило все изображения. docker system df
подтверждает, что ни контейнеров, ни образов не осталось:
TYPE TOTAL SIZE
Images 0 0B
Containers 0 0B
9. Принудительно удалить контейнеры и образы
Команда docker prune
удаляет остановленные контейнеры и висящие образы. Но что, если мы хотим удалить все образы Docker с нашей машины. Для этого нам сначала нужно удалить все контейнеры Docker, работающие на нашей машине, а затем удалить образы Docker:
docker rm -f $(docker ps -qa)
Эта команда удалит все контейнеры. Флаг -f
используется для принудительного удаления запущенных контейнеров Docker.
Теперь давайте удалим все образы Docker с помощью команды docker rmi
:
docker rmi -f $(docker images -aq)
Docker images -qa
вернет идентификатор изображения всех образов Docker. Затем команда docker rmi
удалит все образы один за другим. Опять же, флаг -f
используется для принудительного удаления образа Docker.
Поскольку все контейнеры Docker уже были удалены с машины, мы также можем использовать команду docker image prune
, чтобы удалить все образы Docker сейчас.
10. Заключение
В этой статье мы впервые увидели, как можно удалить один образ Docker. Далее мы узнали, как удалять изображения по имени, размеру или дате создания. Наконец-то мы научились удалять все неиспользуемые контейнеры и образы.