Come cancellare correttamente i log per un contenitore Docker?


210

Io uso docker logs [container-name] per vedere i registri di un contenitore specifico.

Esiste un modo elegante per cancellare questi registri?


14
Su un sidenote, è possibile ottenere la dimensione dei registri tramitesudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log"
Daniel F

Risposte:


251

Da questa domanda c'è un one-liner che puoi eseguire:

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

o c'è il comando troncato simile:

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

Non sono un grande fan di nessuno dei due poiché modificano direttamente i file di Docker. L'eliminazione del registro esterno potrebbe verificarsi mentre la finestra mobile sta scrivendo i dati in formato json nel file, risultando in una riga parziale e interrompendo la capacità di leggere qualsiasi registro dal docker logscli.

Invece, puoi fare in modo che Docker ruoti automaticamente i log per te. Questo viene fatto con flag aggiuntivi per dockerd se si utilizza il driver di registrazione JSON predefinito :

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

Puoi anche impostarlo come parte del tuo file daemon.json invece di modificare i tuoi script di avvio:

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

Queste opzioni devono essere configurate con accesso root. Assicurati di eseguire un systemctl reload dockerdopo aver modificato questo file per applicare le impostazioni. Questa impostazione sarà quindi quella predefinita per tutti i contenitori appena creati. Nota: i contenitori esistenti devono essere eliminati e ricreati per ricevere i nuovi limiti di registro.


Opzioni di registro simili possono essere passate ai singoli contenitori per sovrascrivere queste impostazioni predefinite, consentendo di salvare più o meno registri sui singoli contenitori. Da docker runquesto sembra:

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

o in un file di composizione:

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

Per risparmiare spazio, è possibile passare dal driver di registro json al driver di registro "locale". Prende le stesse opzioni di dimensione massima e file massimo, ma invece di archiviare in json utilizza una sintassi binaria che è più veloce e più piccola. Ciò consente di archiviare più registri nello stesso file di dimensioni. La voce daemon.json per questo assomiglia a:

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

L'aspetto negativo del driver locale è che i parser / forwarder di log esterni che dipendevano dall'accesso diretto ai log json non funzioneranno più. Quindi, se usi uno strumento come filebeat per inviare a Elastic, o lo spedizioniere universale di Splunk, eviterei il driver "locale".

Ho un po 'di più su questo nella mia presentazione Suggerimenti e trucchi .


6
Ho fatto un service docker restart che da solo non ha funzionato. Inoltre ha dovuto creare nuovi contenitori prima di entrare in vigore. vale a dire che solo il
recupero

Sto usando Docker 1.13.1 e 'docker inspect --format =' {{. LogPath}} '<id contenitore>' restituisce una stringa nulla ("") .... ma sto ancora ricevendo output da ' log docker <ID contenitore> '?!? Da dove viene e come posso cancellarlo ??
JD Allen,

@JDAllen 1.13.1 non è più supportato. Non ho un sistema così vecchio per visualizzare i risultati delle ispezioni.
BMitch

Meglio ancora sarebbe echo -n > .... Ad ogni modo, vorrei poter avere un maggiore controllo sui miei registri. Ad esempio, dopo il riavvio della finestra mobile , mi piacerebbe avere il meccanismo per fare qualcosa con i registri conservati.
NarūnasK,

2
@AlexisWilke se riesci a fermare la finestra mobile, allora puoi probabilmente fermare il tuo container. Se riesci a fare quest'ultimo, ricreare il contenitore con le opzioni di registrazione sarebbe il mio consiglio. Il nuovo contenitore non ha registri vecchi e i nuovi registri verranno spostati automaticamente, risolvendo contemporaneamente sia il problema a breve che a lungo termine.
BMitch,

227

Uso:

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

Potrebbe essere necessario sudo

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

rif. Jeff S. Come cancellare correttamente i log per un container Docker?

Riferimento: troncare un file mentre viene utilizzato (Linux)


4
troncare: impossibile aprire '/var/lib/docker/containers/*/*-json.log' per la scrittura: nessun file o directory di questo tipo
BTR Naidu,

2
@BTRNaidu devi eseguirlo come root / sudo, containersaltrimenti il contenuto di non è disponibile.
Spydon,

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"- ha funzionato per me
Jeff S.

7
Ignora i due professionisti sopra. Se non sei sicuro, puoi semplicemente verificare con "ls /var/lib/docker/containers/*/*-json.log" cosa viene troncato.
duketwo,

1
dopo aver svuotato il file di registro, ottengo questo errore:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol

42

Su Docker per Windows e Mac, e probabilmente anche su altri, è possibile utilizzare l'opzione tail. Per esempio:

docker logs -f --tail 100

In questo modo, vengono visualizzate solo le ultime 100 linee e non è necessario prima scorrere tra le linee 1M ...

(E quindi, probabilmente non è necessario eliminare il registro)


12
L'idea è di pulire i file di registro e di non stampare le ultime n righe di file di registro
Youssouf Maiga

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

4
Per ottenere la dimensione dei registri sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log", per ottenere solo il totale della dimensione dei registrisudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F

Ci sono problemi con dockerd / aufs ignari e incapaci di rimuovere i file di registro ruotati?
ThorSummoner,

