本頁說明映像檔摘要,包括映像檔摘要的用途、如何尋找映像檔摘要,以及如何在 Kubernetes 叢集中強制使用映像檔摘要。本頁面適用於建構及部署容器映像的開發人員和作業人員。
容器映像檔摘要可做為容器映像檔的不重複且不可變更的 ID。使用摘要部署映像檔可避免使用映像檔標記部署映像檔的缺點。
本頁面的指令假設您可存取 Linux 或 macOS 的 Shell 環境,且已安裝 Google Cloud CLI、Docker、cURL、jq 和 pack 等工具。或者,您可以使用已預先安裝這些工具的 Cloud Shell。
容器映像檔和映像檔標記
使用容器映像檔時,您需要參照所用映像檔的方法。圖片標記
是參照圖片不同修訂版本的常見方式。常見的做法是在建構時為映像檔加上版本 ID 標記。舉例來說,v1.0.1 可以參照您呼叫的 1.0.1 版本。
標記可讓使用者透過易讀的字串輕鬆查閱圖片修訂版本。不過,標記是可變更的參照,因此標記參照的映像檔可能會變更,如下圖所示:
如上圖所示,如果您使用與現有映像檔相同的標記發布新映像檔,該標記會停止指向現有映像檔,並開始指向新映像檔。
圖片代碼的缺點
由於標記可變動,因此使用標記部署映像檔時,會有下列缺點:
- 在 Kubernetes 中,透過標記部署可能會導致非預期的結果。舉例來說,假設您現有的 Deployment 資源是透過標記 - v1.0.1參照容器映像檔。如要修正錯誤或進行小幅變更,建構程序會建立具有相同標記- v1.0.1的新映像檔。即使您未變更 Deployment 資源規格,從 Deployment 資源建立的新 Pod 仍可能使用舊版或新版映像檔。這個問題也適用於其他 Kubernetes 資源,例如 StatefulSet、DaemonSet、ReplicaSet 和工作。
- 如果您使用工具掃描或分析圖片,這些工具的結果只適用於掃描的圖片。為確保部署的是掃描的映像檔,您不能依賴標記,因為標記參照的映像檔可能已變更。 
- 如果您搭配使用二進位授權和 Google Kubernetes Engine (GKE),系統會禁止根據標記部署,因為建立 Pod 時無法判斷使用的確切映像檔。 
部署映像檔時,您可以使用映像檔摘要,避免使用標記的缺點。你還是可以視需要為圖片加上標記, 但不必這麼做。
圖片結構
映像檔包含下列元件:
下圖說明這些元件:
上圖顯示圖片元件的額外詳細資料:
- 圖片資訊清單是 JSON 文件,內含設定物件、檔案系統層和選用中繼資料的參照。
- 映像檔資訊清單會使用 digest屬性,參照設定物件和每個檔案系統層。digest屬性的值是摘要所指內容的密碼編譯雜湊,通常是使用 SHA-256 演算法計算。
- 摘要值用於建構物件的不變位址。這個程序稱為「可定址內容的儲存空間」,代表您可以根據摘要擷取映像檔資訊清單、映像檔索引、設定物件和層。
- 映像檔摘要是映像檔索引或映像檔資訊清單 JSON 文件的雜湊值。
- 設定物件是 JSON 文件,用於定義映像檔的屬性,例如 CPU 架構、進入點、公開的連接埠和環境變數。
- 檔案系統層陣列會定義容器執行階段用來堆疊層的順序。這些層會以 tar 檔案的形式發布,通常會使用 gzip公用程式壓縮。
- 選用的映像檔索引 (有時稱為資訊清單表) 會參照一或多個映像檔資訊清單。參考資料是映像檔資訊清單的摘要。如果您為不同平台 (例如 amd64和arm64架構) 製作多個相關圖片,映像檔索引就非常實用。
詳情請參閱「探索映像檔資訊清單、摘要和標記」一節。
尋找映像檔摘要
如要使用映像檔摘要進行部署,請先找出摘要。接著,您可以在部署指令中使用摘要,或將摘要納入 Kubernetes 資訊清單。
視目前情況而定,您可以透過各種方式取得圖片摘要。以下章節提供不同產品和工具的範例。
在接下來的章節中,請在 Cloud Shell 或已安裝 gcloud CLI、Docker、cURL 和 jq 等工具的 Shell 環境中執行指令。
Artifact Registry
- 如要掃描儲存在 Artifact Registry 中的映像檔,請使用 - gcloud artifacts docker images describe指令。- gcloud artifacts docker images describe \ LOCATION-docker.pkg.dev/PROJECT/REPOSITORY/IMAGE:TAG \ --format 'value(image_summary.digest)'- 更改下列內容: - LOCATION:存放區的區域或多區域位置
- PROJECT:您的 Google Cloud 專案 ID
- REPOSITORY:存放區名稱
- IMAGE:圖片名稱
- TAG:圖片代碼
 
