Перейти к содержимому
Главная страница » Как почистить весь мусор Docker

Как почистить весь мусор Docker

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

Кэширование слоев

Docker использует кэширование слоёв для повторного использования ранее вычисленных результатов сборки. Каждая инструкция в Dockerfile связана со слоем, который содержит изменения, вызванные выполнением этой инструкции. 
Если предыдущие слои, а также входные данные для инструкции не изменились, а инструкция уже была выполнена и кэширована ранее, Docker будет использовать для неё кэшированный слой. В противном случае Docker перестроит этот слой и все последующие слои.

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

Одним из основных факторов, влияющих на то, сколько слоёв в вашем образе необходимо пересобрать, является порядок операций в Dockerfile.

Сколько пространства 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 позволяет освободить место на диске от неиспользуемых образов, контейнеров и томов.

Периодическая обрезка

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

docker system prune

Несколько более рискованный вариант — это:

docker system prune -a

Это также удаляет все образы, не связанные с работающим контейнером. Это может показаться немного радикальным решением, но Docker повторно загрузит все необходимые образы. Первая попытка будет немного медленнее, но затем образ будет кэширован для дальнейшего использования.

В следующих разделах описаны дополнительные способы удаления определенных элементов.

Удаление Dockerimage

Docker образ — это снимок с диска приложения, такого как веб-сервер, языковая среда выполнения или система управления базами данных. Вы можете просмотреть все изображения, как активные, так и висячие (те, которые не связаны с контейнером), введя:

docker image ls -a

Изображение Docker можно удалить, введя:

docker image rm <name_or_id>

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

Удаление неиспользуемых Docker образов

Для удаления неиспользуемых образов из системы мы можем использовать команду docker image prune.

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

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

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

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

docker image prune -a -fDeleted Images:untagged: k8s.gcr.io/etcd:3.4.13-0untagged: k8s.gcr.io/etcd@sha256:4ad90a11b55313b182afc186b9876c8e891531b8db4c9bf1541953021618d0e2deleted: sha256:0369cf4303ffdb467dc219990960a9baa8512a54b0ad9283eaf55bd6c0adb934deleted: sha256:f3cecccfe2bea1cbd18db5eae847c3a9c8253663bf30a41288f541dc1470b41e Total reclaimed space: 22.66GB

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

Удаление Docker контейнера

Docker контейнер — это запущенный экземпляр образа, и любое количество контейнеров может быть запущено из одного и того же. Контейнеры обычно небольшие, потому что они не имеют состояния и ссылаются на файловую систему образа. Просмотрите все контейнеры, как запущенные, так и остановленные, введя:

docker container ls -a

Вы можете удалить контейнер только после его остановки. Остановите контейнеры, введя:

docker container stop <name_or_id>

Затем контейнеры можно удалить, введя:

docker container rm <name_or_id>

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

Обычно нет необходимости сохранять остановленные контейнеры. Опцию — rm можно добавить к любой docker run команде, чтобы автоматически удалять контейнер после его завершения.

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

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

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

Какие контейнеры не используются?

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

docker ps --filter status=exited --filter status=dead -q11bc2aa92622355901f38ecb263e9bde1f24

Удаление всех контейнеров

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

Приведение в порядок сети

Контейнеры могут быть подключены к управляемой Docker сети, чтобы они могли взаимодействовать друг с другом. Это файлы конфигурации, которые не занимают много места на диске. Чтобы просмотреть все сети Docker, введите:

docker network ls

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

docker network rm <name_or_id>

Опять же, в эту команду можно добавить любое количество сетевых имён/идентификаторов, разделённых пробелами.

Удаление томов

Docker Том — это образ виртуального диска. Его необходимо прикрепить к работающему контейнеру, чтобы он мог сохранять файлы или другую информацию о состоянии между перезапусками. Размеры тома зависят от приложения, использующего его, но типичной базе данных потребуется несколько сотен мегабайт пространства, даже если она в основном пуста.

Просмотрите все дисковые тома, управляемые Docker, введя:

docker volume ls

При удалении тома Docker все его данные будут безвозвратно удалены! Вернуться назад будет невозможно.

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

Большинство систем баз данных предоставляют инструмент для резервного копирования, такой как mysqldump утилита в MySQL. Их можно запустить в работающем контейнере с помощью docker exec команды.