Questo comando ha funzionato per me mentre gli altri comandi in questo SO non lo hanno fatto. Se è importante, eseguo Docker versione 18 su CentOS 7
Tundra Fizz

27

È possibile impostare logrotate per cancellare periodicamente i registri.

File di esempio in /etc/logrotate.d/docker-logs

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}

e come lo uso? è usato come predefinito con docker run? il file /etc/logrotate.d/docker-logsnon esiste, devo crearlo?
Carlos.V,

Devi chiamare l'utilità logrotate (logrotate <config-file>) e leggerà la tua configurazione ed eseguirà la pulizia. Ad esempio, puoi anche impostarlo come cron job.
AlexPnt,

Il problema con questo è che potrebbe non essere correttamente sincronizzato con quello che sta facendo la finestra mobile. L'uso della funzione docker è probabilmente molto più saggio. ( "log-opts"come mostrato da BMitch)
Alexis Wilke,

12

Docker4Mac, una soluzione 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 prima riga ottiene il percorso del file di registro, simile alla risposta accettata.

La seconda riga utilizza nsenterche consente di eseguire comandi nella xhyveVM che server come host per tutti i contenitori docker in Docker4Mac. Il comando che eseguiamo è il familiare truncate -s0 $LOGPATHdalle risposte non Mac.

Se stai usando docker-compose, la prima riga diventa:

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

ed <service>è il nome del servizio dal tuo docker-compose.ymlfile.

Grazie a https://github.com/justincormack/nsenter1 per il nsentertrucco.


4
E per troncare i registri di tutti i contenitori è possibile utilizzare un carattere jolly shell come mostrato nelle altre risposte, quindi è solo 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

Non puoi farlo direttamente tramite un comando Docker.

È possibile limitare le dimensioni del registro o utilizzare uno script per eliminare i registri relativi a un contenitore. Qui puoi trovare esempi di script (leggi dal basso): Funzione: possibilità di cancellare la cronologia dei registri # 1083

Controlla la sezione di registrazione del riferimento al file comporre docker, in cui è possibile specificare le opzioni (come la rotazione del registro e il limite della dimensione del registro) per alcuni driver di registrazione.


7

Come utente root , prova a eseguire quanto segue:

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

o

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

o

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

6

Sui miei server Ubuntu anche se sudo avrei ottenuto Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

Ma pettinando la finestra mobile ispezionare e troncare le risposte ha funzionato:

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

2

Preferisco questo (dalle soluzioni sopra):

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

Tuttavia sto eseguendo diversi sistemi (Ubuntu 18.x Bionic per esempio), in cui questo percorso non funziona come previsto. Docker viene installato tramite Snap, quindi il percorso dei contenitori è più simile a:

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

1

Puoi anche fornire i parametri di log-opts dalla docker runriga di comando, in questo modo:

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

o in un docker-compose.yml come questo

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

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


I valori dei parametri devono essere citati (cioè "5"e "10m"rispettivamente), come mostrato qui per il file globale daemon.json, ma è lo stesso per un docker-compose.yml. In entrambi i casi, interesserà solo i contenitori appena creati.
Adrian W,

@AdrianW: docker-compose.yml non ha bisogno di virgolette. Questi sono formati di file completamente diversi. E sì, hai ragione: i comandi di "docker run" e i parametri di docker-compose influiscono solo sui container appena creati, al contrario della risposta qui con il maggior numero di voti che riguarda solo i demoni dockerd riavviati ed è disponibile solo tramite l'accesso root. La mia risposta dovrebbe mostrare un percorso molto più semplice e aggiornato rispetto alla modifica rispetto al riavvio dell'intero processo dockerd.
Dag Baardsen,

Senza virgolette, ottengo: ERRORE: per app Impossibile creare il contenitore per l'app di servizio: json: impossibile annullare il numero nel campo Vai struttura LogConfig.Config di tipo stringa Se cito in questo modo: "5"funziona. Il 10mlavoro senza citare davvero.
Adrian W

Sembra che ci sia una differenza tra Docker per Windows e Docker per Linux. In quest'ultimo caso, devo racchiudere i valori tra virgolette. Non sul primo. Aggiornato la descrizione per adattarli entrambi. Grazie, @AdrianW
Dag Baardsen il

0

Docker per utenti Mac, ecco la soluzione:

    1. Trova il percorso del file di registro per:

      $ docker inspect | grep log

    1. SSH nella macchina docker (supponiamo che il nome sia default, in caso contrario, eseguito docker-machine lsper scoprirlo):

      $ docker-machine ssh default

    1. Passa a utente root ( riferimento ):

      $ sudo -i

    1. Elimina il contenuto del file di registro:

      $ echo "" > log_file_path_from_step1


2
docker-machine non funziona con Docker per Mac. È invece possibile eseguire "run finestra mobile -ti -v / var / lib / finestra mobile / contenitori: / var / inizio CentOS bash" e poi "troncare --size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log"
Jamshid

È possibile utilizzare docker exec -it default shper inserire una shell sh in un contenitore. Tuttavia, molti contenitori non rendono implicitamente sudodisponibile il comando.
Dag Baardsen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.