Container Registry
- 如要取得儲存在 Container Registry 中的映像檔摘要,請提供名稱和標記,然後使用 - gcloud container images describe指令。使用- --format旗標,只顯示摘要:- gcloud container images describe \ gcr.io/google-containers/pause-amd64:3.2 \ --format 'value(image_summary.digest)'- 輸出內容大致如下,但摘要值可能有所不同: - sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
Cloud Build
如要取得使用 Cloud Build 建構的映像檔摘要,請使用 gcloud builds describe 指令搭配 --format 標記。無論您使用哪個登錄檔發布映像檔,這種做法都適用。
- 如要為已完成的建構作業執行這項操作,請按照下列步驟操作: - 取得專案的建構版本清單: - gcloud builds list- 請記下 - BUILD_ID。
- 取得映像檔摘要: - gcloud builds describe BUILD_ID \ --format 'value(results.images[0].digest)'- 將 - BUILD_ID替換為 Cloud Build 指派給建構作業的專屬 ID。
 
- 從目前專案的 Cloud Build 取得最新版本的映像檔名稱和摘要: - gcloud builds describe \ $(gcloud builds list --limit 1 --format 'value(id)') \ --format 'value[separator="@"](results.images[0].name,results.images[0].digest)'
- 如果建構作業產生多個映像檔,請篩選輸出內容,並取得其中一個映像檔的摘要: - gcloud builds describe BUILD_ID --format json \ | jq -r '.results.images[] | select(.name=="YOUR_IMAGE_NAME") | .digest'- 將 - YOUR_IMAGE_NAME換成- cloudbuild.yaml檔案中的其中一個圖片名稱。
- 如果您使用 - gcloud builds submit指令將建構作業提交至 Cloud Build,可以從輸出內容擷取映像檔摘要,並存入環境變數:- IMAGE_DIGEST=$(gcloud builds submit \ --format 'value(results.images[0].digest)' | tail -n1)
Cloud Native Buildpacks
- 如果您使用 Cloud Native Buildpacks 和 Google Cloud 建構子建構及發布映像檔,可以使用 - --quiet旗標搭配- pack指令擷取映像檔名稱和摘要:- pack build --builder gcr.io/buildpacks/builder:v1 --publish --quiet \ LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE \ > image-with-digest.txt- 更改下列內容: - LOCATION:存放區的區域或多區域位置
- PROJECT_ID:您的 Google Cloud 專案 ID
- REPOSITORY:存放區名稱
- IMAGE:圖片名稱
 - 檔案 - image-with-digest.txt包含圖片名稱和摘要。- 如要為圖片新增標記,請使用 - --tag旗標。
Docker 用戶端
- docker指令列用戶端的- manifest子指令可從容器映像檔登錄檔擷取映像檔資訊清單和資訊清單清單。- 從映像檔 - registry.k8s.io/pause:3.9的資訊清單清單中取得摘要,適用於- amd64CPU 架構和- linux作業系統:- docker manifest inspect --verbose registry.k8s.io/pause:3.9 | \ jq -r 'if type=="object" then .Descriptor.digest else .[] | select(.Descriptor.platform.architecture=="amd64" and .Descriptor.platform.os=="linux") | .Descriptor.digest end'- 輸出看起來類似以下內容: - sha256:8d4106c88ec0bd28001e34c975d65175d994072d65341f62a8ab0754b0fafe10
- 如要取得儲存在本機 Docker Daemon 中,且已從映像檔登錄檔提取或推送至該登錄檔的映像檔摘要,可以使用 Docker 指令列工具: - 將映像檔拉取至本機 Docker Daemon: - docker pull docker.io/library/debian:bookworm
- 取得映像檔摘要: - docker inspect docker.io/library/debian:bookworm \ | jq -r '.[0].RepoDigests[0]' \ | cut -d'@' -f2- 輸出內容會與以下所示內容類似,但摘要值可能不同: - sha256:3d868b5eb908155f3784317b3dda2941df87bbbbaa4608f84881de66d9bb297b
 
