Descargar imágenes de Docker desde Docker Hub sin usar Docker

32

Quiero descargar manualmente una imagen de Docker desde Docker Hub . Más específicamente, quiero descargar una imagen de Docker de Docker Hub en una máquina en un entorno restringido que no tiene (y no puede) tener instalado el software del cliente Docker. Pensé que esto sería posible utilizando la API oficial , pero este no parece ser el caso; consulte la siguiente discusión:

¿Es realmente el caso de que la API no admite la descarga de imágenes? ¿Hay alguna manera de evitar esto?


ACTUALIZACIÓN 1:

Me encontré con la siguiente publicación de ServerFault:

La solución aceptada utiliza el docker savecomando, que no ayuda en mi situación. Pero otra solución publicada allí cita la siguiente publicación de StackOverflow:

Una de las soluciones allí se refiere a una herramienta de línea de comandos llamada docker-Registry-Debug que, entre otras cosas, puede generar un curlcomando para descargar una imagen. Esto es lo que obtuve:

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

Desafortunadamente, parece que el curlcomando generado no funciona.


ACTUALIZACIÓN 2:

Parece que puedo descargar blobs de capa desde Docker Hub. Así es como lo estoy haciendo actualmente.

Obtenga un token de autorización:

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

Tire de un manifiesto de imagen:

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

Tire de un manifiesto de imagen y extraiga las sumas de 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

Descargue un blob de una sola capa y escríbalo en un archivo:

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"

Escriba todas las sumas de blob en un archivo:

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

Descargue todos los blobs de capa del manifiesto:

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

Ahora tengo un montón de capas de blobs y necesito recombinarlas en una imagen, creo.


Enlaces relacionados:

igal
fuente
"Más específicamente, quiero descargar una imagen Docker de Docker Hub en una máquina en un entorno restringido que no tiene (y no puede) tener instalado el software del cliente Docker". => ¿Cuál es el punto de tener las imágenes en esta máquina entonces? (una solución más fácil es usar un host de pivote, uno en el que acn docker extrae de dockerhub y docker save / docker push a un registro interno después)
Tensibai
@Tensibai para copiarlo en otra máquina que lo hace tener estibador, pero no tienen acceso a Internet.
Igal
¿Le echó un vistazo al código de extracción de la ventana acoplable? Parece el camino a seguir para construir algo como esto a partir de llamadas http básicas
Tensibai
@Tensibai Creo que lo descubrí. También creo que obtuve una solución de la comunidad Docker. Volveré y publicaré la solución más tarde hoy.
Igal
@Tensibai Publiqué una solución con un script de shell que resuelve el problema.
igal

Respuestas:

23

Resulta que el Proyecto Moby tiene un script de shell en Moby Github que puede descargar imágenes de Docker Hub en un formato que se puede importar a Docker:

La sintaxis de uso para el script viene dada por lo siguiente:

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

La imagen se puede importar con tary docker load:

tar -cC 'target_dir' . | docker load

Para verificar que el script funciona como se esperaba, descargué una imagen de Ubuntu de Docker Hub y la cargué en 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:/#

En la práctica, primero tendría que copiar los datos del cliente de Internet (que no tiene Docker instalado) en la máquina de destino / destino (que tiene Docker instalado):

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

y luego cargue y use la imagen en el host de destino:

user@hasdocker:~ docker load ubuntu.tar
user@hasdocker:~ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#
igal
fuente
The machine with internet connectivity does not and cannot have Docker installed. pero usted aplicadocker load
030
@ 030 Solo para probar / demostrar que el script funciona y que los datos de la imagen de descarga se pueden importar a Docker. En la práctica, primero tendría que copiar los datos a una máquina con Docker instalado.
igal
Quizás podría agregar esa parte para aclaración
030
2
@ 030 Agregué una sesión de ejemplo que ilustra cómo se vería el flujo de trabajo en la práctica.
Igual
7

Existe una herramienta llamada Skopeo que puede recuperar imágenes de Docker de un repositorio y guardarlas en varios formatos.

Por ejemplo:

  1. Descargue la imagen y guarde las capas como un tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. Transfiera /tmp/ubuntu.tara otra máquina si lo desea.

  3. Cargue la imagen en una instancia de Docker que no tenga conexión a Internet: docker load --input /tmp/ubuntu.tar

Está disponible en CentOS 7 repo con el nombre del paquete skopeo. No hay paquetes Debian o Ubuntu en este momento (pero es fácil de compilar).

chasquido
fuente
3

Gracias por la motivación. Hice una versión de PowerShell. Compruébelo ... Con él, puede mover los contenedores de dockerhub a una red de docker restringida con un escritorio de Windows y una herramienta ssh-scp para la máquina docker sin derechos de administrador o root

https://gitlab.com/Jancsoj78/dockerless_docker_downloader una nueva herramienta de hackers :)

$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
fuente
1

Para mí, no está completamente claro lo que está tratando de lograr y por qué los intentos no son una solución para el problema. Si tuviera que resolver este problema, me gustaría @Tensibai y otras preguntas y respuestas indicadas, haga primero una ventana acoplable en un sistema con conectividad a Internet, guarde la imagen de la ventana acoplable, cópiela en la máquina sin conexión a Internet, cargue la imagen y ejecútela. .

Demostración

No hay imágenes en el sistema A:

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

Extrae una imagen de 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

Guardar imagen acoplable:

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

Copie la imagen del acoplador en systemB y cárguela.

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
fuente
1
La máquina con conectividad a Internet no tiene y no puede tener Docker instalado. La pregunta es pedir una forma de descargar una imagen sin usar el cliente Docker. Mira mi solución .
igal
0

Aquí hay un script de Python adaptado, que tiene una solución independiente del SO: docker-drag

Úselo así, y creará un archivo TAR que podrá importar utilizando la carga acoplable:

python docker_pull.py hello-world
python docker_pull.py alpine:3.9
python docker_pull.py kalilinux/kali-linux-docker
Dutfaz
fuente
1
Si cierra su cuenta de github, no queda nada, si está de acuerdo con compartirla, mantenga el enlace pero pegue el script aquí también, por favor. Puede editar su respuesta, pegar su código y luego seleccionarlo y escribir ctrl + K o el {}botón (código) en la barra superior del editor para formatearlo.
Tensibai
Me encantaría pegar el código aquí, pero tiene 100 líneas de longitud y no creo que sea legible. Sin embargo, puede bifurcar el código para guardar su propia copia del script.
Dutfaz
Eso no es para mí, tener una respuesta que sea autosuficiente, si se rompe el enlace, ¿realmente crees que esto puede ayudar a alguien a leer esta respuesta en unos meses? (por cierto, el tamaño máximo para una respuesta es de 30k caracteres)
Tensibai