¿Cómo borrar los registros correctamente para un contenedor Docker?

210

yo suelo docker logs [container-name] para ver los registros de un contenedor específico.

¿Hay alguna forma elegante de borrar estos registros?

Youssouf Maiga
fuente
14
En una nota al margen, puede obtener el tamaño de los registros a través desudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Respuestas:

251

De esta pregunta hay una línea que puedes ejecutar:

echo "" > $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

o hay un comando truncado similar:

truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

No soy un gran admirador de ninguno de ellos, ya que modifican los archivos de Docker directamente. La eliminación del registro externo podría ocurrir mientras Docker está escribiendo datos con formato json en el archivo, lo que da como resultado una línea parcial y rompe la capacidad de leer cualquier registro desde el docker logscli.

En cambio, puede hacer que Docker gire automáticamente los registros por usted. Esto se hace con indicadores adicionales para dockerd si está utilizando el controlador de registro JSON predeterminado :

dockerd ... --log-opt max-size=10m --log-opt max-file=3

También puede configurar esto como parte de su archivo daemon.json en lugar de modificar sus scripts de inicio:

{
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

Estas opciones deben configurarse con acceso root. Asegúrese de ejecutar un systemctl reload dockerdespués de cambiar este archivo para que se aplique la configuración. Esta configuración será la predeterminada para cualquier contenedor recién creado. Tenga en cuenta que los contenedores existentes deben eliminarse y recrearse para recibir los nuevos límites de registro.


Se pueden pasar opciones de registro similares a contenedores individuales para anular estos valores predeterminados, lo que le permite guardar más o menos registros en contenedores individuales. De docker runesto se ve así:

docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...

o en un archivo de redacción:

version: '3.7'
services:
  app:
    image: ...
    logging:
      options:
        max-size: "10m"
        max-file: "3"

Para ahorrar espacio adicional, puede cambiar del controlador de registro json al controlador de registro "local". Toma las mismas opciones de tamaño máximo y archivo máximo, pero en lugar de almacenar en json, usa una sintaxis binaria que es más rápida y más pequeña. Esto le permite almacenar más registros en el mismo archivo de tamaño. La entrada daemon.json para eso se ve así:

{
  "log-driver": "local",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

La desventaja del controlador local es que los analizadores / reenviadores de registros externos que dependían del acceso directo a los registros json ya no funcionarán. Entonces, si usa una herramienta como filebeat para enviar a Elastic, o al reenviador universal de Splunk, evitaría el controlador "local".

Tengo un poco más de esto en mi presentación de Consejos y trucos .

BMitch
fuente
66
Hice una service docker restart que por sí sola no funcionó. También tuve que crear nuevos contenedores antes de que entrara en vigencia. es decir, simplemente al abrir los contenedores antiguos no se aplicó el nuevo registro
Robbo_UK
Estoy usando Docker 1.13.1, y 'docker inspect --format =' {{. LogPath}} '<container id>' devuelve una cadena nula ("") .... pero aún obtengo resultados de ' Docker registra <id del contenedor> '?!? ¿De dónde viene eso y cómo lo aclaro?
JD Allen
@JDAllen 1.13.1 ya no tiene soporte. No tengo un sistema tan antiguo para ver su salida de inspección.
BMitch
Mejor aún lo sería echo -n > .... De todos modos, me gustaría poder tener más control sobre mis registros. Por ejemplo, después de reiniciar Docker-compose , me encantaría tener el mecanismo para hacer algo con los registros conservados.
NarūnasK
2
@AlexisWilke si puede detener la ventana acoplable, es probable que pueda detener su contenedor. Si puede hacer lo último, mi consejo sería recrear el contenedor con las opciones de registro. El nuevo contenedor no tiene registros antiguos, y los registros nuevos se lanzarán automáticamente, resolviendo el problema a corto y largo plazo al mismo tiempo.
BMitch
227

Utilizar:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Puede que necesites sudo

sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

árbitro. Jeff S. ¿Cómo borrar los registros correctamente para un contenedor Docker?

Referencia: truncar un archivo mientras se está utilizando (Linux)

duketwo
fuente
44
truncar: no se puede abrir '/var/lib/docker/containers/*/*-json.log' para escribir: No existe dicho archivo o directorio
BTR Naidu
2
@BTRNaidu tienes que ejecutarlo como root / sudo, el contenido de containersno está disponible de otra manera.
Spydon
25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- trabajó para mí
Jeff S.
77
Ignora a los dos profesionales anteriores. Si no está seguro, puede verificar con "ls /var/lib/docker/containers/*/*-json.log" lo que se está truncando.
duketwo 01 de
1
después de vaciar el archivo de registro, recibo este error:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol
42

En Docker para Windows y Mac, y probablemente también en otros, es posible usar la opción de cola. Por ejemplo:

docker logs -f --tail 100

De esta forma, solo se muestran las últimas 100 líneas, y no tiene que desplazarse primero por las líneas 1M ...

(Y por lo tanto, eliminar el registro es probablemente innecesario)

Egbert Nierop
fuente
12
La idea es limpiar los archivos de registro y no imprimir las últimas n líneas de archivos de registro
Youssouf Maiga
41
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Ricardo
fuente
44
Para obtener el tamaño de los registros sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", para obtener solo el total del tamaño de los registrossudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F
¿Hay algún problema con que dockerd / aufs ignore e incapaz de eliminar los archivos de registro rotados?
ThorSummoner
Este comando funcionó para mí, mientras que los otros comandos en este SO no. Si es importante, estoy ejecutando Docker versión 18 en CentOS 7
Tundra Fizz
27

Puede configurar logrotate para borrar los registros periódicamente.

Archivo de ejemplo en /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}
AlexPnt
fuente
y como uso esto? se usa por defecto con docker run? el archivo /etc/logrotate.d/docker-logsno existe, tengo que crearlo?
Carlos.V
Debe llamar a la utilidad logrotate (logrotate <config-file>) y leerá su configuración y ejecutará la limpieza. También puede configurarlo como un trabajo cron, por ejemplo.
AlexPnt
El problema con este es que puede no estar sincronizado correctamente con lo que está haciendo Docker. El uso de la instalación acoplable es probablemente mucho más sabio. ( "log-opts"como lo muestra BMitch)
Alexis Wilke
12

Docker4Mac, una solución 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

La primera línea obtiene la ruta del archivo de registro, similar a la respuesta aceptada.

La segunda línea utiliza nsentereso le permite ejecutar comandos en la xhyveVM que sirve como servidor para todos los contenedores de Docker en Docker4Mac. El comando que ejecutamos es el familiar truncate -s0 $LOGPATHde las respuestas que no son de Mac.

Si está usando docker-compose, la primera línea se convierte en:

local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q <service>))