- 列出本機 Docker Daemon 中的所有映像檔和摘要: - docker images --digests- 輸出會顯示具有摘要值的圖片摘要。只有從映像檔登錄檔提取或推送至映像檔登錄檔的映像檔,才會有摘要值。 
crane 和 gcrane
您可以使用開放原始碼的 crane 和 gcrane 指令列工具,取得映像檔的摘要,而不必將映像檔提取至本機 Docker 精靈。
- 將 - crane和- gcrane下載到目前目錄:- VERSION=$(curl -sL https://api.github.com/repos/google/go-containerregistry/releases/latest | jq -r .tag_name) curl -L "https://github.com/google/go-containerregistry/releases/download/${VERSION}/go-containerregistry_$(uname -s)_$(uname -m).tar.gz" | tar -zxf - crane gcrane
- 取得圖片摘要: - ./gcrane digest gcr.io/distroless/static-debian11:nonroot- crane和- gcrane還有其他功能,不在本頁面的討論範圍內。詳情請參閱- crane和- gcrane的說明文件。
在 Kubernetes 部署作業中強制使用映像檔摘要
如要強制對部署至 Kubernetes 叢集的映像檔使用摘要,可以使用 Policy Controller 或 Open Policy Agent (OPA) Gatekeeper。Policy Controller 是以 OPA Gatekeeper 開放原始碼專案為基礎建構而成。
Policy Controller 和 OPA Gatekeeper 都是以 OPA 政策引擎為基礎。Policy Controller 和 OPA Gatekeeper 提供 Kubernetes 驗證許可控制器 Webhook,可強制執行政策,並提供自訂資源定義 (CRD),用於限制範本和限制。
限制範本包含以高階宣告式語言 (稱為 Rego) 表示的政策邏輯。以下是驗證容器、init 容器和臨時容器的限制範本,確保 Kubernetes 資源規格中的容器使用含有摘要的映像檔:
上述政策包含規則運算式,做為 re_match 函式的輸入內容。這個規則運算式會比對容器映像檔摘要,並以開放容器倡議映像檔規格中的摘要格式為依據。
限制會比對 kind 和 namespace 等屬性,將政策套用至 Kubernetes 資源。以下範例限制會將限制範本中的政策套用至 default 命名空間中的所有 Pod 資源。
建立限制範本和限制後,default 名稱空間中的任何新 Pod 都必須使用映像檔摘要,才能參照容器映像檔。
如需完整範例,請參閱 Gatekeeper 政策程式庫中的imagedigests 政策。
關於映像檔資訊清單、摘要和標記
在本節中,您將瞭解如何使用 curl 和 docker 等指令列工具,探索登錄檔中的現有映像檔。在 Cloud Shell 中執行指令,或在已安裝 gcloud CLI、Docker、cURL 和 jq 等工具的殼層環境中執行指令。下列指令會使用 Artifact Registry 中的公開映像檔。
- 使用 cURL 和資訊清單網址取得圖片的資訊清單 - gcr.io/google-containers/pause-amd64:3.2:- curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2- 輸出結果會與下列內容相似: - { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "config": { "mediaType": "application/vnd.docker.container.image.v1+json", "size": 759, "digest": "sha256:80d28bedfe5dec59da9ebf8e6260224ac9008ab5c11dbbe16ee3ba3e4439ac2c" }, "layers": [ { "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", "size": 296534, "digest": "sha256:c74f8866df097496217c9f15efe8f8d3db05d19d678a02d01cc7eaed520bb136" } ] }- config區段具有摘要屬性,您可以使用這個值擷取設定物件。同樣地,每個層都有- digest屬性,可用於擷取該層的 tar 檔案。
- 如果圖片包含選用的圖片索引,使用標記對資訊清單網址發出的 HTTP - GET要求,會傳回圖片索引,而非圖片資訊清單。- 取得圖片 - gcr.io/google-containers/pause:3.2的圖片索引:- curl -s https://gcr.io/v2/google-containers/pause/manifests/3.2- 輸出結果會與下列內容相似: - { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 526, "digest": "sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108", "platform": { "architecture": "amd64", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 526, "digest": "sha256:bbb7780ca6592cfc98e601f2a5e94bbf748a232f9116518643905aa30fc01642", "platform": { "architecture": "arm", "os": "linux", "variant": "v7" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 526, "digest": "sha256:31d3efd12022ffeffb3146bc10ae8beb890c80ed2f07363515580add7ed47636", "platform": { "architecture": "arm64", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 526, "digest": "sha256:7f82fecd72730a6aeb70713476fb6f7545ed1bbf32cadd7414a77d25e235aaca", "platform": { "architecture": "ppc64le", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 526, "digest": "sha256:1175fd4d728641115e2802be80abab108b8d9306442ce35425a4e8707ca60521", "platform": { "architecture": "s390x", "os": "linux" } } ] }
- 篩選結果,擷取所需平台的圖片摘要。取得 - amd64CPU 架構和- linux作業系統的映像檔資訊清單摘要:- curl -s https://gcr.io/v2/google-containers/pause/manifests/3.2 | \ jq -r '.manifests[] | select(.platform.architecture=="amd64" and .platform.os=="linux") | .digest'- 這項指令中的篩選作業會模擬容器執行階段 (例如 containerd) 從映像檔索引選取符合目標平台的映像檔。 - 輸出結果會與下列內容相似: - sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
- 取得圖片的摘要 - gcr.io/google-containers/pause-amd64:3.2:- curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \ | shasum -a 256 \ | cut -d' ' -f1- 輸出結果會與下列內容相似: - 4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108- 您可以使用映像檔摘要值參照這個映像檔,如下所示: - gcr.io/google-containers/pause-amd64@sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
- 使用內容可定址儲存空間概念,以摘要做為參照,取得映像檔資訊清單: - curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108
- 許多容器映像檔登錄檔會在回應 HTTP - HEAD要求時,於- Docker-Content-Digest標頭中傳回資訊清單、映像檔索引、設定物件和檔案系統層的摘要。取得圖片索引的摘要,圖片索引是指圖片的摘要:- gcr.io/google-containers/pause-amd64:3.2- curl -s --head https://gcr.io/v2/google-containers/pause/manifests/3.2 \ | grep -i Docker-Content-Digest \ | cut -d' ' -f2- 輸出結果會與下列內容相似: - sha256:927d98197ec1141a368550822d18fa1c60bdae27b78b0c004f705f548c07814f- Docker-Content-Digest標頭並非 Open Container Initiative Distribution 規格的必要條件,因此這個方法可能不適用於所有容器映像檔登錄檔。您可以搭配 Artifact Registry 和 Container Registry 使用。
- 如要使用映像檔資訊清單中的摘要值擷取映像檔設定物件,請執行下列操作: - 取得設定摘要: - CONFIG_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \ | jq -r '.config.digest')
- 使用設定摘要擷取設定物件,並使用 - jq格式化輸出內容,方便閱讀:- curl -sL https://gcr.io/v2/google-containers/pause-amd64/blobs/$CONFIG_DIGEST \ | jq- 輸出結果會與下列內容相似: - { "architecture": "amd64", "config": { "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Entrypoint": [ "/pause" ], "WorkingDir": "/", "OnBuild": null }, "created": "2020-02-14T10:51:50.60182885-08:00", "history": [ { "created": "2020-02-14T10:51:50.60182885-08:00", "created_by": "ARG ARCH", "comment": "buildkit.dockerfile.v0", "empty_layer": true }, { "created": "2020-02-14T10:51:50.60182885-08:00", "created_by": "ADD bin/pause-amd64 /pause # buildkit", "comment": "buildkit.dockerfile.v0" }, { "created": "2020-02-14T10:51:50.60182885-08:00", "created_by": "ENTRYPOINT [\"/pause\"]", "comment": "buildkit.dockerfile.v0", "empty_layer": true } ], "os": "linux", "rootfs": { "type": "layers", "diff_ids": [ "sha256:ba0dae6243cc9fa2890df40a625721fdbea5c94ca6da897acdd814d710149770" ] } }
 