Следующая команда Linux/macOS создает резервную копию базы данных MySQL с именем mydb, работающей в контейнере с именем mysql, в файл с именем backup.sql. Используется пользователь MySQL root с паролем mysecret:

docker exec mysql /usr/bin/mysqldump -u root -pmysecret mydb > backup.sql

эквивалентная команда для Windows PowerShell:

docker exec mysql /usr/bin/mysqldump -u root -pmysecret -r mydb | Set-Content backup.sql

Вы также можете копировать файлы данных в работающий контейнер или из него с помощью docker cp команды. При этом передаются пути к источнику и месту назначения, где контейнеры указываются по имени/идентификатору, за которым следует двоеточие и путь, например:

docker cp mycontainer:/some/file ./host/directory

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

docker volume rm <name>

Все неиспользуемые тома Docker — те, которые в данный момент не подключены к работающему контейнеру — можно удалить с помощью:

docker volume prune

В качестве альтернативы docker volume prune -a я удалю их все. Вы ведь сначала сделали резервную копию, не так ли?..

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

docker volume prune -fTotal reclaimed space: 0B

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

DRIVER    VOLUME NAMElocal     0a44f085adc881ac9bb9cdcd659c28910b11fdf4c07aa4c38d0cca21c76d4ac4local     0d3ee99b36edfada7834044f2caa063ac8eaf82b0dda8935ae9d8be2bffe404c...

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

docker volume prune -a -fDeleted Volumes:c0c240b680d70fffef420b8699eeee3f0a49eec4cc55706036f38135ae121be02ce324adb91e2e6286d655b7cdaaaba4b6b363770d01ec88672e26c3e2704d9e Total reclaimed space: 15.31GB

Полный чистый старт

Все неиспользуемые контейнеры, образы, тома и сети можно удалить с помощью одной команды:

docker system prune -a --volumes

Добавьте -f если вы хотите принудительно выполнить очистку без запроса подтверждения. Ваша система вернется в исходное состояние без каких-либо данных Docker.

Очистка файлов Docker по CRON

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

docker system prune -af  --filter "until=$((30*24))h"

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

Давайте немного разберёмся, чтобы понять, что здесь происходит:

  • Удаление неиспользуемых контейнеров в системе Docker — мы просим Docker удалить неиспользуемые контейнеры.
  • -af — здесь мы объединили два флага. Добавление флага -a заставляет Docker искать не только зависшие контейнеры, но и все контейнеры, которые больше не используются. Флаг -f просто предотвращает появление запроса на подтверждение, который обычно появляется, когда пользователь подтверждает удаление.

Только одно предупреждение: «неиспользуемые» означает «изображения, на которые не ссылается ни один контейнер»: будьте осторожны при использовании -a!

  • —filter — добавление фильтра позволяет указать возраст изображений, которые мы хотим удалить. В данном случае это любые изображения старше 30 дней или 1 месяца. Здесь мы используем базовую математику в bash, так как bash поддерживает только h (часы). Поэтому давайте вычислим 30 * 24 часа, что даст нам 1 месяц в часах, что обычно ограничивает количество контейнеров несколькими гигабайтами. Вы можете сократить это время, если у вас очень мало места на диске вашего VPS.

давайте создадим новый файл в Cron-файле для размещения нашей команды:

cd /etc/cron.daily
sudo nano docker-prune

Команда для создания нового файла в папке /etc/cron.daily/

Как только файл откроется, добавьте созданную нами команду prune и сообщите ОС, что это файл bash

#!/bin/bash
docker system prune -af  --filter "until=$((30*24))h"

содержимое файла docker-prune, который мы только что создали

После добавления команды нажмите Ctrl + O, а затем Ctrl + X, чтобы сохранить и закрыть файл

Теперь, когда мы создали файл, нам нужно сообщить операционной системе, что он должен быть исполняемым, с помощью следующей команды:

sudo chmod +x /etc/cron.daily/docker-prune

команда, чтобы сделать файл, который мы только что создали, исполняемым

И это всё. Теперь Docker будет выполнять эту команду ежедневно.

Ссылки:

How to clean your Docker data

How to clear Docker cache and free up space on your system

How to Prune Docker Images Automatically with a Daily Cron job

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *