不幸的是,我尝试使用HTTP API将图像上传到我的私有Docker注册表,但没有成功。
显然,我还不了解上传过程,想问问是否有人可以详细解释此问题或将我推向正确的方向。
到目前为止,我已经尝试使用curl进行以下操作。为了进行实验,我只使用空的高山图像。为此,我使用docker pull alpine
将其下载到我的工作站,然后使用docker save -o alpine.tar alpine
然后,我将此档案解压缩到一个高山目录中。内容如下所示:ls -R alpine
alpine:
39cb81dcd06e3d4e2b813f56b72da567696fa9a59b652bd477615b31af969239
e7d92cdc71feacf90708cb59182d0df1b911f8ae022d29e8e95d75ca6a99776a.json
manifest.json
alpine/39cb81dcd06e3d4e2b813f56b72da567696fa9a59b652bd477615b31af969239:
json
layer.tar
VERSION
根据文档,我应该首先通过将POST发送到/ v2 // blobs / uploads / URL来启动上传,为此,我执行以下命令:
curl -X POST -L -D headers $DOCKER_HOST/v2/alpine/blobs/uploads
答案如下:
cat headers
HTTP/1.1 301 Moved Permanently
Docker distribution api version: registry/2.0
location: /v2/alpine/blobs/uploads/
Date: Tu, 21 Jan 2020 12:42:55 GMT
content length: 0
HTTP/1.1 202 Accepted
content length: 0
Docker distribution api version: registry/2.0
Docker upload guide: ed595b3c-1236-46c8-a759-14187fc60e7d
Location: http://<IPADDRESS>/v2/alpine/blobs/uploads/ed595b3c-1236-46c8-a759-14187fc60e7d?_state=GjzU_y-YDQherf4xXO57KyEonSSSwNEM8FiF8rmNfuN7Ik5hbWUiOiJhbHBpbmUiLCJVVUlEIjoiZWQ1OTViM2MtMTIzNi00NmM4LWE3NTktMTQxODdmYzYwZTdkIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIwLTAxLTIxVDEyOjQyOjU1LjMxNDYzNTg0NVoifQ%3D%3D
Range: 0-0
X Content Type Options: nosniff
Date: Tu, 21 Jan 2020 12:42:55 GMT
现在我想进行整体上传,如docker-registry文档中所述。
为此,我提出以下卷曲请求:
url=http://<IPADDRESS>/v2/alpine/blobs/uploads/ed595b3c-1236-46c8-a759-14187fc60e7d?_state=GjzU_y-YDQherf4xXO57KyEonSSSwNEM8FiF8rmNfuN7Ik5hbWUiOiJhbHBpbmUiLCJVVUlEIjoiZWQ1OTViM2MtMTIzNi00NmM4LWE3NTktMTQxODdmYzYwZTdkIiwiT2Zmc2V0IjowLCJTdGFydGVkQXQiOiIyMDIwLTAxLTIxVDEyOjQyOjU1LjMxNDYzNTg0NVoifQ%3D%3D?digest=sha256:39cb81dcd06e3d4e2b813f56b72da567696fa9a59b652bd477615b31af969239
layerpath=/home/user/alpine/39cb81dcd06e3d4e2b813f56b72da567696fa9a59b652bd477615b31af969239/layer.tar
curl -X PUT -H "Content-Type=application/octet-stream" --data-binary @"$layerpath" $url
为此,我收到的答案对我没有任何意义:
{"errors":[{"code": "BLOB_UPLOAD_INVALID", "message": "blob upload invalid", "detail":212}]}
我不知道我在做什么错。对于任何帮助,我都非常感谢。
好的,我知道了。对于所有其他也在处理此问题的人,这里有一个小脚本,该脚本应阐明对HTTP-Api的处理:
#!/bin/bash
# Global Variables
MANIFEST="./Manifest.json"
DOCKER_HOST=$1
REPOSITORY=$2
LAYERPATH=$3
CONFIGPATH=$4
SIZE=
DIGEST=
LOCATION=
CONFIGSIZE=
CONFIGDIGEST=
LAYERSIZE=
LAYERDIGEST=
# Functions
function initiateUpload(){
LOCATION=$(curl -X POST -siL -v -H "Connection: close" $DOCKER_HOST/v2/$REPOSITORY/blobs/uploads | grep Location | sed '2q;d' | cut -d: -f2- | tr -d ' ' | tr -d '\r')
}
function patchLayer(){
layersize=$(stat -c%s "$1")
LOCATION=$(curl -X PATCH -v -H "Content-Type: application/octet-stream" \
-H "Content-Length: $layersize" -H "Connection: close" --data-binary @"$1" \
$LOCATION 2>&1 | grep 'Location' | cut -d: -f2- | tr -d ' ' | tr -d '\r')
SIZE=$layersize
}
function putLayer(){
DIGEST=sha256:$(sha256sum $1 | cut -d ' ' -f1)
url="$LOCATION&digest=$DIGEST"
curl -X PUT -v -H "Content-Length: 0" -H "Connection: close" $url
}
function uploadManifest(){
((size=$(stat -c%s "$MANIFEST")-1))
curl -X PUT -vvv -H "Content-Type: application/vnd.docker.distribution.manifest.v2+json"\
-H "Content-Length: $size" -H "Connection: close" \
-d "$(cat "$MANIFEST")" $DOCKER_HOST/v2/$REPOSITORY/manifests/latest
}
# Check Parameters
if [ $# -lt 4 ]
then
echo "Error: No arguments supplied."
echo "Usage: upload.sh <DOCKER_HOST> <REPOSITORY> <LAYER> <CONFIG>"
exit 1
fi
#upload Layer
initiateUpload
patchLayer $LAYERPATH
LAYERSIZE=$SIZE
putLayer $LAYERPATH
LAYERDIGEST=$DIGEST
#upload Config
initiateUpload
patchLayer $CONFIGPATH
CONFIGSIZE=$SIZE
putLayer $CONFIGPATH
CONFIGDIGEST=$DIGEST
cat > $MANIFEST << EOF
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": $CONFIGSIZE,
"digest": "$CONFIGDIGEST"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size":$LAYERSIZE,
"digest": "$LAYERDIGEST"
}
]
}
EOF
uploadManifest
它不漂亮,但可以做到这一点。
如果您需要更多信息,我们将很乐意扩展此答案