- 如要使用映像檔資訊清單中的摘要值擷取檔案系統層,請按照下列步驟操作: - 取得要擷取圖層的摘要: - LAYER_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \ | jq -r '.layers[0].digest')
- 使用層摘要擷取層 tar 檔案,並列出內容: - curl -sL https://gcr.io/v2/google-containers/pause-amd64/blobs/$LAYER_DIGEST \ | tar --list- 這個圖層只有一個名為 - pause的檔案。
 
- 如要查詢與映像檔摘要相關聯的標記,請按照下列步驟操作: - 定義要查詢的摘要: - IMAGE_DIGEST=$(curl -s https://gcr.io/v2/google-containers/pause-amd64/manifests/3.2 \ | shasum -a 256 \ | cut -d' ' -f1)- IMAGE_DIGEST環境變數包含標記- 3.2參照的映像檔摘要。
- 使用映像檔標記清單端點 - /tags/list列出標記資訊,並擷取摘要值的標記:- curl -s "https://gcr.io/v2/google-containers/pause-amd64/tags/list?n=1" \ | jq ".manifest.\"sha256:$IMAGE_DIGEST\".tag"- 輸出結果會與下列內容相似: - [ "3.2" ]
 
- 如要使用 cURL 從 Artifact Registry 容器映像檔存放區取得映像檔資訊清單,請在 - Authorization要求標頭中加入存取權杖:- curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \ https://LOCATION-docker.pkg.dev/v2/PROJECT_ID/REPOSITORY/IMAGE/manifests/DIGEST- 更改下列內容: - LOCATION:存放區的區域或多區域位置
- PROJECT_ID:您的 Google Cloud 專案 ID
- REPOSITORY:存放區名稱
- IMAGE:圖片名稱
- DIGEST:圖片摘要,格式為- sha256:DIGEST_VALUE