Herunterladen von Docker-Bildern von Docker Hub ohne Verwendung von Docker

32

Ich möchte ein Docker-Image manuell von Docker Hub herunterladen . Insbesondere möchte ich ein Docker-Image von Docker Hub auf einen Computer in einer eingeschränkten Umgebung herunterladen, auf dem die Docker-Client-Software nicht installiert ist (und nicht installiert werden kann). Ich hätte gedacht, dass dies mit der offiziellen API möglich wäre , aber dies scheint nicht der Fall zu sein - siehe folgende Diskussion:

Ist es wirklich so, dass die API das Herunterladen von Bildern nicht unterstützt? Gibt es eine Möglichkeit, dies zu umgehen?


UPDATE 1:

Ich bin auf folgenden ServerFault-Beitrag gestoßen:

Die akzeptierte Lösung verwendet den docker saveBefehl, der in meiner Situation nicht hilft. Eine andere dort veröffentlichte Lösung nennt jedoch den folgenden StackOverflow-Beitrag:

Eine der dortigen Lösungen bezieht sich auf ein Befehlszeilentool namens Docker-Registry-Debug, das unter anderem einen curlBefehl zum Herunterladen eines Bildes generieren kann . Folgendes habe ich bekommen:

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

Es sieht also leider so aus, als würde der curlgenerierte Befehl nicht funktionieren.


UPDATE 2:

Es sieht so aus, als ob ich Layer-Blobs von Docker Hub herunterladen kann. Hier ist, wie ich es gerade mache.

Holen Sie sich ein Autorisierungstoken:

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' \
)"

Ziehen Sie ein Bildmanifest:

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

Ziehen Sie ein Bildmanifest und extrahieren Sie die Blobsummen:

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

Laden Sie einen einzelnen Layer-Blob herunter und schreiben Sie ihn in eine Datei:

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"

Schreiben Sie alle Blobsummen in eine Datei:

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

Laden Sie alle Layer-Blobs aus dem Manifest herunter:

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

Jetzt habe ich ein paar Layer-Blobs, die ich zu einem Bild zusammenfügen muss - glaube ich.


Ähnliche Links:

