Как правильно очистить логи для контейнера Docker?
Я использую docker logs [container-name]
чтобы увидеть логи конкретного контейнера.
Есть ли элегантный способ очистить эти журналы?
24 ответа
Из этого вопроса есть одна строка, которую вы можете запустить:
echo "" > $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)
Я не большой поклонник модификации файлов Докера напрямую. Вы можете сделать так, чтобы Docker автоматически поворачивал логи за вас. Это делается с помощью дополнительных флагов для dockerd, если вы используете драйвер ведения журнала JSON по умолчанию:
dockerd ... --log-opt max-size=10m --log-opt max-file=3
Вы также можете установить это как часть вашего файла daemon.json вместо изменения ваших скриптов запуска:
{
"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"}
}
Обязательно запустите systemctl reload docker
после изменения этого файла, чтобы применить настройки.
Использование:
truncate -s 0 /var/lib/docker/containers/*/*-json.log
В Docker на Windows и, возможно, на других тоже можно использовать опцию tail.
например, журналы докера -f --tail 100 msftmodbus
Таким образом, отображаются только последние 100 строк, и вам не нужно сначала просматривать 1M строк...
(И, следовательно, удаление журнала, вероятно, не требуется)
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Вы можете настроить logrotate для периодической очистки журналов.
Файл примера в /etc/logrotate.d/docker-logs
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
size=50M
missingok
delaycompress
copytruncate
}
Вы также можете указать параметры log-opts на docker run
командная строка, например:
docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest
или в docker-compose.yml вроде этого
my-app:
image: my-app:latest
logging:
driver: "json-file"
options:
max-file: "5"
max-size: 10m
Кредиты: https://medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412 (Джеймс Куигли)
Docker4Mac, решение 2018 года:
LOGPATH=$(docker inspect --format='{{.LogPath}}' <container_name_or_id>)
docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- truncate -s0 $LOGPATH
Первая строка получает путь к файлу журнала, аналогично принятому ответу.
Вторая строка использует nsenter
что позволяет запускать команды в xhyve
ВМ, которая является хостом для всех док-контейнеров под Docker4Mac. Команда, которую мы запускаем, является знакомой truncate -s0 $LOGPATH
из не-Mac ответов.
Если вы используете docker-compose
первая строка становится:
local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q <service>))
а также <service>
это название сервиса от вашего docker-compose.yml
файл.
Спасибо https://github.com/justincormack/nsenter1 за nsenter
трюк.
Вы не можете сделать это напрямую через команду Docker.
Вы можете либо ограничить размер журнала, либо использовать скрипт для удаления журналов, связанных с контейнером. Вы можете найти примеры сценариев здесь (читайте снизу) : Возможность: Очистить историю журнала #1083
Ознакомьтесь с разделом ведения журнала в справочнике по файлам docker-compose, где вы можете указать параметры (например, поворот журнала и ограничение размера журнала) для некоторых драйверов ведения журнала.
Вот кроссплатформенное решение для очистки журналов контейнера докеров:
docker run --rm -v /var/lib/docker:/var/lib/docker alpine sh -c "echo '' > $(docker inspect --format='{{.LogPath}}' CONTAINER_NAME)"
Вставьте это в свой терминал и измените
CONTAINER_NAME
на желаемое имя или идентификатор контейнера.
Как пользователь root, попробуйте выполнить следующее:
> /var/lib/docker/containers/*/*-json.log
или же
cat /dev/null > /var/lib/docker/containers/*/*-json.log
или же
echo "" > /var/lib/docker/containers/*/*-json.log
На моих серверах Ubuntu даже как sudo я получу Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory
Но расчесывание докера проверяет и усекает ответы:
sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`
sudo find /var/lib/docker/containers/ -type f -name "*.log" -delete
Я предпочитаю этот (из решений выше):
truncate -s 0 /var/lib/docker/containers/*/*-json.log
Однако я использую несколько систем (например, Ubuntu 18.x Bionic), где этот путь не работает должным образом. Docker устанавливается через Snap, поэтому путь к контейнерам больше похож на:
truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log
Делюсь этим, поскольку другие ответы кажутся слишком сложными.
Самый простой способ удалить журналы связанных контейнеров — принудительно воссоздать их.
docker-compose up -d [container] --force-recreate
Затем бегdocker-compose logs [container]
должно привести к появлению только новых записей с момента открытия контейнера.
Не уверен, что это полезно для вас, но удаление контейнера всегда помогает.
Итак, если вы используете docker-compose для своей настройки, вы можете просто использовать docker-compose down && docker-compose up
вместо того docker-compose restart
. При правильной настройке (обязательно используйте монтирование томов для постоянных данных) таким образом вы не потеряете никаких данных.
Конечно, это больше, чем требовалось. Но есть различные ситуации, когда другие ответы не могут помочь (при использовании удаленного докер-сервера или работе на машине с Windows)
САЛАМ
Благодаря ответу @BMitch, я только что написал сценарий оболочки для очистки журналов всех контейнеров:
#!/bin/bash
ids=$(docker ps -a --format='{{.ID}}')
for id in $ids
do
echo $(docker ps -a --format='{{.ID}} ### {{.Names}} ### {{.Image}}' | fgrep $id)
truncate -s 0 $(docker inspect --format='{{.LogPath}}' $id)
ls -llh $(docker inspect --format='{{.LogPath}}' $id)
done
Я АЛИ.
Linux / Ubuntu:
Если у вас несколько контейнеров, и вы хотите удалить только один журнал, но не другие.
- ( Если у вас есть такие проблемы, как "Permission denied", сначала сделайте
sudo su
. ) - Перечислите все контейнеры:
- Найдите желаемый контейнер и скопируйте
CONTAINER ID
. Пример: . - Папки контейнеров и настоящие имена длиннее, но первые 12 символов - это те, которые приводят к
docker ps -a
. - Удалите только этот журнал:
> /var/lib/docker/containers/E1X2A3M4P5L6*/E1X2A3M4P5L6*-json.log
(ЗаменятьE1X2A3M4P5L6
за ваш результат !! )
Как видите, внутри
/containers
- это контейнеры, а журналы имеют то же имя, но с
-json.log
в конце. Вам просто нужно знать эти первые 12 символов, потому что
*
означает «что угодно».
Мне нужно было что-то, что я мог бы запустить как одну команду, вместо того, чтобы писать
docker ps
и копирование каждого идентификатора контейнера и выполнение команды несколько раз. Я адаптировал ответ BMitch и подумал, что поделюсь, если кому-то это может пригодиться.
Смешивание
xargs
кажется, снимает то, что мне нужно здесь:
docker ps --format='{{.ID}}' | \
xargs -I {} sh -c 'echo > $(docker inspect --format="{{.LogPath}}" {})'
Это захватывает каждый идентификатор контейнера, указанный
docker ps
(сотрет ваши журналы для любого контейнера в этом списке!), направляет его в
xargs
а затем отображает пустую строку, чтобы заменить путь к журналу контейнера.
Docker для пользователей Mac, вот решение:
Найти путь к файлу журнала по:
$ docker inspect | grep log
SSH в док-машину (предположим, имя
default
если нет, бегиdocker-machine ls
выяснить):$ docker-machine ssh default
Изменить на пользователя root ( ссылка):
$ sudo -i
Удалить содержимое файла журнала:
$ echo "" > log_file_path_from_step1
Если вам нужно сохранить резервную копию файлов журнала перед их удалением, я создал сценарий, который выполняет следующие действия (вы должны запустить его с помощью sudo) для указанного контейнера:
- Создает папку для хранения сжатых файлов журнала в качестве резервной копии.
- Ищет идентификатор работающего контейнера (указанный в имени контейнера).
- Скопируйте файл журнала контейнера в новое место (папку на шаге 1), используя случайное имя.
- Сожмите предыдущий файл журнала (для экономии места).
- Обрезает файл журнала контейнера до определенного размера, который вы можете определить.
Примечания:
- Он использует команду shuf . Убедитесь, что он есть в вашем дистрибутиве Linux, или замените его на другой генератор случайных чисел, поддерживаемый bash.
- Перед использованием измените переменную CONTAINER_NAME, чтобы она соответствовала вашему работающему контейнеру; это может быть частичное имя (не обязательно точно совпадающее имя).
- По умолчанию он усекает файл журнала до 10 МБ (10 мегабайт), но вы можете изменить этот размер, изменив переменную SIZE_TO_TRUNCATE.
- Он создает папку по пути: / opt / your-container-name / logs , если вы хотите хранить сжатые журналы в другом месте, просто измените переменную LOG_FOLDER.
- Перед запуском в продакшн выполните несколько тестов.
#!/bin/bash
set -ex
############################# Main Variables Definition:
CONTAINER_NAME="your-container-name"
SIZE_TO_TRUNCATE="10M"
############################# Other Variables Definition:
CURRENT_DATE=$(date "+%d-%b-%Y-%H-%M-%S")
RANDOM_VALUE=$(shuf -i 1-1000000 -n 1)
LOG_FOLDER="/opt/${CONTAINER_NAME}/logs"
CN=$(docker ps --no-trunc -f name=${CONTAINER_NAME} | awk '{print $1}' | tail -n +2)
LOG_DOCKER_FILE="$(docker inspect --format='{{.LogPath}}' ${CN})"
LOG_FILE_NAME="${CURRENT_DATE}-${RANDOM_VALUE}"
############################# Procedure:
mkdir -p "${LOG_FOLDER}"
cp ${LOG_DOCKER_FILE} "${LOG_FOLDER}/${LOG_FILE_NAME}.log"
cd ${LOG_FOLDER}
tar -cvzf "${LOG_FILE_NAME}.tar.gz" "${LOG_FILE_NAME}.log"
rm -rf "${LOG_FILE_NAME}.log"
truncate -s ${SIZE_TO_TRUNCATE} ${LOG_DOCKER_FILE}
Вы можете создать задание cron для запуска предыдущего скрипта каждый месяц. Первый забег:
sudo crontab -e
Введите a на клавиатуре, чтобы перейти в режим редактирования. Затем добавьте следующую строку:
0 0 1 * * /your-script-path/script.sh
Хит побега для выхода из режима редактирования. Сохраните файл, набрав :wq и нажав Enter. Убедитесь, что у файла script.sh есть разрешения на выполнение.
Чтобы удалить / очистить журналы контейнера докеров, мы можем использовать команду ниже
$(docker inspect container_id | grep "LogPath" | cut -d "" "-f4) или $(docker inspect container_name | grep" LogPath "| cut -d" "" -f4)
На компьютерах с рабочим столом docker мы используем:truncate -s 0 //wsl.localhost/docker-desktop-data/data/docker/containers/*/*-json.log
Для дистрибутивов Linux вы можете использовать это, у меня работает этот путь:truncate -s 0 /var/lib/docker/containers/*/*-json.log
Если ваш хост-компьютер использует systemd , рассмотрите возможность использования драйвера журнала Journald .
Таким образом, вы получаете централизованное управление журналами вместо тихой регистрации в локальном неротируемом файле ( драйвер регистрации json-файла по умолчанию делает именно это ). В моем случае использование настроек докера по умолчанию привело к исчерпанию дискового пространства (файл журнала съеден более 7 ГБ).
Демон Journald можно легко настроить для ротации журналов, см. документацию.