BLOB_UNKNOWN на действительном изображении контейнера mcr.microsoft.com/windows/servercore:ltsc2019-amd64

В течение последних нескольких дней я играл с API-интерфейсом реестра докеров и писал небольшой инструмент, который контролирует его взаимодействие с реестром контейнеров Microsoft (mcr.microsoft.com). Моя конечная цель - иметь возможность загружать образ из MCR без прямой зависимости от Docker Pull или какого-либо инструмента Docker.

Читая документацию по API реестра Docker, в частности, раздел о том, как создать слой, вы узнаете, что 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 есть некоторые упоминания о хранилище для больших двоичных объектов, которое, как я считаю, является тем, из которого строятся пути загрузки слоев. Тем не менее, я не совсем понимаю, как он вычисляет реальный путь, так как он просто пробует несколько из них, пока один не станет действительным.

Что здесь может быть не так? Я делаю что-то неправильно? Я что-то пропустил?

1 ответ

Решение

Если вы проверите спецификацию манифеста докера, он говорит о внешнем слое: https://docs.docker.com/registry/spec/manifest-v2-2/

Слои типа application/vnd.docker.image.rootfs.foreign.diff.tar.gzip могут быть извлечены из удаленного местоположения, но их никогда не следует выдвигать.

В основном это относится к базовым слоям Windows, которые обычно размещаются отдельно от реестра. Это в настоящее время то же самое для MCR. Если вы посмотрите на манифест изображения, вы увидите слои с URL-адресами. Когда сервер возвращает 404, вы должны следовать URL-адресам в манифесте, чтобы загрузить блоб слоя

   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.foreign.diff.tar.gzip",
         "size": 1534685324,
         "digest": "sha256:65014b3c312172f10bd6701a063f9b5aaf9a916c2d2cb843d406a6f77ded3f8d",
         "urls": [
            "https://go.microsoft.com/fwlink/?linkid=2041275"
         ]
      }
Другие вопросы по тегам