我一直在密切关注此处操作脚本中的步骤(https://github.com/sudo-bot/action-docker-sign/blob/main/action.yml)来信任并签署多平台图像。唯一需要的修改是提取 SHA256,其中我提取了 manifest-push-command 返回的最后一个 SHA256(操作脚本中的
cut
命令似乎没有返回有效的 SHA256);也许清单推送结果已经改变。我还尝试了推送返回的不同 SHA256 值,结果相同。
这是脚本,使用 Docker 23.0.0 和在 Ubuntu 上通过
sudo apt-get notary
安装的 notary 包。
脚本完成且没有错误,但最终没有图像标签签名。我缺少什么?您如何信任并签署多平台图像标签?
请注意,buildx 并不能帮助签署多平台镜像;据我所知,它只是推送未签名的图像。
export DOCKER_CONTENT_TRUST=1
# build for platforms, authentication build args omitted; needs docker 23.0.0
docker build --platform=linux/amd64 --tag mydockerid/test-amd64:$(tag)$(tagSuffix) --file $(Folder)/Dockerfile .
docker build --platform=linux/arm64 --tag mydockerid/test-arm64:$(tag)$(tagSuffix) --file $(Folder)/Dockerfile .
export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE='$(SignerKeyPassword)'
docker trust key load $(signerKey.secureFilePath)
export NOTARY_TARGETS_PASSPHRASE='$(TargetKeyPassword)'
export NOTARY_SNAPSHOT_PASSPHRASE='$(SnapshotKeyPassword)'
# Sign and push platform specific images - is it necessary to sign these?
docker trust sign mydockerid/test-amd64:$(tag)$(tagSuffix)
docker trust sign mydockerid/test-arm64:$(tag)$(tagSuffix)
# Create manifest list from platform manifests
docker manifest create mydockerid/test:$(tag)$(tagSuffix) mydockerid/test-amd64:$(tag)$(tagSuffix) mydockerid/test-arm64:$(tag)$(tagSuffix)
# orignal action command does not extract valid SHA
# SHA_256=$(docker manifest push mydockerid/test:$(tag)$(tagSuffix) --purge | cut -d ':' -f 2)
# Push manifest
MANIFEST=$(docker manifest push mydockerid/test:$(tag)$(tagSuffix) --purge)
# Extract last sha256 return by push command which is the only sha256 not corresponding to layers
echo "MANIFEST: ${MANIFEST}"
SHA_256=$(echo ${MANIFEST//*:})
echo "SHA_256: $SHA_256"
MANIFEST_FROM_REG="$(docker manifest inspect "mydockerid/test:$(tag)$(tagSuffix)" -v)";
echo "MANIFEST_FROM_REG: $MANIFEST_FROM_REG"
# Determine byte size as per action script
BYTES_SIZE="$(printf "${MANIFEST_FROM_REG}" | jq -r '.[].Descriptor.size' | uniq)";
echo "BYTES_SIZE: $BYTES_SIZE"
REF="mydockerid/test"
TAG="$(tag)$(tagSuffix)"
AUTH_BASIC=$(SignerAuthBasic)
ROLE_CLI=""
# Check that keys are present
notary key list -d $(DOCKER_CONFIG)/trust/
# Encode user:pat as base 64
export NOTARY_AUTH="$(printf "${AUTH_BASIC}" | base64 -w0)";
TRUST_FOLDER="$(DOCKER_CONFIG)/trust/"
echo "TRUST_FOLDER: $TRUST_FOLDER"
# publish and sign
notary -d ${TRUST_FOLDER} -s "https://notary.docker.io" addhash "${REF}" "${TAG}" "${BYTES_SIZE}" --sha256 "${SHA_256}" ${ROLE_CLI} --publish --verbose
notary -s "https://notary.docker.io" list "${REF}";
unset NOTARY_AUTH;
脚本完成且没有错误。
notary ... --publish ...
命令返回:
Addition of target "1.1.1234-beta" by sha256 hash to repository "***/test" staged for next publish.
Auto-publishing changes to ***/test
Successfully published changes for repository ***/test
最后一个
notary ... list
命令按预期列出了图像标签:
NAME DIGEST SIZE (BYTES) ROLE
---- ------ ------------ ----
1.0.1234-beta 91e75e43bd.... 637 targets
但是检查信任时却没有签名:
docker trust inspect --pretty mydockerid/test
No signatures for mydockerid/test
...
修复相对简单。在我的例子中,
notary
命令中的图像参考需要在前面docker.io
,如下所示:
notary -d ${TRUST_FOLDER} -s "https://notary.docker.io" addhash "docker.io/${REF}" "${TAG}" "${BYTES_SIZE}" --sha256 "${SHA_256}" ${ROLE_CLI} --publish --verbose
这将要求
notary
提供需要提供的存储库密钥,即:
export NOTARY_TARGETS_PASSPHRASE='$(RepoKeyPassword)'
不需要其他公证钥匙。
这两项更改后,签名按预期出现在
docker inspect trust
中。