Завантаження зображень Docker з Docker Hub без використання Docker


32

Я хочу вручну завантажити зображення Docker з Docker Hub . Більш конкретно, я хочу завантажити Docker Image з Docker Hub на машину в обмеженому середовищі, на якій не (і не може) встановлено клієнтське програмне забезпечення Docker. Я б подумав, що це можливо за допомогою офіційного API , але це, мабуть, не так - див. Наступне обговорення:

Чи справді так, що API не підтримує завантаження зображень? Чи є спосіб обійти це?


ОНОВЛЕННЯ 1:

Я натрапив на наступний пост ServerFault:

Прийняте рішення використовує docker saveкоманду, яка не допомагає в моїй ситуації. Але інше рішення, розміщене там, цитує наступний пост StackOverflow:

Одне з рішень там стосується інструмента командного рядка, який називається docker-register-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. Ось як я зараз про це берусь.

Отримайте маркер авторизації:

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

Завантажте всі крапки шару з маніфесту:

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

Зараз у мене є купа шарових крапок і мені потрібно їх рекомбінувати в зображення - я думаю.


Пов'язані посилання:


"Більш конкретно, я хочу завантажити Docker Image з Docker Hub на машину в обмеженому середовищі, де не встановлено (і не може) встановити клієнтське програмне забезпечення Docker." => Який сенс мати зображення на цій машині? (Простіше обійти використовує шарнірний вузол, один , де ви ACN докер тягнути з dockerhub і докер збереження / докер нажімной на внутрішній реєстр після)
Tensibai

@Tensibai Щоб скопіювати його на іншу машину, яка має Docker, але не має доступу до Інтернету.
igal

Ви подивилися на код потягу докера? Звучить спосіб побудувати щось подібне з базових http-дзвінків
Tensibai

@Tensibai Я думаю, я це зрозумів. Я також думаю, що я отримав рішення від спільноти Докер. Я повернусь та опублікую рішення пізніше сьогодні.
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:/#

На практиці я б спочатку скопіювати дані від клієнта інтернет (що НЕ має Docker встановлений) до машини цільової / призначення (який дійсно має 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:~

а потім завантажте та використовуйте зображення на цільовому хості:

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. Завантажте зображення та збережіть шари як тарбол: skopeo copy docker://ubuntu docker-archive:/tmp/ubuntu.tar:ubuntu

  2. За /tmp/ubuntu.tarбажанням перенесіть на іншу машину.

  3. Завантажте зображення в екземпляр Docker, який не має підключення до Інтернету: 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

Скопіюйте зображення докера в 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 або кнопку {}(code) у верхній панелі редактора, щоб відформатувати її.
Тенсібай

Я хотів би вставити код тут, але він становить 100 рядків, і я не думаю, що він буде читабельним. Тим не менш, ви можете роздрібнити код, щоб зберегти власну копію сценарію.
Датфаз

Це не для мене, щоб мати відповідь, яка є самостійкою, якщо посилання перерветься, чи справді ви думаєте, що це може допомогти комусь, хто прочитає цю відповідь через кілька місяців? (btw максимальний розмір для відповіді - 30k символів)
Tensibai
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.