ดาวน์โหลด Docker Images จาก Docker Hub โดยไม่ต้องใช้ Docker


32

ฉันต้องการดาวน์โหลด Docker Image จากDocker Hubด้วยตนเอง โดยเฉพาะอย่างยิ่งฉันต้องการดาวน์โหลดภาพ Docker จาก Docker Hub บนเครื่องในสภาพแวดล้อมที่ จำกัด ซึ่งไม่มี (และไม่สามารถ) ติดตั้งซอฟต์แวร์ไคลเอ็นต์ Docker ได้ ฉันคิดว่าอาจเป็นไปได้ที่จะใช้API อย่างเป็นทางการแต่นี่ไม่ใช่กรณี - ดูการสนทนาต่อไปนี้:

เป็นจริงหรือไม่ที่ API ไม่รองรับการดาวน์โหลดภาพ? มีวิธีแก้ไขไหม


อัปเดต 1:

ฉันเจอโพสต์ ServerFault ต่อไปนี้:

โซลูชั่นที่ได้รับการยอมรับใช้docker saveคำสั่งซึ่งไม่ได้ช่วยในสถานการณ์ของฉัน แต่โซลูชันอื่นที่โพสต์มีอ้างอิงโพสต์ StackOverflow ต่อไปนี้:

หนึ่งในวิธีแก้ปัญหานั้นอ้างถึงเครื่องมือบรรทัดคำสั่งที่เรียกว่าdocker-registry-debugซึ่งสามารถสร้างcurlคำสั่งสำหรับดาวน์โหลดรูปภาพได้ นี่คือสิ่งที่ฉันได้รับ:

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

ดังนั้นน่าเสียดายที่ดูเหมือนว่าcurlคำสั่งที่สร้างขึ้นไม่ทำงาน


อัปเดต 2:

ดูเหมือนว่าฉันสามารถดาวน์โหลดเลเยอร์ blobs จาก Docker Hub นี่คือสิ่งที่ฉันกำลังทำอยู่

รับโทเค็นการอนุญาต:

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

ดึงรายการรูปภาพ:

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

ดึงรายการรูปภาพและแยกจำนวนหยด:

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

ดาวน์โหลดเลเยอร์หยดเดียวแล้วเขียนลงในไฟล์:

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"

เขียนผลรวมของ 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' > ubuntu-blobsums.txt

ดาวน์โหลดเลเยอร์ blobs ทั้งหมดจากไฟล์ Manifest:

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

ตอนนี้ฉันมีเลเยอร์ blobs หลายชั้นและฉันจำเป็นต้องรวมภาพเหล่านั้นกลับเป็นรูปภาพ - ฉันคิดว่า


ลิงก์ที่เกี่ยวข้อง:


"โดยเฉพาะอย่างยิ่งฉันต้องการดาวน์โหลดภาพ Docker จาก Docker Hub บนเครื่องในสภาพแวดล้อมที่ จำกัด ซึ่งไม่มี (และไม่สามารถ) ติดตั้งซอฟต์แวร์ไคลเอ็นต์ Docker ได้" => แล้วจุดที่จะมีภาพในเครื่องนี้คืออะไร? (วิธีแก้ปัญหาได้ง่ายขึ้นคือการใช้โฮสต์เดือยหนึ่งที่คุณ ACN ดึงนักเทียบท่าจาก dockerhub และนักเทียบท่าบันทึก / ผลักดันนักเทียบท่าเพื่อสตรีภายในหลัง)
Tensibai

@Tensibai การคัดลอกไปยังเครื่องอื่นที่ไม่ได้มีหาง แต่ไม่ได้มีการเข้าถึงอินเทอร์เน็ต
igal

คุณเคยดูรหัสดึงนักเทียบท่าหรือไม่? ดูเหมือนจะเป็นไปได้ที่จะสร้างบางสิ่งเช่นนี้จากการโทร http พื้นฐาน
Tensibai

@ Tenensai ฉันคิดว่าฉันคิดออก ฉันยังคิดว่าฉันได้รับการแก้ไขจากชุมชนนักเทียบท่า ฉันจะกลับมาและโพสต์โซลูชันในวันนี้
igal

@ Tensibai ฉันโพสต์วิธีแก้ปัญหาด้วยเชลล์สคริปต์ที่แก้ปัญหาได้
igal

คำตอบ:


23

ดังนั้นปรากฎว่าMoby Projectมีเชลล์สคริปต์บนMoby Githubซึ่งสามารถดาวน์โหลดรูปภาพจากDocker Hubในรูปแบบที่สามารถนำเข้าสู่ Docker:

ไวยากรณ์การใช้งานสำหรับสคริปต์ได้รับดังต่อไปนี้:

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

ภาพนั้นสามารถนำเข้าด้วยtarและdocker load:

tar -cC 'target_dir' . | docker load

เพื่อตรวจสอบว่าสคริปต์ทำงานได้ตามที่คาดไว้ฉันดาวน์โหลดรูปภาพ Ubuntu จาก Docker Hub และโหลดลงใน 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:/#

ในทางปฏิบัติผมจะต้องแรกคัดลอกข้อมูลจากลูกค้าอินเทอร์เน็ต (ซึ่งไม่ได้มีหางติดตั้ง) ไปยังเครื่องเป้าหมาย / ปลายทาง (ซึ่งไม่ได้มีหางติดตั้ง):

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

