Estrarre il file dall'immagine docker?


24

Mi piacerebbe estrarre un file da un'immagine Docker senza dover eseguire l'immagine.

L' docker saveopzione non è attualmente un'opzione valida per me in quanto sta salvando un file troppo grande solo per decomprimere un file specifico.


Quale distro stai usando?
ryekayo,

@ryekayo: Ubuntu 14, docker 1.12.4 (api 1.24)
BlakBat

Risposte:


21

Puoi estrarre file da un'immagine con i seguenti comandi:

docker create $image  # returns container ID
docker cp $container_id:$source_path $destination_path
docker rm $container_id

Secondo la docker create documentazione , questo non esegue il contenitore:

Il docker createcomando crea un livello contenitore scrivibile sull'immagine specificata e lo prepara per l'esecuzione del comando specificato. L'ID contenitore viene quindi stampato su STDOUT. Questo è simile ad docker run -deccezione del fatto che il contenitore non viene mai avviato. È quindi possibile utilizzare il docker start <container_id>comando per avviare il contenitore in qualsiasi momento.


Per riferimento (la mia risposta precedente), un modo meno efficiente di estrarre un file da un'immagine è il seguente:

docker run some_image cat $file_path > $output_path

3
Potresti voler scavalcare l'entrata. docker run --entrypoint /bin/sh my_image -c /bin/cat some_file
Andrew

1
Questo esegue l'immagine, che è specificamente ciò che non volevo fare come indicato nella mia domanda.
BlakBat,

Ah, questo è un buon punto. Sono d'accordo che la mia risposta attuale non è soddisfacente allora.
bbc

1
@BlakBat Questa risposta aggiornata funziona per te? Immagino che avrei dovuto creare una nuova risposta, ma ora è fatta.
bbc

1
@bbc Questa risposta aggiornata infatti non avvia un contenitore (il nocciolo della domanda) e non richiede di essere root.
BlakBat,

2

Nessuna delle precedenti ha funzionato per me. Il comando di lavoro completo è:

docker run --rm --entrypoint /bin/sh image_name -c "cat /path/filename" > output_filename

Senza virgolette catviene passato senza nome file, quindi non sa cosa mostrare. Inoltre è una buona idea eliminare il contenitore al termine del comando.


Il comando a cui ti riferisci funzionerà solo in base alla finestra mobile e alla corretta impostazione di ENTRYPOINT / CMD nel file Docker; questo non ha nulla a che fare con la citazione. Dici anche di eliminare il contenitore, ma specifichi --rm. Infine, quando ho pubblicato la mia domanda ho specificato "senza dover eseguire l'immagine" e nessuna risposta è stata una soluzione che ne tiene conto.
BlakBat,

1
Indipendentemente da quali CMD ed ENTRYPOINT sono stati impostati in Dockerfile, eseguo l'override di entrambi, quindi funzionerebbe sempre (su Linux ovviamente). Cosa intendi con "dipendente dalla finestra mobile"? Impostazioni, versione, env, cosa? La tua domanda non è corretta perché le immagini non possono essere eseguite, solo i contenitori possono farlo. Penso che non ci sia una risposta corretta, devi affrontare molti file o creare un contenitore temporaneo. --rm rimuove il contenitore temporaneo, le risposte degli altri lasciano spazzatura sul tuo disco.
sekrett,

1

Se non sbaglio, credo che i contenitori docker memorizzino i file memorizzati nella cache creati nella seguente directory per Ubuntu:

/var/lib/docker/aufs/diff/<container_id>

Da lì dovresti essere in grado di accedere al file system e recuperare i tuoi file.


No. Tale directory contiene solo layersizee json, inoltre, non è leggibile dall'utente (anche se l'utente si trova nel gruppo finestra mobile). /var/lib/docker/aufs/diffconterrà il file che cerco (ma non è classificato in base all'ID contenitore) e inoltre non è leggibile.
BlakBat,

Dammi alcuni e lo cercherò. So per certo che c'è un modo per recuperare i file senza entrare nel contenitore o eseguirlo.
ryekayo,

Non leggibile, come mostra? Ho trovato un esempio in cui è possibile estrarre file di testo dai contenitori andando nella directory / var / lib / docker / aufs / diff / *
ryekayo,

Errore mio. L'utente può accedere /var/lib/docker/aufs(ma non tutte le altre directory in /var/lib/docker/)
BlakBat il

Puoi accedere come root?
Ryekayo,

0

Se la memorizzazione dell'output completo di docker savenon è un'opzione, è possibile utilizzare le pipeline per estrarre solo il file necessario da esso.

Sfortunatamente, poiché l'output è un "catrame di tar", può essere un processo leggermente iterativo.

Quello che ho fatto quando avevo bisogno di estrarre un file proprio ora era:

1) Determina quale versione dell'immagine il file che ti interessa è cambiato più di recente (il modo in cui lo fai dipende probabilmente dalla tua immagine) e la data in cui è stato creato / salvato

2) Ottieni il sommario completo dall'output del docker savecomando con:

docker save IMAGE_NAME | tar -tvf -

3) Fine i layer.tarfile nell'output di quel comando che corrispondono alla data dell'immagine che hai determinato nel passaggio 1. (puoi aggiungere | grep layer.tarper mostrare solo quei file)

4) Estrai quel layer.tarfile in standard e ottieni il sommario di esso:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -tvf -

5) Verificare che il file desiderato sia elencato ed estrarlo una volta trovato il nome:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - PATH/TO/YOUR/FILE

Se sono presenti più layer.tarfile corrispondenti alla data che stai cercando nel passaggio 2/3, potrebbe essere necessario ripetere il passaggio 4 per ognuno di essi fino a trovare quello giusto

Sostituisci il testo in maiuscolo nei comandi sopra con i nomi delle immagini, i checksum e i nomi dei file corretti per il tuo caso.

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.