igal
quelle
"Insbesondere möchte ich ein Docker-Image von Docker Hub auf einen Computer in einer eingeschränkten Umgebung herunterladen, auf dem die Docker-Client-Software nicht installiert ist (und nicht installiert werden kann)." => Was nützt es, wenn die Bilder auf diesem Computer gespeichert sind? (Einfachere Problemumgehung ist die Verwendung eines Pivot-Hosts, bei dem Sie von Dockerhub und Docker Save / Docker Push zu einer internen Registrierung
wechseln.
@Tensibai Zum Kopieren auf einen anderen Computer, der über Docker verfügt, jedoch keinen Internetzugang hat.
30.
Haben Sie sich den Docker Pull Code angesehen? Es ist der
richtige
@Tensibai Ich glaube, ich habe es herausgefunden. Ich denke auch, dass ich eine Lösung von der Docker-Community bekommen habe. Ich werde später heute zurückkommen und die Lösung posten.
30.
@Tensibai Ich habe eine Lösung mit einem Shell-Skript gepostet , das das Problem löst.
3.

Antworten:

23

Es stellt sich also heraus, dass das Moby-Projekt ein Shell-Skript auf dem Moby Github hat, mit dem Bilder von Docker Hub in einem Format heruntergeladen werden können, das in Docker importiert werden kann:

Die Verwendungssyntax für das Skript lautet wie folgt:

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

Das Bild kann dann mit tarund importiert werden docker load:

tar -cC 'target_dir' . | docker load

Um sicherzustellen, dass das Skript wie erwartet funktioniert, habe ich ein Ubuntu-Image von Docker Hub heruntergeladen und in Docker geladen:

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 der Praxis würde ich zuerst müssen die Daten aus dem Internet Client kopieren (was nicht nicht Docker installiert ist ) an das Ziel / Zielmaschine (die nicht Docker installiert ist ):

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:~

Laden Sie das Image und verwenden Sie es auf dem Zielhost:

user@hasdocker:~ docker load ubuntu.tar
user@hasdocker:~ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#
igal
quelle
The machine with internet connectivity does not and cannot have Docker installed. aber Sie bewerben sichdocker load
030
@ 030 Nur um zu testen / zu demonstrieren, dass das Skript funktioniert und die heruntergeladenen Bilddaten in Docker importiert werden können. In der Praxis müsste ich zuerst die Daten auf einen Computer mit Docker kopieren.
3.
Vielleicht könnten Sie diesen Teil zur Klarstellung hinzufügen
030
2
@ 030 Ich habe eine Beispielsitzung hinzugefügt, die veranschaulicht, wie der Workflow in der Praxis aussehen würde.
3.
7

Es gibt ein Tool namens Skopeo, mit dem Docker-Bilder aus einem Repository abgerufen und in verschiedenen Formaten gespeichert werden können.

Beispielsweise:

  1. Lade das Bild herunter und speichere die Ebenen als Tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. Übertragen /tmp/ubuntu.tarauf eine andere Maschine , falls gewünscht.

  3. Laden Sie das Image auf eine Docker-Instanz ohne Internetverbindung: docker load --input /tmp/ubuntu.tar

Es ist in CentOS 7 Repo mit dem Paketnamen verfügbar skopeo. Zur Zeit gibt es keine Debian- oder Ubuntu-Pakete (aber es ist einfach zu kompilieren).

schnappen
quelle
3

danke für die motivation. Ich habe eine Powershell-Version davon gemacht. Probieren Sie es aus ... Damit können Sie in Dockerhub-Containern mit einem Windows-Desktop und einem SSH-SCP-Tool ohne Root- oder Administratorrechte zu einem eingeschränkten Docker-Netzwerk wechseln

https://gitlab.com/Jancsoj78/dockerless_docker_downloader ein neues Hacker-Tool :)

$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"
Jancsó József
quelle
1

Mir ist nicht ganz klar, was Sie erreichen wollen und warum die Versuche keine Lösung für das Problem sind. Wenn ich dieses Problem lösen müsste, möchte ich, dass @Tensibai und andere Fragen und Antworten angezeigt werden. Führen Sie zuerst einen Docker-Pull auf einem System mit Internetverbindung aus, speichern Sie das Docker-Image, kopieren Sie es auf den Computer ohne Internetverbindung, laden Sie das Image und führen Sie es aus .

Demonstration

Auf System A sind keine Bilder vorhanden:

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

Ein Bild von dockerhub ziehen:

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

Docker-Bild speichern:

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

Kopieren Sie das Docker-Image nach systemB und laden Sie es.

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
030
quelle
1
Auf dem Computer mit Internetverbindung ist Docker nicht installiert und kann nicht installiert werden. Die Frage lautet, wie Sie ein Bild herunterladen können, ohne den Docker-Client zu verwenden. Siehe meine Lösung .
3.
0

Hier ist ein angepasstes Python-Skript, das eine vom Betriebssystem unabhängige Lösung bietet: Docker-Drag

Verwenden Sie es wie folgt und erstellen Sie ein TAR-Archiv, das Sie mit docker load importieren können:

python docker_pull.py hello-world
python docker_pull.py alpine:3.9
python docker_pull.py kalilinux/kali-linux-docker
Dutfaz
quelle
1
Wenn Sie Ihr Github-Konto schließen, bleibt nichts mehr übrig. Wenn Sie es freigeben möchten, behalten Sie den Link bei, fügen Sie das Skript aber bitte auch hier ein. Sie können Ihre Antwort bearbeiten , Ihren Code einfügen und dann auswählen und Strg + K oder die {}Schaltfläche (Code) in der oberen Leiste des Editors eingeben, um sie zu formatieren.
Tensibai
Ich würde den Code gerne hier einfügen, aber er ist 100 Zeilen lang und ich glaube nicht, dass er lesbar ist. Trotzdem können Sie den Code teilen, um Ihre eigene Kopie des Skripts zu speichern.
Dutfaz
Das ist nichts für mich, eine Antwort zu haben, die sich selbst erhält, wenn die Verbindung unterbrochen wird. Glaubst du wirklich, dass dies jemandem helfen kann, diese Antwort in ein paar Monaten zu lesen? (Übrigens ist die maximale Größe für eine Antwort 30k Zeichen)
Tensibai