Download de imagens do Docker do Docker Hub sem usar o Docker

32

Quero baixar manualmente uma imagem do Docker do Docker Hub . Mais especificamente, quero baixar uma imagem do Docker do Docker Hub em uma máquina em um ambiente restrito que não possui (e não pode) ter o software cliente do Docker instalado. Eu pensaria que isso seria possível usando a API oficial , mas isso não parece ser o caso - consulte a seguinte discussão:

É realmente o caso de a API não suportar o download de imagens? Existe uma maneira de contornar isso?


ATUALIZAÇÃO 1:

Me deparei com a seguinte postagem ServerFault:

A solução aceita usa o docker savecomando, o que não ajuda na minha situação. Mas outra solução publicada lá cita a seguinte postagem do StackOverflow:

Uma das soluções refere-se a uma ferramenta de linha de comando chamada docker-registry-debug que, entre outras coisas, pode gerar um curlcomando para baixar uma imagem. Aqui está o que eu tenho:

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

Infelizmente, parece que o curlcomando gerado não funciona.


ATUALIZAÇÃO 2:

Parece que sou capaz de baixar blobs de camada do Docker Hub. Aqui está como eu estou indo sobre isso atualmente.

Obtenha um token de autorização:

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

Puxe um manifesto de imagem:

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

Puxe um manifesto de imagem e extraia as somas do 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

Faça o download de um blob de camada única e grave-o em um arquivo:

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"

Escreva todas as somas do blob em um arquivo:

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

Faça o download de todos os blobs de camada do manifesto:

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

Agora eu tenho vários blobs de camada e preciso recombiná-los em uma imagem - eu acho.


Links Relacionados:

igal
fonte
"Mais especificamente, quero fazer o download de uma imagem do Docker do Docker Hub em uma máquina em um ambiente restrito que não possui (e não pode) ter o software cliente do Docker instalado." => Qual é o objetivo de ter as imagens nesta máquina então? (mais fácil solução alternativa é usar uma série de pivô, aquele em que você acn puxar janela de encaixe de dockerhub e estivador save / push janela de encaixe para um registro interno depois)
Tensibai
@Tensibai Para copiá-lo para outra máquina que faz tem Docker mas não têm acesso à Internet.
Igal
Você deu uma olhada no código pull do docker? Parece o caminho a percorrer para construir algo como isto desde o básico http chama
Tensibai
@ Tensibai Acho que descobri. Também acho que recebi uma solução da comunidade do Docker. Voltarei e publicarei a solução ainda hoje.
Igal
@ Tensibai Publiquei uma solução com um script de shell que resolve o problema.
Igal

Respostas:

23

Portanto, o Moby Project possui um shell script no Moby Github que pode baixar imagens do Docker Hub em um formato que pode ser importado para o Docker:

A sintaxe de uso para o script é fornecida pelo seguinte:

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

A imagem pode ser importada com tare docker load:

tar -cC 'target_dir' . | docker load

Para verificar se o script funciona conforme o esperado, baixei uma imagem do Ubuntu do Docker Hub e carreguei no 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:/#

Na prática, eu teria que primeiro copie os dados do cliente internet (o que não tem Docker instalado) para a máquina de destino / destino (que não têm 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:~

e carregue e use a imagem no host de destino:

user@hasdocker:~ docker load ubuntu.tar
user@hasdocker:~ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#
igal
fonte
The machine with internet connectivity does not and cannot have Docker installed. mas você se inscreveudocker load
030
@ 030 Apenas para testar / demonstrar que o script funciona e que os dados da imagem de download podem ser importados para o Docker. Na prática, eu primeiro teria que copiar os dados em uma máquina com o Docker instalado.
Igal
Talvez você possa adicionar essa parte para esclarecimentos.
030
2
@ 030 Adicionei uma sessão de exemplo que ilustra como seria o fluxo de trabalho na prática.
Igal
7

Existe uma ferramenta chamada Skopeo que pode recuperar imagens do Docker de um repositório e salvá-las em vários formatos.

Por exemplo:

  1. Faça o download da imagem e salve as camadas como um tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. Transfira /tmp/ubuntu.tarpara outra máquina, se desejar.

  3. Carregue a imagem em uma instância do Docker que não possui conexão à Internet: docker load --input /tmp/ubuntu.tar

Está disponível no repositório do CentOS 7 com o nome do pacote skopeo. Não há pacotes Debian ou Ubuntu no momento (mas é fácil compilar).

estalar
fonte
3

obrigado pela motivação. Eu fiz uma versão powerhell dele. Confira ... Com ele, você pode mover contêineres do dockerhub para redes de docker restritas com uma área de trabalho do windows e uma ferramenta ssh-scp para a docker machine sem direitos de administrador ou root

https://gitlab.com/Jancsoj78/dockerless_docker_downloader uma nova ferramenta 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"
Jancsó József
fonte
1

Para mim, não está completamente claro o que você está tentando alcançar e por que as tentativas não são uma solução para o problema. Se eu precisar resolver esse problema, gostaria que o @Tensibai e outras perguntas e respostas indicadas fizessem uma janela de encaixe primeiro em um sistema com conectividade à Internet, salve a imagem da janela de encaixe, copie-a para a máquina sem conectividade à Internet, carregue a imagem e execute-a .

Demonstração

Não há imagens no sistema A:

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

Puxe uma imagem do 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

Salvar imagem da janela de encaixe:

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

Copie a imagem da janela de encaixe para systemB e carregue-a.

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
fonte
1
A máquina com conectividade à Internet não possui e não pode ter o Docker instalado. A pergunta está pedindo uma maneira de baixar uma imagem sem usar o cliente Docker. Veja minha solução .
Igal
0

Aqui está um script python adaptado, com uma solução independente do SO: docker-drag

Use-o assim e criará um arquivo TAR que você poderá importar usando o docker load:

python docker_pull.py hello-world
python docker_pull.py alpine:3.9
python docker_pull.py kalilinux/kali-linux-docker
Dutfaz
fonte
1
Se você fechar sua conta do github, não resta mais nada; se você concorda em compartilhá-la, mantenha o link, mas cole o script aqui também. Você pode editar sua resposta, colar seu código e, em seguida, selecioná-lo e digitar ctrl + K ou o {}botão (código) na barra superior do editor para formatá-lo.
Tensibai 9/04
Eu adoraria colar o código aqui, mas ele tem 100 linhas e não acho que seja legível. No entanto, você pode bifurcar o código para salvar sua própria cópia do script.
Dutfaz 9/04
Isso não é para mim, que ter uma resposta auto-sustentável, se o link quebrar, você realmente acha que isso pode ajudar alguém a ler essa resposta em alguns meses? (o tamanho máximo para uma resposta é 30k caracteres)
Tensibai 9/04