จากนั้นโหลดและใช้รูปภาพบนโฮสต์เป้าหมาย:

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. แต่คุณสมัครdocker load
030

@ 030 เพียงเพื่อทดสอบ / แสดงให้เห็นว่าสคริปต์ทำงานได้และข้อมูลภาพดาวน์โหลดสามารถนำเข้าไปยัง Docker ได้ ในทางปฏิบัติฉันจะต้องคัดลอกข้อมูลไปยังเครื่องที่ติดตั้ง Docker ก่อน
igal

บางทีคุณอาจเพิ่มส่วนดังกล่าวเพื่อชี้แจง
030

2
@ 030 ฉันได้เพิ่มเซสชันตัวอย่างที่แสดงให้เห็นว่าเวิร์กโฟลว์จะมีลักษณะอย่างไรในทางปฏิบัติ
igal

7

มีเครื่องมือที่เรียกว่าSkopeoซึ่งสามารถเรียกคืนอิมเมจ Docker จากที่เก็บและบันทึกในหลายรูปแบบ

ตัวอย่างเช่น:

  1. ดาวน์โหลดภาพและบันทึกเลเยอร์เป็น tarball: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. ถ่ายโอน/tmp/ubuntu.tarไปยังเครื่องอื่นหากต้องการ

  3. โหลดภาพบนอินสแตนซ์นักเทียบท่าที่ไม่มีการเชื่อมต่ออินเทอร์เน็ต: docker load --input /tmp/ubuntu.tar

มันมีอยู่ใน CentOS 7 repo skopeoกับชื่อแพคเกจ ไม่มีแพ็คเกจ Debian หรือ Ubuntu ในขณะนี้ (แต่มันก็รวบรวมได้ง่าย)


3

ขอบคุณสำหรับแรงจูงใจ ฉันทำรุ่นพาวเวอร์นรกของมัน ลองดู ... คุณสามารถย้ายในคอนเทนเนอร์ dockerhub ไปยังเครือข่ายนักเทียบท่าที่ จำกัด ด้วยเดสก์ท็อป windows และเครื่องมือ ssh-scp ไปยังเครื่องเชื่อมต่อโดยไม่ต้องใช้สิทธิ์ root หรือผู้ดูแลระบบ

https://gitlab.com/Jancsoj78/dockerless_docker_downloader เครื่องมือแฮ็กเกอร์ใหม่ :)

$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

สำหรับฉันมันยังไม่ชัดเจนว่าคุณกำลังพยายามทำอะไรให้สำเร็จและทำไมความพยายามไม่ใช่วิธีแก้ปัญหา หากฉันต้องการแก้ปัญหานี้ฉันต้องการ @Tensibai และคำถาม & อื่น ๆ ตามที่ระบุให้ทำการดึงนักเทียบท่าก่อนบนระบบที่มีการเชื่อมต่ออินเทอร์เน็ตบันทึกภาพนักเทียบท่าคัดลอกไปที่เครื่องโดยไม่ต้องเชื่อมต่ออินเทอร์เน็ตโหลดภาพและเรียกใช้ .

สาธิต

ไม่มีภาพในระบบ A:

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

ดึงภาพจาก 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

บันทึกภาพนักเทียบท่า:

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

คัดลอกอิมเมจ docker ไปยัง systemB และโหลด

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
เครื่องที่เชื่อมต่ออินเทอร์เน็ตไม่ได้และไม่สามารถติดตั้ง Docker ได้ คำถามกำลังถามวิธีการดาวน์โหลดภาพโดยไม่ใช้ไคลเอ็นต์ Docker ดูวิธีการแก้ปัญหาของฉัน
igal

0

นี่คือสคริปต์ python ที่ปรับใช้แล้วซึ่งมีโซลูชันระบบปฏิบัติการอิสระ: docker-drag

ใช้มันอย่างนั้นและมันจะสร้างไฟล์เก็บถาวร TAR ที่คุณจะสามารถนำเข้าโดยใช้โหลดนักเทียบท่า:

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

1
หากคุณปิดบัญชี GitHub แล้วก็ไม่มีอะไรเหลือถ้าคุณโอเคกับการแชร์ให้เก็บลิงค์ไว้ แต่วางสคริปต์ที่นี่ด้วย คุณสามารถแก้ไขคำตอบวางรหัสของคุณจากนั้นเลือกและพิมพ์ ctrl + K หรือปุ่ม{}(รหัส) ในแถบด้านบนของตัวแก้ไขเพื่อจัดรูปแบบ
Tensibai

ฉันชอบวางโค้ดที่นี่ แต่มีความยาว 100 บรรทัดและฉันไม่คิดว่าจะอ่านได้ อย่างไรก็ตามคุณสามารถแยกรหัสเพื่อบันทึกสำเนาสคริปต์ของคุณเอง
Dutfaz

นั่นไม่ใช่สำหรับฉันที่จะมีคำตอบที่สนับสนุนตัวเองหากลิงค์ผิดคุณคิดว่านี่อาจช่วยให้คนที่อ่านคำตอบนี้ในไม่กี่เดือน? (ขนาดสูงสุดสำหรับคำตอบคือ 30k อักขระ)
Tensibai
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.