В течение последних нескольких дней я поигрался с API-интерфейсом реестра докеров и написал небольшой инструмент, который контролирует его взаимодействие с реестром контейнеров Microsoft (mcr.microsoft.com). Моя конечная цель - иметь возможность загружать образ из MCR, не имея прямой зависимости ни от докера, ни от какого-либо инструмента докера.
Прочитав документацию по Docker Registry API , в частности, раздел о том, как перетаскивать слой, говорится, что URL построен как /v2/<name>/blobs/<digest>
. Затем в нем упоминается, как клиенты должны быть готовы получить ответ с таким перенаправлением.
Я пытался получить изображение mcr.microsoft.com/windows/servercore:ltsc2019-amd64
, но, похоже, я не смог добиться этого успешно.
Из докера это работает нормально:
PS C:\> docker pull mcr.microsoft.com/windows/servercore:ltsc2019-amd64 ltsc2019-amd64: Pulling from windows/servercore
65014b3c3121: Pull complete b16cfeeaf4b3: Pull complete Digest: sha256:481b0eb967cee61ce09dd81ece5effc5c327c170d11cc73c307c88a80017c9eb
Status: Downloaded newer image for mcr.microsoft.com/windows/servercore:ltsc2019-amd64
mcr.microsoft.com/windows/servercore:ltsc2019-amd64
Однако я не могу получить доступ к отдельным BLOB-объектам для этого изображения, используя API-интерфейс реестра Docker:
PS C:\> (Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/windows/servercore/manifests/ltsc2019-amd64").fsLayers
blobSum
-------
sha256:b16cfeeaf4b37af9fc146f7043ceb629c1bc50ace967227817e50e47f4a71529
sha256:65014b3c312172f10bd6701a063f9b5aaf9a916c2d2cb843d406a6f77ded3f8d
PS C:\> Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/windows/servercore/blobs/sha256:b16cfeeaf4b37af9fc146f7043ceb629c1bc50ace967227817e50e47f4a71529" Invoke-RestMethod : {"errors":[{"code":"BLOB_UNKNOWN","message":"blob unknown to
registry","detail":"sha256:b16cfeeaf4b37af9fc146f7043ceb629c1bc50ace967227817e50e47f4a71529"}]}
At line:1 char:1
+ Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/wind ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
PS C:\> Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/windows/servercore/blobs/sha256:65014b3c312172f10bd6701a063f9b5aaf9a916c2d2cb843d406a6f77ded3f8d" Invoke-RestMethod : {"errors":[{"code":"BLOB_UNKNOWN","message":"blob unknown to
registry","detail":"sha256:65014b3c312172f10bd6701a063f9b5aaf9a916c2d2cb843d406a6f77ded3f8d"}]}
At line:1 char:1
+ Invoke-RestMethod -Method Get -Uri "https://mcr.microsoft.com/v2/wind ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Возвращенная ошибка, по-видимому, "не найдена", а не "перенаправлена". Как Docker pull определяет правильную ссылку, откуда загружать слои?
Я попытался прочитать кодовую базу дистрибутива Docker, но, похоже, не могу собрать головоломку. Начиная с https://github.com/docker/distribution/blob/master/registry/storage/paths.go, есть некоторые упоминания о хранилище для больших двоичных объектов, которое, как я полагаю, является тем, из которого построены пути загрузки слоев. Тем не менее, я не совсем понимаю, как он определяет реальный путь, поскольку он просто пробует несколько из них, пока один не будет действительным.
Что здесь может быть не так? Я делаю что-то неправильно? Я что-то упустил?