y <service>es el nombre del servicio de su docker-compose.ymlarchivo.

Gracias a https://github.com/justincormack/nsenter1 por el nsentertruco.

elifiner
fuente
44
Y para truncar los registros de todos los contenedores que puede utilizar un comodín de la shell como se muestra en otras respuestas, por lo que es sólo un comando:docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- sh -c 'truncate -s0 /var/lib/docker/containers/*/*-json.log'
bradenm
11

No puede hacer esto directamente a través de un comando Docker.

Puede limitar el tamaño del registro o usar un script para eliminar registros relacionados con un contenedor. Puede encontrar ejemplos de scripts aquí (leer desde abajo): Característica: Capacidad para borrar el historial de registro # 1083

Consulte la sección de registro de la referencia del archivo docker-compose, donde puede especificar opciones (como rotación de registro y límite de tamaño de registro) para algunos controladores de registro.

Tristan
fuente
7

Como usuario root , intente ejecutar lo siguiente:

>  /var/lib/docker/containers/*/*-json.log

o

cat /dev/null > /var/lib/docker/containers/*/*-json.log

o

echo "" > /var/lib/docker/containers/*/*-json.log
matson kepson
fuente
6

En mis servidores Ubuntu, incluso como sudo, obtendría Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Pero peinar el docker inspeccionar y truncar respuestas funcionó:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`
aqwan
fuente
2

Prefiero este (de las soluciones anteriores):

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Sin embargo, estoy ejecutando varios sistemas (Ubuntu 18.x Bionic, por ejemplo), donde esta ruta no funciona como se esperaba. Docker se instala a través de Snap, por lo que la ruta a los contenedores se parece más a:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log
igraczech
fuente
1

También puede proporcionar los parámetros log-opts en la docker runlínea de comando, de esta manera:

docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest

o en un docker-compose.yml como este

my-app:
image: my-app:latest
logging:
    driver: "json-file"
    options:
        max-file: "5"
        max-size: 10m

Créditos: https://medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412 (James Quigley)

Dag Baardsen
fuente
Los valores de los parámetros se deben citar (es decir, "5"y "10m"respectivamente), como se muestra aquí para el archivo global daemon.json, pero es lo mismo para un docker-compose.yml. En ambos casos, solo afectará a los contenedores recién creados.
Adrian W
@AdrianW: docker-compose.yml no necesita comillas. Estos son formatos de archivo completamente diferentes. Y sí, tiene razón: los comandos "docker run" y los parámetros de compilación de docker solo afectan a los contenedores recién creados, a diferencia de la respuesta aquí con la mayoría de los votos, que afecta solo a los demonios dockerd reiniciados y está disponible solo a través del acceso raíz. Se supone que mi respuesta muestra una ruta mucho más simple y actualizada que la edición que reiniciar todo el proceso dockerd.
Dag Baardsen
Sin comillas, obtengo: ERROR: para la aplicación No se puede crear un contenedor para la aplicación de servicio: json: no se puede ordenar el número en el campo Go struct LogConfig.Config de tipo string Si cito así: "5"funciona. El 10mtrabajo sin citar de hecho.
Adrian W
Parece que hay una diferencia entre Docker para Windows y Docker para Linux. En este último caso, tengo que encerrar los valores entre comillas. No en el primero. Se actualizó la descripción para adaptarse a ambos. Gracias, @AdrianW
Dag Baardsen
0

Docker para usuarios de Mac, aquí está la solución:

    1. Encuentre la ruta del archivo de registro por:

      $ docker inspect | grep log

    1. SSH en la máquina acoplable (supongamos que el nombre es default, si no, ejecutar docker-machine lspara averiguarlo):

      $ docker-machine ssh default

    1. Cambiar a usuario root ( referencia ):

      $ sudo -i

    1. Eliminar el contenido del archivo de registro:

      $ echo "" > log_file_path_from_step1

Jinsong Li
fuente
2
docker-machine no funciona con Docker para Mac. En su lugar, puede ejecutar "run ventana acoplable -ti -v / var / lib / acoplable / contenedores: / var / inicio centos fiesta" y luego "truncado --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Jamshid
Puede usar docker exec -it default shpara ingresar un sh shell en un contenedor. Sin embargo, muchos contenedores no hacen que el sudocomando esté implícitamente disponible.
Dag Baardsen