Pobieranie obrazów Docker z Docker Hub bez korzystania z Docker


32

Chcę ręcznie pobrać obraz Docker z Docker Hub . Mówiąc dokładniej, chcę pobrać obraz Docker z Docker Hub na maszynie w ograniczonym środowisku, które nie ma (i nie może) mieć zainstalowanego oprogramowania klienckiego Docker. Myślałem, że byłoby to możliwe przy użyciu oficjalnego interfejsu API , ale nie wydaje się, że tak jest - patrz następująca dyskusja:

Czy tak naprawdę jest tak, że interfejs API nie obsługuje pobierania obrazów? Czy istnieje sposób na obejście tego?


AKTUALIZACJA 1:

Natrafiłem na następujący wpis ServerFault:

Przyjętego rozwiązania korzysta z docker savekomendy, która nie pomaga w mojej sytuacji. Ale inne opublikowane tam rozwiązanie cytuje następujący post StackOverflow:

Jedno z rozwiązań odnosi się do narzędzia wiersza polecenia o nazwie docker-register-debug, które między innymi może wygenerować curlpolecenie pobierania obrazu. Oto co mam:

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

Niestety wygląda na to, że curlwygenerowane polecenie nie działa.


AKTUALIZACJA 2:

Wygląda na to, że mogę pobrać obiekty BLOB warstwy z Docker Hub. Oto, w jaki sposób obecnie o tym mówię.

Uzyskaj token autoryzacji:

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

Wyciągnij manifest obrazu:

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

Wyciągnij manifest obrazu i wyodrębnij sumy kropli:

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

Pobierz jednowarstwowy obiekt blob i zapisz go do pliku:

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"

Zapisz wszystkie sumy obiektów blob do pliku:

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

Pobierz wszystkie obiekty BLOB warstwy z manifestu:

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

Teraz mam kilka warstwowych obiektów blob i muszę je ponownie połączyć w obraz - tak myślę.


Powiązane linki:


„Mówiąc dokładniej, chcę pobrać obraz Docker z Docker Hub na maszynie w ograniczonym środowisku, w którym nie ma (i nie można) zainstalować oprogramowania klienckiego Docker”. => Po co więc mieć obrazy na tym komputerze? (łatwiejszym obejściem jest użycie hosta przestawnego, takiego, w którym acer docker ściąga z dockerhub i zapisuje / pusher docker do wewnętrznego rejestru po)
— Tensibai

@Tensibai Aby skopiować go na inną maszynę, która ma Docker, ale nie ma dostępu do Internetu.
— igal

Czy obejrzałeś kod ściągający dokera? Wydaje się, że można zbudować coś takiego z podstawowych wywołań http
— Tensibai

@Tensibai Chyba to rozgryzłem. Myślę też, że dostałem rozwiązanie od społeczności Docker. Wrócę i opublikuję rozwiązanie później dzisiaj.
— igal

@Tensibai Opublikowałem rozwiązanie ze skryptem powłoki, który rozwiązuje problem.
— igal

Odpowiedzi:


23

Okazuje się, że Moby Project ma skrypt powłoki na Moby Github, który może pobierać obrazy z Docker Hub w formacie, który można zaimportować do Docker:

Składnia użycia skryptu jest następująca:

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

Obraz można następnie zaimportować za pomocą tari docker load:

tar -cC 'target_dir' . | docker load

Aby sprawdzić, czy skrypt działa zgodnie z oczekiwaniami, pobrałem obraz Ubuntu z Docker Hub i załadowałem go do 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:/#

W praktyce musiałbym najpierw skopiować dane z klienta internetowego (który ma nie mieć zainstalowany Docker) do docelowej / maszyny docelowej (który ma być zainstalowany 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:~

a następnie załaduj i użyj obrazu na hoście docelowym:

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. ale aplikujeszdocker load
— 030

@ 030 Wystarczy przetestować / wykazać, że skrypt działa i że dane obrazu do pobrania można zaimportować do Docker. W praktyce najpierw musiałbym skopiować dane na maszynę z zainstalowanym Dockerem.
— igal

Być może mógłbyś dodać tę część w celu wyjaśnienia
— 030

2
@ 030 Dodałem przykładową sesję ilustrującą przepływ pracy w praktyce.
— igal

7

Istnieje narzędzie o nazwie Skopeo, które może pobierać obrazy Docker z repozytorium i zapisywać je w kilku formatach.

Na przykład:

  1. Pobierz obraz i zapisz warstwy jako tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. W /tmp/ubuntu.tarrazie potrzeby przenieś na inną maszynę.

  3. Załaduj obraz do instancji Docker, która nie ma połączenia z Internetem: docker load --input /tmp/ubuntu.tar

Jest dostępny w repozytorium CentOS 7 z nazwą pakietu skopeo. Obecnie nie ma pakietów Debian ani Ubuntu (ale łatwo je skompilować).


3

dzięki za motywację. Zrobiłem wersję PowerShell. Sprawdź to ... Dzięki niemu możesz przenosić kontenery dockerhub do ograniczonych sieci dokerów z pulpitem systemu Windows i narzędziem ssh-scp do maszyny dokującej bez uprawnień użytkownika root lub administratora

https://gitlab.com/Jancsoj78/dockerless_docker_downloader nowe narzędzie hakera :)

$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

Dla mnie nie jest całkowicie jasne, co próbujesz osiągnąć i dlaczego próby nie są rozwiązaniem problemu. Gdybym musiał rozwiązać ten problem, chciałbym @Tensibai i inne pytania i odpowiedzi, jak wskazano, najpierw wykonaj dokerowanie w systemie z łącznością internetową, zapisz obraz dokera, skopiuj go na maszynę bez połączenia z Internetem, załaduj obraz i uruchom go .

Demonstracja

Brak obrazu w systemie A:

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

Wyciągnij obraz z 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

Zapisz obraz dokera:

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

Skopiuj obraz dokera do systemu B i załaduj go.

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
W urządzeniu z połączeniem internetowym nie ma zainstalowanego Dockera. Pytanie dotyczy sposobu pobrania obrazu bez korzystania z klienta Docker. Zobacz moje rozwiązanie .
— igal

0

Oto dostosowany skrypt Pythona, który ma rozwiązanie niezależne od systemu operacyjnego: docker-drag

Użyj go w ten sposób, aby utworzyć archiwum TAR, które będziesz mógł zaimportować za pomocą obciążenia dokera:

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

1
Jeśli zamkniesz swoje konto github, nic nie pozostanie, jeśli zgadzasz się z jego udostępnieniem, zachowaj link, ale także wklej tutaj skrypt. Możesz edytować swoją odpowiedź, wkleić kod, a następnie wybrać go i wpisać ctrl + K lub przycisk {}(kod) na górnym pasku edytora, aby go sformatować.
— Tensibai

Chciałbym tu wkleić kod, ale ma on 100 wierszy i nie sądzę, żeby był czytelny. Niemniej jednak możesz rozwidlić kod, aby zapisać własną kopię skryptu.
— Dutfaz

To nie dla mnie, żeby mieć odpowiedź, która jest samowystarczalna, jeśli link się zepsuje, czy naprawdę uważasz, że może to pomóc komuś czytając tę ​​odpowiedź za kilka miesięcy? (przy okazji maksymalny rozmiar odpowiedzi to 30
— 000
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.