将人工 blob 转换为 docker 注册表结构

Convert artifactory blobs to docker registry structure

谁能指出 docker 注册表所依赖的目录结构的描述?

背景

我无法从我们公司的人工服务器中提取 docker 图片。我对 docker pull art.server.corp/repo/image:label 的所有调用都以错误 Unexpected EOF 结束。我的同事报告了同样的问题。

我已经向我们的 Artifactory 支持寻求帮助,但等待他们的回应需要时间,我不相信他们的结果。

与此同时,我能够通过 Artifactory 的 www 界面从浏览器下载该图像的内容。

我已经下载了文件 manifest.json 和一堆名称为 sha256__<long string with hash> 的文件。 其中大部分是 .tar.gz 档案,一个是 JSON 格式。

如何将这些文件导入本地 docker 安装?我的目标是拥有与注册表中相同的容器映像。

我是 Docker 的新手。

我试过 docker loaddocker import。结果不如预期。

docker load 抱怨缺少 json 个文件但什么都不做。

$ for f in sha256* ; do docker load < $f  ; done
open /var/lib/docker/tmp/docker-import-234007886/var/json: no such file or directory
...
open /var/lib/docker/tmp/docker-import-777861766/var/json: no such file or directory
$ docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

docker import 为每个文件创建一个单独的映像,而它们似乎是单个文件系统的不同层。

$ for f in sha256* ; do docker import $f image:label; done
sha256:a19634d70ff568616b9c42a0151ae8abbd6b915cb24e9d127e366e14453a0dd4
sha256:28c559e39d3be8267757ba8ca540c6b8440f66b71d4ed640fff1b42a04aa54c5
...
sha256:...

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
image        label     7a4c9fe6210c   About a minute ago   111MB
<none>       <none>    654768c91f55   About a minute ago   404kB
<none>       <none>    85d37d403e34   About a minute ago   1.37GB
<none>       <none>    28c559e39d3b   About a minute ago   63.2MB

更新

我尝试安装 Artifactory-OSS,希望在其中导入这些 blob,但 OSS 似乎不支持 Docker。

然后我决定启动本地 docker 注册表并将它们导入其中。

我开发了以下脚本,将文件复制到 blobs 并创建名为 link.

的文件
#!/bin/zsh

source_dir=/path/to/downloaded/blobs
registrty_root=/mnt/volume/docker/registry/v2
image_name=image
image_tag=label


blobs=$registrty_root/blobs/sha256
repo_path=$registrty_root/repositories/$image_name
layers=$repo_path/_layers/sha256
manifests=$repo_path/_manifests/revisions/sha256

#debug=echo
debug=

for f in $source_dir/sha256* ; do
    echo $f
    bn=$(basename $f)
    sha256=$(echo $bn | cut -c9-)
    first2=$(echo $sha256 | cut -c-2)
    blob_dir=$blobs/$first2/$sha256
    layer_dir=$layers/sha256/$sha256
    $debug mkdir -p $blob_dir
    $debug cp -v $f $blob_dir/data

    if [[ $(file $f)=~"gzip" ]] then ; 
        $debug mkdir -p $layer_dir
        $debug echo "sha256:$sha256" > $layer_dir/link
    else
        $debug mkdir -p $manifests
        $debug echo "sha256:$sha256" > $manifests/link
    fi
done

man_sha256=$(sha256sum $source_dir/manifest.json)
first2=$(echo $man_sha256 | cut -c-2)
$debug mkdir -p $blobs/$first2/$man_sha256
$debug cp -v $source_dir/manifest.json $blobs/$first2/$man_sha256/data

$debug mkdir -p $manifests/$man_sha256
$debug echo "sha256:$man_sha256" >  $manifests/$man_sha256/link

$debug mkdir -p $repo_path/_manifests/tags/$image_tag/{current,index/sha256/$man_sha256}
$debug echo "sha256:$man_sha256" > $repo_path/_manifests/tags/$image_tag/index/sha256/$man_sha256/link
$debug echo "sha256:$man_sha256" > $repo_path/_manifests/tags/$image_tag/current/link

然后我启动本地 docker 注册表:docker run -p 5000:5000 -v /mnt/volume/docker:/var/lib/registry registry:2

但是,当我尝试检索图像时,我收到错误消息:

$ docker pull localhost:5000/image:label

Error response from daemon: received unexpected HTTP status: 500 Internal Server Error

Docker 控制台显示如下:

time="2021-01-18T14:04:54.269748704Z"  level=error msg="response completed with error" err.code=unknown err.detail="invalid checksum digest format" err.message="unknown error" go.version=go1.11.2 http.request.host="localhost:5000" http.request.id=7d9fdc93-e74f-42d6-a722-81b51c371df5 http.request.method=HEAD http.request.remoteaddr="172.17.0.1:39770" http.request.uri="/v2/image/manifests/label" http.request.useragent="docker/20.10.2 go/go1.13.15 git-commit/8891c58 kernel/5.4.0-62-generic os/linux arch/amd64 UpstreamClient(Docker-Client/20.10.2 \(linux\))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=21.43068ms http.response.status=500 http.response.written=70 vars.name="image" vars.reference="label"

我也咨询过这个 link: https://notsosecure.com/anatomy-of-a-hack-docker-registry/ 并尝试从浏览器请求清单。标签列表获取成功,但清单报错

所以,我好像漏掉了什么。有帮助吗?

在进一步了解 Docker 和 Docker 文件后,我发现可以使用 ADD 指令从这些档案中重建此映像。

来自https://docs.docker.com/engine/reference/builder/#add

If '< src >' is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory.