這幾天在更新程式的時候,忽然發現 GitLab CI/CD 的工作沒辦法正確推送 Docker Image 到 GitLab 內建的 Container registry?他最後總是會顯示「error from registry: blob unknown to registry」的錯誤。
這邊試了很多方法,都沒有能解決。最後才發現,看起來是 Docker 更新後造成的問題?
在 GitLab 的論壇有一篇《Started yesterday: docker push "error from registry: blob unknown to registry”》就是在討論這個問題,在 buildkit 的《Attestations as OCI artifacts fail to push to gitlab.com when the subject manifest is new》也有解釋原因。
而後來 GitLab 官方也有說明(連結),確定是 BuildKit v0.32.0+ 造成的。
根據官方的說法,這個問題是因為 BuildKit 在更新到 0.32.0 之後,在執行 docker buildx build 時,attestation manifests 會預設使用 OCI artifact 格式。
這讓推送的物件變成 OCI image index(application/vnd.oci.image.index.v1+json)、包含兩個 manifests:
- 真正的平台映像(例如
linux/amd64) - 一個包含
platform: unknown/unknown和vnd.docker.reference.type: attestation-manifest的 attestation manifest- 透過
vnd.docker.reference.digest指向真正的映像
- 透過
而由於 GitLab 的 Container Registry 不接受 attestation manifest 的 media type,因此在提交 manifest 時會拒絕整個 index push,並回傳 MANIFEST_BLOB_UNKNOWN。
而目前的解決方法、或是說繞過去的方法,是在建置的時候把 BuildKit 的預設 attestation 關掉;如果是自己在下指令建置的話,可以用:
BUILDX_NO_DEFAULT_ATTESTATIONS=1 docker build ...
或:
docker build --provenance=false ...
而如果是 GitLab CI/CD 環境,可以透過在 .gitlab-ci.yml 裡面加入這個變數:
variables:
BUILDX_NO_DEFAULT_ATTESTATIONS: "1"
如果完全不想改腳本的話,比較方便的方法,可能是在網站新增變數讓 Runner 執行工作的時候使用?
以 Heresy 自己管理的 GitLab 來說,是在 Admin 區域裡面,點選 Settings – CI/CD,找到裡面的 Variables,建立一個 key 是 BUILDX_NO_DEFAULT_ATTESTATIONS 的變數、然後把 Value 設定成 1 就可以了。
理論上,這樣整個站的 CI/CD 應該都不用修改腳本、就可以繼續跑了;而如果沒有全站管理者個權限,理論上也可以針對專案/群組做設定。
接下來,就不知道 GitLab 官方什麼時候會修正 Container Registry 的設計了?
