Mengunduh Gambar Docker dari Docker Hub tanpa menggunakan Docker

32

Saya ingin mengunduh secara manual Gambar Docker dari Docker Hub . Lebih khusus lagi, saya ingin mengunduh Gambar Docker dari Docker Hub pada mesin di lingkungan terbatas yang tidak (dan tidak bisa) menginstal perangkat lunak klien Docker. Saya akan berpikir bahwa ini akan mungkin menggunakan API resmi , tetapi ini tampaknya bukan kasusnya - lihat diskusi berikut:

Benarkah API tidak mendukung pengunduhan gambar? Apakah ada cara untuk mengatasi ini?


PEMBARUAN 1:

Saya menemukan posting ServerFault berikut:

The solusi yang diterima menggunakan docker saveperintah, yang tidak membantu dalam situasi saya. Tetapi solusi lain yang diposting di sana mengutip posting StackOverflow berikut:

Salah satu solusi yang ada mengacu pada alat baris perintah yang disebut docker-registry-debug yang, antara lain, dapat menghasilkan curlperintah untuk mengunduh gambar. Inilah yang saya dapat:

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

Jadi sayangnya sepertinya curlperintah yang dihasilkan tidak berfungsi.


PEMBARUAN 2:

Sepertinya saya dapat mengunduh layer gumpalan dari Docker Hub. Ini adalah bagaimana saya saat ini akan melakukannya.

Dapatkan token otorisasi:

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

Tarik manifes gambar:

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

Tarik manifes gambar dan ekstrak jumlah gumpalan:

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

Unduh satu lapisan gumpalan dan tulis ke 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"

Tulis semua jumlah gumpalan ke 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

Unduh semua gumpalan layer dari manifes:

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

Sekarang saya memiliki banyak gumpalan layer dan saya perlu menggabungkannya kembali menjadi gambar - saya pikir.


Tautan yang berhubungan:

igal
sumber
"Lebih khusus, saya ingin mengunduh Gambar Docker dari Docker Hub pada mesin di lingkungan terbatas yang tidak (dan tidak bisa) menginstal perangkat lunak klien Docker." => Apa gunanya memiliki gambar pada mesin ini? (solusi yang lebih mudah adalah menggunakan host pivot, di mana Anda dapat menarik buruh pelabuhan dari dockerhub dan mendorong / menyimpan buruh pelabuhan ke registri internal setelahnya)
Tensibai
@Tensibai Untuk menyalinnya ke komputer lain yang tidak memiliki Docker tetapi tidak memiliki akses internet.
igal
Apakah Anda sudah melihat kode tarik buruh pelabuhan? Kedengarannya cara untuk membangun sesuatu seperti ini dari panggilan http dasar
Tensibai
@Tensibai kurasa aku sudah menemukannya. Saya juga berpikir saya mendapat solusi dari komunitas Docker. Saya akan kembali dan memposting solusinya hari ini.
igal
@Tensibai Saya memposting solusi dengan skrip shell yang memecahkan masalah.
igal

Jawaban:

23

Jadi ternyata Proyek Moby memiliki skrip shell pada Moby Github yang dapat mengunduh gambar dari Docker Hub dalam format yang dapat diimpor ke Docker:

Sintaks penggunaan untuk skrip diberikan oleh yang berikut:

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

Gambar kemudian dapat diimpor dengan tardan docker load:

tar -cC 'target_dir' . | docker load

Untuk memverifikasi bahwa skrip berfungsi seperti yang diharapkan, saya mengunduh gambar Ubuntu dari Docker Hub dan memuatnya ke 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:/#

Dalam praktiknya saya harus menyalin data dari klien internet (yang tidak memiliki Docker diinstal) ke mesin target / tujuan (yang tidak memiliki Docker diinstal):

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

dan kemudian memuat dan menggunakan gambar pada host target:

