Download di immagini Docker dall'hub Docker senza utilizzare Docker


32

Voglio scaricare manualmente un'immagine Docker dall'hub Docker . Più specificamente, voglio scaricare un'immagine Docker dall'hub Docker su una macchina in un ambiente limitato che non ha (e non può) avere installato il software client Docker. Avrei pensato che questo sarebbe stato possibile utilizzando l' API ufficiale , ma questo non sembra essere il caso - vedi la seguente discussione:

È davvero il caso che l'API non supporti il ​​download di immagini? C'è un modo per aggirare questo?


AGGIORNAMENTO 1:

Mi sono imbattuto nel seguente post ServerFault:

La soluzione accettata utilizza il docker savecomando, che non aiuta nella mia situazione. Ma un'altra soluzione pubblicata lì cita il seguente post StackOverflow:

Una delle soluzioni qui fa riferimento a uno strumento da riga di comando chiamato docker-register-debug che, tra le altre cose, può generare un curlcomando per il download di un'immagine. Ecco cosa ho ottenuto:

user@host:~$ docker-registry-debug curlme docker ubuntu

# Reading user/passwd from env var "USER_CREDS"
# No password provided, disabling auth
# Getting token from https://index.docker.io
# Got registry endpoint from the server: https://registry-1.docker.io
# Got token: signature=1234567890abcde1234567890abcde1234567890,repository="library/docker",access=read
curl -i --location-trusted -I -X GET -H "Authorization: Token signature=1234567890abcde1234567890abcde1234567890,repository="library/docker",access=read" https://registry-1.docker.io/v1/images/ubuntu/layer

user@host:~$ curl \
-i --location-trusted -I -X GET \
-H "Authorization: Token signature=1234567890abcde1234567890abcde1234567890,repository="library/docker",access=read" 

https://registry-1.docker.io/v1/images/ubuntu/layer
HTTP/1.1 404 NOT FOUND
Server: gunicorn/18.0
Date: Wed, 29 Nov 2017 01:00:00 GMT
Expires: -1
Content-Type: application/json
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 29
X-Docker-Registry-Version: 0.8.15
X-Docker-Registry-Config: common
Strict-Transport-Security: max-age=31536000

Quindi sfortunatamente sembra che il curlcomando generato non funzioni.


AGGIORNAMENTO 2:

Sembra che riesca a scaricare BLOB di layer dall'hub Docker. Ecco come lo sto attualmente facendo.

Ottieni un token di autorizzazione:

user@host:~$ export TOKEN=\
"$(curl \
--silent \
--header 'GET' \
"https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull" \
| jq -r '.token' \
)"

Tirare un manifest di immagine:

user@host:~$ curl \
--silent \
--request 'GET' \
--header "Authorization: Bearer ${TOKEN}" \
'https://registry-1.docker.io/v2/library/ubuntu/manifests/latest' \
| jq '.'

Tirare un manifest di immagine ed estrarre le somme di BLOB:

user@host:~$ curl \
--silent \
--request 'GET' \
--header "Authorization: Bearer ${TOKEN}" \
'https://registry-1.docker.io/v2/library/ubuntu/manifests/latest' \
| jq -r '.fsLayers[].blobSum'

sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4
sha256:be588e74bd348ce48bb7161350f4b9d783c331f37a853a80b0b4abc0a33c569e
sha256:e4ce6c3651b3a090bb43688f512f687ea6e3e533132bcbc4a83fb97e7046cea3
sha256:421e436b5f80d876128b74139531693be9b4e59e4f1081c9a3c379c95094e375
sha256:4c7380416e7816a5ab1f840482c9c3ca8de58c6f3ee7f95e55ad299abbfe599f
sha256:660c48dd555dcbfdfe19c80a30f557ac57a15f595250e67bfad1e5663c1725bb

Scarica un BLOB a livello singolo e scrivilo in un file:

user@host:~$ BLOBSUM=\
"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"

user@host:~$ curl \
--silent \
--location \
--request GET \
--header "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/ubuntu/blobs/${BLOBSUM}" \
> "${BLOBSUM/*:/}.gz"

Scrivi tutte le somme BLOB in un file:

user@host:~$ curl \
--silent \
--request 'GET' \
--header "Authorization: Bearer ${TOKEN}" \
'https://registry-1.docker.io/v2/library/ubuntu/manifests/latest' \
| jq -r '.fsLayers[].blobSum' > ubuntu-blobsums.txt

