DevOps

Как очистить кэш Docker и освободить место в системе

Сколько дискового пространства использует Docker?
Первый шаг - узнать, сколько дискового пространства использует Docker. Мы можем использовать команду docker system df, чтобы получить представление о том, сколько дискового пространства занимают различные артефакты.

docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 138 34 36.18GB 34.15GB (94%)
Containers 74 18 834.8kB 834.6kB (99%)
Local Volumes 118 6 15.31GB 15.14GB (98%)
Build Cache 245 0 1.13GB 1.13GB

Docker использует 36,18 ГБ для образов, 834,8 кБ для контейнеров, 15,31 ГБ для локальных томов и 1,13 ГБ для кэша сборки Docker. В общей сложности это
около 50 ГБ пространства, и большая его часть может быть освобождена.

Какое пространство мы можем вернуть без ущерба для производительности сборки Docker?
Удаление неиспользуемых образов и слоев Docker в целом вполне безопасно - если только вы не собираете в CI. Для CI очистка слоев может повлиять на производительность, поэтому лучше этого не делать. Вместо этого перейдите к нашему разделу, посвященному CI.

Удаление контейнеров из кэша Docker
Мы можем использовать команду docker container prune, чтобы очистить дисковое пространство, используемое контейнерами. Эта команда удалит все остановленные контейнеры из системы.

Мы можем опустить флаг -f здесь и в последующих примерах, чтобы получить запрос на подтверждение перед удалением артефактов.

docker container prune -f
Deleted Containers:
399d7e3679bf9b14a1c7045cc89c056f2efe31d0a32f186c5e9cb6ebbbf42c8e
 
Total reclaimed space: 834.6kB

Какие контейнеры не используются?
Мы можем узнать идентификаторы неиспользуемых контейнеров, выполнив команду docker ps с фильтрами по статусу контейнера. Контейнер считается неиспользуемым, если он имеет статус exited или dead.

docker ps --filter status=exited --filter status=dead -q
11bc2aa92622
355901f38ecb
263e9bde1f24

Если мы хотим узнать размер неиспользуемого контейнера, мы можем заменить флаг -q на -s, чтобы получить размер и другие метаданные о контейнере.

Удаление всех контейнеров
Если мы хотим удалить все контейнеры из системы, мы можем остановить все запущенные контейнеры, а затем использовать ту же команду prune. Для этого нужно передать вывод docker ps -q в команду docker stop или docker kill, если вы хотите уничтожить контейнер принудительно.

docker stop $(docker ps -q)
docker container prune

Другой вариант - команда docker rm, которую можно использовать вместе с командой docker ps -a -q для удаления всех контейнеров.Другой вариант - это docker rm команда, с которой можно использовать docker ps -a -q удалить все контейнеры.

docker rm $(docker ps -a -q)

Команда docker rm принудительно удаляет запущенный контейнер по сигналу SIGKILL. Это то же самое, что и команда docker kill. Команда docker ps -a -q выведет список всех контейнеров в системе, включая запущенные, и передаст его в команду docker rm.

Удаление образов
Образы Docker могут занимать значительный объем дискового пространства. Мы накапливаем новые образы при изменении базовых образов или создаем новые, например, с помощью docker build. Мы можем использовать команду docker image prune для удаления неиспользуемых образов из системы.

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

docker image prune -f
Deleted Images:
deleted: sha256:6f096c9fa1568f7566d4acaf57d20383851bcc433853df793f404375c8d975d6
...
 
Total reclaimed space: 2.751GB

Мы освободили более 2,7 ГБ пространства за счет удаления висящих изображений. Но, если вспомнить вывод команды df нашей системы docker, у нас есть 34,15 ГБ восстанавливаемых образов.

Откуда взялось остальное пространство? Это образы в нашей системе, которые помечены или связаны с контейнером. Мы можем выполнить команду docker image prune- a, чтобы принудительно удалить и эти образы, предполагая, что они не используются.

docker image prune -a -f
Deleted Images:
untagged: k8s.gcr.io/etcd:3.4.13-0
untagged: k8s.gcr.io/etcd@sha256:4ad90a11b55313b182afc186b9876c8e891531b8db4c9bf1541953021618d0e2
deleted: sha256:0369cf4303ffdb467dc219990960a9baa8512a54b0ad9283eaf55bd6c0adb934
deleted: sha256:f3cecccfe2bea1cbd18db5eae847c3a9c8253663bf30a41288f541dc1470b41e
 