user@hasdocker:~ docker load ubuntu.tar
user@hasdocker:~ docker run --rm -ti ubuntu bash
root@1dd5e62113b9:/#
igal
sumber
The machine with internet connectivity does not and cannot have Docker installed. tetapi Anda melamardocker load
030
@ 030 Hanya untuk menguji / menunjukkan bahwa skrip berfungsi dan bahwa data gambar unduhan dapat diimpor ke Docker. Dalam praktiknya, saya pertama-tama harus menyalin data ke mesin dengan Docker diinstal.
igal
Mungkin Anda bisa menambahkan bagian itu untuk klarifikasi
030
2
@ 030 Saya menambahkan sesi contoh yang menggambarkan seperti apa alur kerjanya dalam praktik.
igal
7

Ada alat yang disebut Skopeo yang dapat mengambil gambar Docker dari repositori dan menyimpannya dalam beberapa format.

Sebagai contoh:

  1. Unduh gambar dan simpan layer sebagai tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. Transfer /tmp/ubuntu.tarke mesin lain jika diinginkan.

  3. Memuat gambar pada instance Docker yang tidak memiliki koneksi internet: docker load --input /tmp/ubuntu.tar

Ini tersedia dalam repo CentOS 7 dengan nama paket skopeo. Tidak ada paket Debian atau Ubuntu saat ini (tetapi mudah dikompilasi).

jepret
sumber
3

terima kasih untuk motivasi. Saya membuat versi PowerShell. Lihat ... Dengan itu Anda dapat memindahkan wadah dockerhub ke jaringan buruh pelabuhan terbatas dengan desktop windows dan alat ssh-scp ke mesin buruh pelabuhan tanpa hak root atau administrator

https://gitlab.com/Jancsoj78/dockerless_docker_downloader alat hacker baru :)

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

Bagi saya tidak sepenuhnya jelas apa yang ingin Anda capai dan mengapa upaya tersebut bukan solusi untuk masalah tersebut. Jika saya perlu menyelesaikan masalah ini, saya ingin @Tensibai dan Tanya Jawab lainnya seperti yang ditunjukkan, lakukan docker pull pada sistem dengan konektivitas internet, simpan gambar buruh pelabuhan, salin ke mesin tanpa konektivitas internet, muat gambar dan jalankan .

Demonstrasi

Tidak ada gambar di sistem A:

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

Tarik gambar dari 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

Simpan gambar buruh pelabuhan:

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

Salin gambar buruh pelabuhan ke systemB dan muat.

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
sumber
1
Mesin dengan konektivitas internet tidak dan tidak dapat menginstal Docker. Pertanyaannya adalah meminta cara untuk mengunduh gambar tanpa menggunakan klien Docker. Lihat solusi saya .
igal
0

Berikut ini adalah skrip python yang diadaptasi, sehingga memiliki solusi independen OS: docker-drag

Gunakan seperti itu, dan itu akan membuat arsip TAR yang dapat Anda impor menggunakan beban buruh pelabuhan:

python docker_pull.py hello-world
python docker_pull.py alpine:3.9
python docker_pull.py kalilinux/kali-linux-docker
Dutfaz
sumber
1
Jika Anda menutup akun github Anda, tidak ada yang tersisa, jika Anda setuju membagikannya, simpan tautannya, tetapi tempelkan skrip di sini juga. Anda dapat mengedit jawaban Anda, menempelkan kode Anda dan kemudian memilihnya dan ketik ctrl + K atau tombol {}(kode) di bilah atas editor untuk memformatnya.
Tensibai
Saya ingin menempelkan kode di sini tetapi panjangnya 100 baris dan saya pikir itu tidak akan bisa dibaca. Meskipun demikian, Anda dapat melakukan fork kode untuk menyimpan salinan skrip Anda sendiri.
Dutfaz
Itu bukan untuk saya, bahwa untuk memiliki jawaban yang mandiri, jika tautannya terputus, apakah Anda benar-benar berpikir ini dapat membantu seseorang membaca jawaban ini dalam beberapa bulan? (btw ukuran maksimum untuk jawaban adalah 30k karakter)
Tensibai