Scarica tutti i BLOB di layer dal manifest:

user@host:~$ while read BLOBSUM; do
curl \
--silent \
--location \
--request 'GET' \
--header "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/library/ubuntu/blobs/${BLOBSUM}" \
> "${BLOBSUM/*:/}.gz"; \
done < blobsums.txt

Ora ho un sacco di macchie di livello e ho bisogno di ricombinarle in un'immagine - penso.


Link correlati:


"Più specificamente, voglio scaricare un'immagine Docker dall'hub Docker su una macchina in un ambiente limitato che non ha (e non può) avere installato il software client Docker." => Qual è il punto di avere le immagini su questa macchina allora? (Una soluzione più semplice consiste nell'utilizzare un host pivot, uno in cui si accede alla finestra mobile estraibile da dockerhub e salvataggio /
docker docker

@Tensibai per copiarlo su un'altra macchina che fa avere Docker, ma non hanno accesso a internet.
igal,

Hai dato un'occhiata al codice pull della finestra mobile? Sembra la strada da percorrere per costruire qualcosa del genere dalle chiamate http di base
Tensibai,

@Tensibai Penso di averlo capito. Penso anche di aver ottenuto una soluzione dalla comunità Docker. Tornerò e pubblicherò la soluzione più tardi oggi.
igal,

@Tensibai Ho pubblicato una soluzione con uno script di shell che risolve il problema.
igal,

Risposte:


23

Quindi si scopre che Moby Project ha uno script shell su Moby Github che può scaricare immagini da Docker Hub in un formato che può essere importato in Docker:

La sintassi di utilizzo per lo script è data da quanto segue:

download-frozen-image-v2.sh target_dir image[:tag][@digest] ...

L'immagine può quindi essere importata con tare docker load:

tar -cC 'target_dir' . | docker load

Per verificare che lo script funzioni come previsto, ho scaricato un'immagine Ubuntu da Docker Hub e caricata in Docker:

user@host:~$ bash download-frozen-image-v2.sh ubuntu ubuntu:latest
user@host:~$ tar -cC 'ubuntu' . | docker load
user@host:~$ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#

In pratica avrei dovuto prima copiare i dati dal client Internet (che non è installato Docker) alla macchina di destinazione / destinazione (che non è installato Docker):

user@nodocker:~$ bash download-frozen-image-v2.sh ubuntu ubuntu:latest
user@nodocker:~$ tar -C 'ubuntu' -cf 'ubuntu.tar' .
user@nodocker:~$ scp ubuntu.tar user@hasdocker:~

e quindi caricare e utilizzare l'immagine sull'host di destinazione:

user@hasdocker:~ docker load ubuntu.tar
user@hasdocker:~ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#

The machine with internet connectivity does not and cannot have Docker installed. ma si applicadocker load
030

@ 030 Solo per testare / dimostrare che lo script funziona e che i dati dell'immagine di download possono essere importati in Docker. In pratica dovrei prima copiare i dati su una macchina con Docker installato.
igal,

Forse potresti aggiungere quella parte per chiarimenti
030

2
@ 030 Ho aggiunto una sessione di esempio che illustra come sarebbe il flusso di lavoro in pratica.
igal,

7

Esiste uno strumento chiamato Skopeo che può recuperare immagini Docker da un repository e salvarle in diversi formati.

Per esempio:

  1. Scarica l'immagine e salva i livelli come tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. /tmp/ubuntu.tarSe lo si desidera, trasferire su un'altra macchina.

  3. Carica l'immagine su un'istanza Docker che non ha una connessione Internet: docker load --input /tmp/ubuntu.tar

È disponibile nel repository CentOS 7 con il nome del pacchetto skopeo. Al momento non ci sono pacchetti Debian o Ubuntu (ma è facile da compilare).


3

grazie per la motivazione. Ne ho realizzato una versione PowerShell. Dai un'occhiata ... Con esso puoi spostare i contenitori dockerhub su reti docker limitate con un desktop Windows e uno strumento ssh-scp sulla macchina docker senza diritti di root o di amministratore

https://gitlab.com/Jancsoj78/dockerless_docker_downloader un nuovo strumento di hacker :)

$image = "ubuntu"
$tag = "latest"
$imageuri = "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/"+$image+":pull"
$taguri = "https://registry-1.docker.io/v2/library/"+$image+"/manifests/"+$tag
$bloburi = "https://registry-1.docker.io/v2/library/"+$image+"/blobs/sha256:"

#token request
$token = Invoke-WebRequest -Uri $imageuri | ConvertFrom-Json | Select -expand token

#pull image manifest
$blobs = $($(Invoke-Webrequest -Headers @{Authorization="Bearer $token"} -Method GET -Uri $taguri | ConvertFrom-Json | Select -expand fsLayers ) -replace "sha256:" -replace "@{blobSum=" -replace "}")

#download blobs
for ($i=0; $i -lt $blobs.length; $i++) {
    $blobelement =$blobs[$i]

    Invoke-Webrequest -Headers @{Authorization="Bearer $token"} -Method GET -Uri $bloburi$blobelement -OutFile blobtmp

    $source = "blobtmp"
    $newfile = "$blobelement.gz"

#overwrite
Copy-Item $source $newfile -Force -Recurse
#source blobs
ls *.gz
}
#postprocess
echo "copy these .gz to your docker machine"
echo "docker import .gz backward one by one"
echo "lastone with ubuntu:latest"
echo "after docker export and reimport to make a simple layer image"

1

Per me non è del tutto chiaro cosa stai cercando di ottenere e perché i tentativi non sono una soluzione al problema. Se avessi bisogno di risolvere questo problema, vorrei @Tensibai e altre domande e risposte indicate, fare prima una finestra mobile su un sistema con connettività Internet, salvare l'immagine docker, copiarla sulla macchina senza connettività Internet, caricare l'immagine ed eseguirla .

Dimostrazione

Non ci sono immagini sul sistema A:

userA@systemA ~ $ docker images
REPOSITORY        TAG               IMAGE ID          CREATED             SIZE
userA@systemA ~ $

Estrai un'immagine da dockerhub:

userA@systemA ~ $
docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
bc95e04b23c0: Pull complete 
f3186e650f4e: Pull complete 
9ac7d6621708: Pull complete 
Digest: sha256:b81f317384d7388708a498555c28a7cce778a8f291d90021208b3eba3fe74887
Status: Downloaded newer image for nginx:latest
userA@systemA ~ $ docker images
REPOSITORY        TAG               IMAGE ID            CREATED             SIZE
nginx             latest            9e7424e5dbae        10 days ago         108MB

Salva immagine docker:

userA@systemA ~ $ docker save nginx -o nginx.tar

Copia l'immagine docker su systemB e caricala.

userB@systemB ~ $ docker load -i nginx.tar
cec7521cdf36: Loading layer  58.44MB/58.44MB
350d50e58b6c: Loading layer  53.76MB/53.76MB
63c39cd4a775: Loading layer  3.584kB/3.584kB
Loaded image: nginx:latest
userB@systemB ~ $ docker images
REPOSITORY        TAG               IMAGE ID            CREATED             SIZE
nginx             latest            9e7424e5dbae        10 days ago         108MB

1
La macchina con connettività Internet non ha e non può avere Docker installato. La domanda è chiedere un modo per scaricare un'immagine senza utilizzare il client Docker. Vedere la mia soluzione .
igal,

0

Ecco uno script python adattato, con una soluzione indipendente dal sistema operativo: docker-drag

Usalo in questo modo e creerà un archivio TAR che sarai in grado di importare usando il docker load:

python docker_pull.py hello-world
python docker_pull.py alpine:3.9
python docker_pull.py kalilinux/kali-linux-docker

1
Se chiudi il tuo account github non è rimasto nulla, se sei d'accordo con la condivisione, mantieni il link ma incolla qui anche lo script. È possibile modificare la risposta, incollare il codice, quindi selezionarlo e digitare ctrl + K o il {}pulsante (codice) nella barra superiore dell'editor per formattarlo.
Tensibai,

Mi piacerebbe incollare il codice qui, ma è lungo 100 righe e non credo che sarà leggibile. Tuttavia, puoi forkare il codice per salvare la tua copia dello script.
Dutfaz,

Non è per me che avere una risposta autosufficiente, in caso di interruzione del collegamento, pensi davvero che questo possa aiutare qualcuno a leggere questa risposta tra qualche mese? (tra la dimensione massima per una risposta è di 30k caratteri)
Tensibai
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.