Total reclaimed space: 22.66GB

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

Удаление томов
Тома никогда не очищаются автоматически в Docker, потому что они могут содержать ценные данные. Но если мы знаем, что данные в томе нам больше не нужны, мы можем удалить его с помощью команды docker volume prune. При этом удаляются все анонимные тома, не используемые никакими контейнерами.

docker volume prune -f
Total reclaimed space: 0B

Интересно, что мы видим, что не освободили ни одного места. Это потому, что у нас есть тома, связанные с контейнерами. Мы можем увидеть эти тома, выполнив команду docker volume ls.

DRIVER VOLUME NAME
local 0a44f085adc881ac9bb9cdcd659c28910b11fdf4c07aa4c38d0cca21c76d4ac4
local 0d3ee99b36edfada7834044f2caa063ac8eaf82b0dda8935ae9d8be2bffe404c
...

Мы получаем вывод, в котором указаны драйвер и имя тома. Команда docker volume prune удаляет только анонимные тома. Эти тома не имеют имени и конкретного названия.

docker volume prune -a -f
Deleted Volumes:
c0c240b680d70fffef420b8699eeee3f0a49eec4cc55706036f38135ae121be0
2ce324adb91e2e6286d655b7cdaaaba4b6b363770d01ec88672e26c3e2704d9e
 
Total reclaimed space: 15.31GB

Удаление кэша сборки
Чтобы удалить кэш сборки Docker, мы можем выполнить команду docker buildx prune, чтобы очистить кэш сборки от сборщика по умолчанию.

docker buildx prune -f
ID RECLAIMABLE SIZE LAST ACCESSED
pw11qgl0xs4zwy533i2x61pef* true 54B 12 days ago
y37tt0kfwn1px9fnjqwxk7dnk true 0B 12 days ago
sq3f8r0qrqh4rniemd396s5gq* true 154.1kB 12 days ago
 
Total: 5.806GB

Если мы хотим удалить кэш сборки для конкретного сборщика, мы можем использовать флаг --builder, чтобы указать имя сборщика.

docker buildx prune --builder builder-name -f

Удаление сетей
Хотя сети Docker не занимают дискового пространства на нашей машине, они создают сетевые мосты, iptables и записи в таблице маршрутизации. Поэтому, как и в случае с другими артефактами, мы можем удалить неиспользуемые сети с помощью команды docker network prune, чтобы очистить их.

docker network prune -f
Deleted Networks:
test-network-1

Удаление всего с помощью docker system prune
Эквивалент docker clean all более известен как Docker prune. Мы можем удалить все неиспользуемые артефакты, созданные Docker, запустив docker system prune. При этом будут удалены все неиспользуемые контейнеры, образы, сети и кэш сборки.

docker system prune -f
Deleted Images:
deleted: sha256:93477d5bde9ef0d3d7d6d2054dc58cbce1c1ca159a7b33a7b9d23cd1fe7436a3
 
Deleted build cache objects:
6mm1daa19k1gdijlde3l2bidb
vq294gub98yx8mjgwila989k1
xd2x5q3s6c6dh5y9ruazo4dlm
 
Total reclaimed space: 419.6MB

По умолчанию Docker prune не удаляет тома и удаляет только висящие образы Docker. Мы можем использовать флаг --volumes, чтобы также удалить тома. Мы также можем добавить флаг -a, чтобы удалить все образы, не связанные с контейнером.

docker system prune --volumes -af

Управление кэшем сборок Docker в CI
Если вы собираете образы Docker в среде CI, вы, конечно, можете использовать и вышеприведенные команды. Однако ваши сборки могут не в полной мере использовать преимущества кэша сборок Docker по следующим структурным причинам:

В среде CI с эфемерными бегунами, такими как GitHub Actions или GitLab CI, кэш сборок не сохраняется во всех сборках без сохранения/загрузки по сети куда-нибудь за пределы эфемерного бегуна. Сохранение и загрузка кэша происходят медленно из-за низкой скорости передачи данных по сети.

По умолчанию все CI-бегунки являются эфемерными, если только вы не запускаете свои собственные.

Если есть дисковое пространство, оно обычно ограничено 10-15 ГБ. Таким образом, если вы создаете большие изображения с большим количеством слоев, вы, скорее всего, исчерпаете его.

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