Борьба с утечками дискового пространства: логи, снапшоты, Docker-образы | AdminWiki

Борьба с утечками дискового пространства: логи, снапшоты, Docker-образы

24 июля 2026 11 мин. чтения

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

Четыре главных потребителя места, которые маскируются под полезную нагрузку: неконтролируемые логи приложений, сиротские образы и тома Docker, снапшоты ZFS без политики жизненного цикла и переполненный tmpfs, вытесняющий данные в swap. Каждый из этих источников требует своего подхода к диагностике и очистке. Разберём их последовательно, от быстрого аудита до полной автоматизации.

Диагностика: как найти, что занимает место

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

Быстрый аудит с df и du

Команда df -h показывает заполнение всех смонтированных файловых систем в человекочитаемом формате. Это первая команда при инциденте - она сразу укажет на проблемный раздел.

df -h

Типичный вывод:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        50G   48G  2.0G  96% /
/dev/sdb1       200G  180G   20G  90% /data

Корневой раздел заполнен на 96% - критический уровень. Теперь нужно найти, какие каталоги потребляют пространство. Для этого используйте du с сортировкой:

du -sh /var/* | sort -rh | head -10

Эта команда покажет топ-10 крупнейших подкаталогов в /var. Обычно лидируют /var/log, /var/lib/docker и /var/lib/snapd. Для поиска отдельных крупных файлов по всей системе:

find / -type f -size +500M -exec ls -lh {} \; 2>/dev/null

Эта команда найдёт все файлы крупнее 500 МБ. Полезна для обнаружения забытых дампов баз данных, несжатых логов и ISO-образов. Если нужно быстро оценить ситуацию и действовать - используйте шпаргалку по df и du с готовыми командами для экстренной диагностики.

Интерактивный анализ с ncdu

Утилита ncdu (NCurses Disk Usage) предоставляет интерактивный интерфейс для навигации по файловой системе прямо в терминале. Установка:

apt install ncdu   # Debian/Ubuntu
yum install ncdu   # RHEL/CentOS

Запуск анализа корневого раздела:

ncdu /

Интерфейс показывает дерево каталогов с размерами, позволяет перемещаться стрелками и удалять файлы нажатием клавиши d. Это безопаснее, чем ручное удаление через rm, так как вы видите контекст. Для больших файловых систем сканирование может занять несколько минут. Ускорить его можно, исключив сетевые и псевдо-файловые системы:

ncdu -x /

Флаг -x ограничивает анализ одной файловой системой, пропуская точки монтирования. После выявления проблемных каталогов переходите к целевой очистке.

Очистка логов: настройка logrotate

Логи - самая частая причина внезапного заполнения диска. Одна ошибка в приложении, зацикленная в бесконечный вывод, способна сгенерировать гигабайты записей за минуты. Стандартный механизм контроля - утилита logrotate, которая сжимает, ротирует и удаляет старые логи по расписанию.

Базовая настройка находится в /etc/logrotate.conf, а конфигурации отдельных сервисов - в /etc/logrotate.d/. Типовой конфиг для веб-сервера решает задачу контроля размера логов без потери данных для отладки.

Типовой конфиг для веб-сервера

Создайте файл /etc/logrotate.d/nginx со следующим содержимым:

/var/log/nginx/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

Разбор параметров:

  • daily - ротация раз в сутки. Для высоконагруженных серверов замените на size 100M, чтобы ротировать по достижении порога
  • rotate 7 - хранить 7 архивных копий. При ежедневной ротации это неделя истории
  • compress - сжимать старые логи gzip, экономя до 90% места
  • delaycompress - отложить сжатие на один цикл, чтобы последний ротированный файл оставался доступным без распаковки
  • missingok - не выдавать ошибку, если файл лога отсутствует
  • notifempty - не ротировать пустые файлы
  • postrotate - отправить сигнал USR1 процессу nginx для переоткрытия файловых дескрипторов

Принудительный запуск для проверки конфигурации:

logrotate -f /etc/logrotate.conf

После выполнения проверьте, что в /var/log/nginx/ появились сжатые файлы с расширением .gz, а текущий лог-файл очищен или переименован.

Решение проблем: когда logrotate не работает

Распространённая ситуация: logrotate отрабатывает по расписанию, но место не освобождается. Причина - приложение удерживает открытый файловый дескриптор удалённого файла. Файл исчезает из директории, но пространство не возвращается до перезапуска процесса или закрытия дескриптора.

Проверьте, какие процессы держат удалённые файлы:

lsof | grep deleted

Решение - параметр copytruncate в конфиге logrotate. Он копирует содержимое лога в новый файл и обрезает оригинал, не требуя переоткрытия дескриптора:

/var/log/myapp/*.log {
    size 50M
    rotate 5
    compress
    copytruncate
    missingok
    notifempty
}

Недостаток copytruncate: между копированием и обрезанием возможна потеря нескольких записей. Для критичных логов используйте postrotate с перезагрузкой сервиса. Проверить, что logrotate вообще запускается cron, можно через логи:

grep logrotate /var/log/syslog | tail -20

Борьба с Docker: образы, контейнеры и тома

Docker накапливает мусор агрессивно. Каждая сборка образа создаёт новые слои, остановленные контейнеры хранят свою файловую систему, а неиспользуемые тома остаются после удаления контейнеров. На production-сервере с частыми деплоями Docker способен занять десятки гигабайт за неделю.

Анализ использования диска Docker

Команда docker system df показывает агрегированную статистику, а с флагом -v - детальный расклад по каждому объекту:

docker system df -v

Вывод разбит на категории:

  • Images - слои образов. Колонка SHARED SIZE показывает, сколько места разделяется между образами
  • Containers - размер файловой системы каждого контейнера. Остановленные контейнеры тоже занимают место
  • Local Volumes - именованные и анонимные тома
  • Build Cache - кэш сборки BuildKit, который может достигать гигабайт

Для быстрой оценки объёма мусора сравните колонки SIZE и SHARED SIZE в секции Images. Если разница велика, значит много уникальных слоёв, которые не используются запущенными контейнерами.

Безопасная очистка: что и когда удалять

Золотое правило: удаляйте только те объекты, которые не связаны с запущенными контейнерами. Docker не даст удалить образ, используемый активным контейнером, но том, примонтированный к контейнеру, может быть удалён принудительно.

Пошаговая очистка от частного к общему:

# 1. Удалить все остановленные контейнеры
docker container prune -f

# 2. Удалить неиспользуемые образы (без тегов или не связанные с контейнерами)
docker image prune -a -f

# 3. Удалить неиспользуемые тома
docker volume prune -f

# 4. Удалить неиспользуемые сети
docker network prune -f

Флаг -f подавляет запрос подтверждения - необходим для автоматизации. Единая команда для полной очистки:

docker system prune -a --volumes -f

Параметр -a удаляет все неиспользуемые образы, не только висячие слои. Параметр --volumes удаляет неиспользуемые тома. Эта команда освобождает максимум места, но требует осторожности: убедитесь, что среди томов нет данных, которые могут понадобиться для восстановления.

Для углублённого управления Docker-образами и автоматизации очистки в production-среде изучите руководство по полной очистке Docker с готовыми скриптами Bash и PowerShell. Если задача шире - безопасное обновление образов и сканирование уязвимостей - обратитесь к материалу по управлению Docker-образами в production.

Снапшоты ZFS: скрытый пожиратель места

Снапшоты ZFS - мощный инструмент для восстановления данных, но без политики жизненного цикла они накапливаются и потребляют гигабайты пространства. Механика такова: снапшот фиксирует состояние датасета на момент создания. При изменении или удалении файлов в основном датасете блоки, на которые ссылается снапшот, не освобождаются. Чем активнее изменяются данные, тем быстрее растёт занятое снапшотами пространство.

Просмотр и оценка объема снапшотов

Список всех снапшотов с объёмом занимаемого пространства:

zfs list -t snapshot -o name,used,referenced,creation

Колонка USED показывает, сколько места занимает снапшот с учётом всех дочерних клонов. Для оценки суммарного объёма всех снапшотов конкретного датасета:

zfs list -o space tank/data

Вывод покажет колонку USEDSNAP - общий объём, занятый всеми снапшотами датасета. Если это значение превышает 20-30% от размера датасета, пора чистить.

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

Удаление снапшотов в TrueNAS

В веб-интерфейсе TrueNAS перейдите в Storage → Snapshots. Отметьте снапшоты для удаления и нажмите Delete. Интерфейс показывает размер каждого снапшота и датасет, к которому он относится.

Для массового удаления через CLI используйте шаблоны. Удаление всех снапшотов датасета с префиксом auto-:

zfs destroy tank/data@auto-%

Удаление снапшотов старше определённой даты - через скрипт:

#!/bin/bash
# Удаление снапшотов tank/data старше 30 дней
zfs list -t snapshot -o name,creation -H tank/data | \
  while read snap date; do
    snap_date=$(date -d "$date" +%s)
    threshold=$(date -d "30 days ago" +%s)
    if [ $snap_date -lt $threshold ]; then
      zfs destroy "$snap"
      echo "Удалён $snap от $date"
    fi
  done

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

Временные файлы и tmpfs: не забывайте про RAM-диски

tmpfs - файловая система, размещённая в оперативной памяти. Каталоги /tmp, /run, /dev/shm часто монтируются как tmpfs для ускорения доступа. Проблема возникает, когда tmpfs переполняется: система начинает вытеснять данные в swap, который находится на диске. Так временные файлы в памяти косвенно отъедают дисковое пространство.

Проверка заполнения tmpfs:

df -h /tmp /run /dev/shm

Если использование приближается к 100%, найдите крупные файлы:

du -sh /tmp/* | sort -rh | head -10

Очистка временных файлов старше 7 дней:

find /tmp -type f -atime +7 -delete

Для предотвращения переполнения ограничьте размер tmpfs в /etc/fstab:

tmpfs /tmp tmpfs defaults,size=2G 0 0

После изменения перемонтируйте раздел:

mount -o remount /tmp

Ограничение размера не даёт tmpfs занять всю доступную память и вытеснить критически важные процессы в swap. Для серверов с небольшим объёмом RAM (до 8 ГБ) ставьте лимит 1-2 ГБ. Для серверов с 32+ ГБ можно выделить 4-8 ГБ под /tmp, если приложения активно используют временные файлы.

Автоматизация очистки: cron-задания

Ручная очистка решает проблему разово. Автоматизация предотвращает её повторение. Cron-задания выполняют команды по расписанию без участия администратора. Логирование вывода позволяет отслеживать, что именно было удалено и когда.

Cron для Docker: еженедельная глубокая очистка

Добавьте в crontab запись, которая запускает полную очистку Docker каждое воскресенье в 3 часа ночи:

0 3 * * 0 docker system prune -af --volumes >> /var/log/docker-cleanup.log 2>&1

Разбор синтаксиса cron:

  • 0 - минута (0-59)
  • 3 - час (0-23)
  • * - день месяца (1-31, * - каждый)
  • * - месяц (1-12)
  • 0 - день недели (0-7, где 0 и 7 - воскресенье)

Конструкция >> /var/log/docker-cleanup.log 2>&1 направляет и stdout, и stderr в лог-файл для последующего аудита.

Cron для снапшотов ZFS: удаление старых копий

Создайте скрипт /usr/local/bin/zfs-cleanup.sh:

#!/bin/bash
# Удаление снапшотов с префиксом auto- старше 30 дней
DATASET="tank/data"
PREFIX="auto-"
RETENTION_DAYS=30

zfs list -t snapshot -o name,creation -H "$DATASET" | \
  grep "@${PREFIX}" | \
  while read snap date; do
    snap_epoch=$(date -d "$date" +%s)
    threshold=$(date -d "$RETENTION_DAYS days ago" +%s)
    if [ $snap_epoch -lt $threshold ]; then
      zfs destroy "$snap" && echo "$(date): Удалён $snap"
    fi
  done

Сделайте скрипт исполняемым и добавьте в crontab:

chmod +x /usr/local/bin/zfs-cleanup.sh
# Запуск каждую субботу в 2:00
0 2 * * 6 /usr/local/bin/zfs-cleanup.sh >> /var/log/zfs-cleanup.log 2>&1

Для комплексной автоматизации задач обслуживания TrueNAS, включая бэкап конфигурации и интеграцию с системами мониторинга, используйте руководство по маршрутизации процессов в TrueNAS. Если вам нужны готовые скрипты для автоматизации резервного копирования и мониторинга ZFS с интеграцией в Zabbix и Prometheus - обратитесь к материалу со скриптами Python и Bash для DevOps.

Мониторинг и алерты: как не пропустить проблему

Автоматическая очистка снижает риск, но не исключает его. Сбой cron, аварийный рост логов из-за ошибки приложения, внезапное заполнение раздела - эти ситуации требуют мониторинга и оповещений. Два уровня контроля: логирование факта выполнения очистки и алерты по порогу свободного места.

Логирование очистки в syslog

Cron по умолчанию пишет в syslog, но для удобства аудита настройте отдельный файл. Создайте конфиг /etc/rsyslog.d/50-cron-cleanup.conf:

# Логирование задач очистки в отдельный файл
:programname, isequal, "CRON" /var/log/cron-cleanup.log
& stop

Перезапустите rsyslog:

systemctl restart rsyslog

Проверка выполнения cron-задач за последние сутки:

grep "$(date +%b\ %d)" /var/log/cron-cleanup.log | grep -E "docker|zfs|logrotate"

Альтернативный способ через journalctl:

journalctl -u cron --since "24 hours ago" | grep -E "docker|zfs"

Настройка триггера в Zabbix

Стандартный шаблон Zabbix для Linux включает мониторинг дискового пространства через ключ vfs.fs.size[/,pfree]. Он возвращает процент свободного места на корневом разделе. Создайте триггер с порогом срабатывания:

  • Warning: свободного места меньше 20%
  • High: свободного места меньше 10%
  • Disaster: свободного места меньше 5%

Выражение триггера для уровня High:

{host:vfs.fs.size[/,pfree].last()}<10

Настройте действие (Action) с эскалацией:

  1. Шаг 1 (мгновенно): отправка алерта в Telegram
  2. Шаг 2 (через 30 минут): повтор алерта + email администратору
  3. Шаг 3 (через 1 час): запуск скрипта экстренной очистки через удалённую команду

Для интеграции Zabbix с Telegram создайте медиа-тип с API-токеном бота и ID чата. Тестовое сообщение подтвердит работоспособность канала.

Отдельно настройте мониторинг разделов, где расположены Docker (/var/lib/docker) и датасеты ZFS. Для каждого раздела создайте свой элемент данных и триггер. Это даст гранулярный контроль и позволит определить источник заполнения до того, как он затронет всю систему.

Если вам нужен облачный хостинг с гибким масштабированием ресурсов для тестовых сред и production-нагрузок, рассмотрите облачную инфраструктуру Timeweb Cloud с поддержкой VDS, Kubernetes и управляемых баз данных.

Поделиться:
Сохранить гайд? В закладки браузера