Dockerを使用せずにDocker HubからDockerイメージをダウンロードする


32

Docker HubからDocker Imageを手動でダウンロードしたい。より具体的には、Dockerクライアントソフトウェアがインストールされていない(およびインストールできない)制限された環境のマシンで、Docker HubからDockerイメージをダウンロードしたい。公式のAPIを使用してこれが可能になると考えていましたが、そうではないようです。次の説明を参照してください。

APIが画像のダウンロードをサポートしていないのは本当ですか?これを回避する方法はありますか?


更新1:

次のServerFaultの投稿に出会いました。

受け入れられた解決策は、使用していますdocker save私の状況では解決しないコマンドを、。しかし、そこに投稿された別のソリューションは、次のStackOverflowの投稿を引用しています。

そこでのソリューションの1つは、特にイメージをダウンロードするためのコマンドを生成できる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:

Docker HubからレイヤーBLOBをダウンロードできるようです。ここに私が現在どのように取り組んでいるかを示します。

認証トークンを取得します。

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"

すべてのブロブの合計をファイルに書き込みます。

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

マニフェストからすべてのレイヤーBLOBをダウンロードします。

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

今、たくさんのレイヤーBLOBがあり、それらをイメージに再結合する必要があると思います。


関連リンク:


「具体的には、Dockerクライアントソフトウェアがインストールされていない(およびインストールできない)制限された環境のマシンで、Docker HubからDockerイメージをダウンロードしたい。」=>このマシンに画像を置くポイントは何ですか?(より簡単な回避策は、ピボットホストを使用することです。このホストでは、Dockerをdockerhubからプルし、その後docker save / docker pushを内部レジストリにプッシュします)
Tensibai

@Tensibaiへは、別のマシンにコピードッカーを持っていますが、しませんインターネットアクセスを持っています。
イガル

ドッカーのプルコードを見ましたか?基本的なhttp呼び出しからこのようなものを構築する方法が聞こえます
-Tensibai

@Tensibai私はそれを理解したと思う。また、Dockerコミュニティから解決策を得たと思います。後で戻って、ソリューションを今日投稿します。
イガル

@Tensibai 問題を解決するシェルスクリプトを使用したソリューションを投稿しまし
イガル

回答:


23

そのため、MobyプロジェクトMoby Githubにはシェルスクリプトがあり、Dockerにインポートできる形式でDocker Hubから画像をダウンロードできます。

スクリプトの使用構文は次のとおりです。

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

その後、イメージをtarand でインポートできますdocker load

tar -cC 'target_dir' . | docker load

スクリプトが期待どおりに機能することを確認するために、Docker HubからUbuntuイメージをダウンロードし、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がインストールされているマシンにデータをコピーする必要があります。
イガル

おそらく、あなたは明確化のために、その部分を追加することができます
030

2
@ 030実際にワークフローがどのように見えるかを示すセッションの例を追加しました。
イガル

7

リポジトリからDockerイメージを取得し、いくつかの形式で保存できるSkopeoというツールがあります。

例えば:

  1. 画像をダウンロードして、レイヤーをtarballとして保存します。 skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. /tmp/ubuntu.tar必要に応じて別のマシンに転送します。

  3. インターネットに接続していないDockerインスタンスにイメージをロードします。 docker load --input /tmp/ubuntu.tar

CentOS 7リポジトリでパッケージ名を使用できますskopeo。現時点ではDebianまたはUbuntuパッケージはありません(ただし、コンパイルは簡単です)。


3

やる気をありがとう。PowerShellバージョンを作成しました。確認してください... Windowsデスクトップとssh-scpツールを使用して、rootまたは管理者権限なしでdockerhubコンテナーを制限付きdockerネットワークに移動できます。

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と他のQ&Aに示されているように、最初にインターネット接続のあるシステムでdocker pullを実行し、dockerイメージを保存し、インターネットに接続せずにマシンにコピーし、イメージをロードして実行します。

デモンストレーション

システム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

Dockerイメージの保存:

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クライアント使用せずにイメージをダウンロードする方法を求めています。私の解決策をご覧ください。
イガル

0

これは、OSに依存しないソリューションを備えた適合Pythonスクリプトです。docker-drag

そのように使用すると、docker loadを使用してインポートできる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を入力するか{}、エディターのトップバーにある(コード)ボタンを押してフォーマットします。
テンシバイ

ここにコードを貼り付けたいのですが、100行の長さで、読みやすいとは思いません。それでも、コードを分岐して、スクリプトのコピーを保存できます。
Dutfaz

それは私のためではありません、自己持続的な答えを持っていること、リンクが切れた場合、あなたは本当にこれが誰かがこの答えを数ヶ月で読むのを助けるかもしれないと思いますか?(ところで、回答の最大サイズは3万文字です)
テンシバイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.