Artifact Registry 簡介
Artifact Registry 是 Google Cloud 的統一型受託管產出物儲存服務,正式取代 Container Registry(GCR),並擴展支援多種格式:容器映像檔(Docker / OCI)、語言套件(Maven、npm、PyPI、Go、NuGet)以及 作業系統套件(APT、YUM)。它與 Cloud Build、Cloud Run、GKE、Cloud Deploy、Binary Authorization 與 Container Analysis 深度整合。
對 Professional Cloud Developer(PCD) 考試而言,Artifact Registry 經常出現在 pipeline 設計題、IAM 權限情境題、供應鏈安全取捨題,以及 CMEK 與 VPC-SC 合規題裡。題目最愛測:該選哪一種存放區模式(mode)、該選哪一種格式(format)、哪個 IAM 角色剛剛好,以及何時必須開啟漏洞掃描與 Binary Authorization。
主機名稱的標準格式是 LOCATION-FORMAT.pkg.dev/PROJECT/REPOSITORY/PATH——例如 asia-east1-docker.pkg.dev/my-project/web-images/api:v1.2.3。光是記住這個 URL 形狀,就可避開不少考試陷阱。
白話文解釋
在進入 IAM 綁定與 CMEK 金鑰之前,先用三個生活化類比把零件之間的關係建立起來。
類比 1:分區式保稅倉庫
如果你的程式碼是設計圖、Cloud Build 是組裝線,那 Artifact Registry 就是港口邊的保稅倉庫。倉庫劃分多個明顯標示的區域:一區放貨櫃(Docker 映像檔)、一區放汽車零件(Maven JAR)、一區放化學品桶(npm 套件)、一區放食品(APT deb)。每個區域有自己的卸貨口(格式專屬的協定)與自己的警衛(存放區層級的 IAM 角色)。海關官員(Container Analysis)會在貨物離開前檢驗,邊境官員(Binary Authorization)只允許帶有正確文件(attestation)的貨物出倉。倉庫管理員(清理政策 / Cleanup Policy)會定期把 90 天沒人碰過的舊木箱清掉。
類比 2:公司內部 App Store 的三種櫃台模式
想像一家公司內部 App Store,有三種櫃台。Standard 模式是自家櫃台,同仁把自己做的應用發佈進來。Remote 模式是「鏡像櫃台」,幫你從外面的公開商店(Docker Hub、Maven Central、PyPI)取回套件,並順手在本地暫存一份,免得 50 個工程師同時下載同一版本把對外網路打爆。Virtual 模式是「服務台」,對外只給一個 URL,內部會自動路由到該去的櫃台——「我要 pandas,不管它是我們內部櫃台還是 PyPI 鏡像櫃台的版本」。開發者只需要記一個位址,剩下的由商店自己決定。
類比 3:銀行金庫與「自己帶鎖」的保管箱
想像一間銀行金庫,每個保管箱都有加密,但客戶可以選擇讓銀行管理母鑰(預設的 Google-managed encryption),也可以自己從家裡帶一支鎖過來(CMEK via Cloud KMS)。如果客戶把自己的鎖拿走,銀行就再也打不開那個保管箱——連法院命令都打不開。這正是 Artifact Registry 上 CMEK 的行為:當你停用 KMS 金鑰,所有 docker pull 在數分鐘內就會從 KMS 層回 PERMISSION_DENIED,連專案 Owner 都拉不到映像檔。
Artifact Registry vs Container Registry — GCR 退場的故事
Container Registry(gcr.io、us.gcr.io、eu.gcr.io、asia.gcr.io)是 Google 第一代容器倉庫,底層其實是名為 artifacts.PROJECT.appspot.com 的 Cloud Storage bucket。Artifact Registry 已正式取代 GCR,並在 2024 年 5 月 15 日 凍結新建 GCR 存放區;既有的 gcr.io 流量會被透通地導向同名 Artifact Registry 存放區。
為什麼必須更新
- 單一格式限制。 GCR 只存 Docker。多語言團隊得同時養 GCR + 第三方 Nexus/Artifactory + 一個 GCS bucket 存
*.tar.gz。Artifact Registry 把三者收斂為一個產品。 - 只有 Project 層級 IAM。 GCR 的權限承襲底層 GCS bucket,無法做到「只能推到存放區 A」。Artifact Registry 有存放區層級的 IAM。
- 沒有區域控制。 GCR 只有四個 multi-region bucket。Artifact Registry 支援所有 GCP region 與 multi-region,每個區域都有可預測的主機名。
- 早期 GCR 沒有 remote / virtual 模式、沒有原生 CMEK、沒有原生清理政策。
gcr.io Redirect — 自 2024 起,Google 會把 gcr.io/PROJECT/IMAGE 自動導向專案內自動建立的 Artifact Registry 存放區 gcr.io。Redirect 保留 digest 與 tag,但計費改走 Artifact Registry SKU,不再是舊的 GCS bucket。啟用指令:gcloud artifacts settings enable-upgrade-redirection --project=PROJECT。
遷移工具
gcloud artifacts docker upgrade migrate 會把 gcr.io 內的映像複製到新的 *-docker.pkg.dev 存放區,保留 digest,並可選擇設定 redirect,讓既有 docker pull gcr.io/... 客戶端無痛續用。語言套件部分目前沒有官方遷移工具,多數團隊在過渡期是「重新發佈」或用 remote repository 把舊倉庫包起來作為前端。
支援格式 — 一個服務,十種產出物
Artifact Registry 支援 十種格式,每種有自己的主機名後綴(-docker.pkg.dev、-maven.pkg.dev、-npm.pkg.dev 等)與原生 client(docker、mvn、npm、pip、helm、apt)。
容器與 OCI 格式
- Docker — 最常用;存放 OCI 相容映像檔。主機名:
LOCATION-docker.pkg.dev。執行gcloud auth configure-docker LOCATION-docker.pkg.dev後docker push即可。 - Helm(OCI) — Helm 3.8+ chart 以 OCI artifact 推送。主機名:
LOCATION-docker.pkg.dev(Helm 共用 Docker 的主機名,沒有獨立的*-helm.pkg.dev)。 - KubeFlow Pipelines — 專用格式,存放編譯後的 ML pipeline template,給 Vertex AI Pipelines 使用。
語言套件格式
- Maven — Java/Kotlin 套件。主機名:
LOCATION-maven.pkg.dev。透過artifactregistry-maven-wagon在settings.xml認證。 - npm — Node.js 套件。主機名:
LOCATION-npm.pkg.dev。用.npmrc配 Google Cloud 簽發的 access token。 - PyPI(Python) — 主機名:
LOCATION-python.pkg.dev。用keyring+keyrings.google-artifactregistry-auth。 - Go modules — 主機名:
LOCATION-go.pkg.dev,作為 Go module proxy 使用,認證用gcloud auth print-access-token。 - NuGet — .NET 套件,
LOCATION-nuget.pkg.dev。
作業系統套件格式
- APT — Debian / Ubuntu 的
.deb,呈現為完整 APT repository(Release、Packages.gz)。 - YUM — RHEL / CentOS / Fedora 的
.rpm。
Generic 格式
- Generic — 任意二進位 blob(
*.tar.gz、*.zip、firmware)。沒有協定語意,用gcloud artifacts generic upload/download。適合存 Terraform 模組、FPGA bitstream、簽章過的 firmware。
PCD 考題若問「能不能在同一個區域存放區裡同時存 Docker 映像與 Maven 套件」,陷阱選項就是「一個 Artifact Registry repo 就好」。單一存放區只能綁定一種格式,建立時就決定且不可變更。正確做法是「在同一個 project / region 下建兩個 repo,共用同一把 KMS 金鑰與 IAM 範本」。
存放區模式 — Standard、Remote、Virtual
每個 Artifact Registry 存放區建立時必須選擇一種模式,透過 --mode=STANDARD-REPOSITORY|REMOTE-REPOSITORY|VIRTUAL-REPOSITORY 設定。模式建立後不可變更。
Standard Repository
預設模式。存放團隊自己發佈的產出物,推進去什麼就拉得到什麼。團隊自家應用的 build artifact 都放在這。建立在 asia-east1 的 Docker standard repo,URL 為 asia-east1-docker.pkg.dev/my-project/app-images/...。
Remote Repository
上游公開倉庫的快取代理。設定一次後,每次 docker pull 會先查本地快取,未命中才去 upstream 抓,並把 layer 留在本地。截至 2024 年支援的上游:Docker Hub、Maven Central、npm Registry、PyPI、Debian、Ubuntu、CentOS,以及通用 HTTP 的「custom remote」。
使用情境:
- 建置可靠性。 Docker Hub 免費匿名拉取限制是每個 IP 每 6 小時 100 次。Remote repository 從你的 GCP region 服務快取後的 layer,不再受 Docker Hub rate limit 限制。
- 省 egress 成本。 第一次 miss 之後,後續拉取都走 GCP backbone 內部。
- VPC-SC 合規。 內部 builder 永遠不直接連
hub.docker.com,只連pkg.dev。
Virtual Repository
邏輯前門,將多個 upstream(standard 或 remote)統一在一個 URL 之下,解析順序可設定。常見模式:建一個 virtual python-all,組合 (1) 內部 standard repo(團隊自家 library)+ (2) PyPI 的 remote repo。開發者只設定一個 URL,virtual repo 會優先回傳內部套件,否則 fallback 到 remote PyPI。行為與 JFrog Artifactory 的「virtual repository」一致。
為了強化供應鏈安全,企業的 python virtual repo 應把「內部 standard repo」排在第一順位,PyPI remote repo 排第二。如果攻擊者在 PyPI 上傳一個與你內部套件同名的 typo-squat,virtual repo 的解析順序會確保開發者拿到的是你的內部版本,而不是攻擊者的版本。這就是 Alex Birsan 揭露的經典「dependency confusion」攻擊的防禦招式。
IAM 角色 — 存放區層級的授權
Artifact Registry IAM 可在 organization、project、或 repository 三個層級授予。存放區層級正是 PCD 考試最愛測的地方。
核心預定義角色
roles/artifactregistry.reader— 讀 metadata、拉產出物。GKE、Cloud Run、Cloud Functions 的執行期 service account 都只需要這個——它們只需要 pull。roles/artifactregistry.writer— reader + 推產出物、建 tag。給 Cloud Build service account 與 CI pipeline。roles/artifactregistry.repoAdmin— writer + 刪產出物、管理 tag、設定清理政策。只授給少數 release manager。roles/artifactregistry.admin— 完整管理:建/刪 repo、設 IAM 政策、設定 CMEK。通常在 project 層級給平台組。roles/artifactregistry.serviceAgent— Service Agentservice-PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com用來呼叫 CMEK 的內部角色。
典型綁定
- Cloud Run runtime SA:
roles/artifactregistry.reader,scope 限定到那一個 repo。 - Cloud Build worker SA:
roles/artifactregistry.writer,scope 限定到輸出 repo。 - GitHub Actions Workload Identity Federation SA:
writer,scope 限定到該團隊的 repo,不是 project-wide。 - 開發者本人:通常只給
reader——推送由 CI 做,不是從筆電做。
gcloud artifacts repositories add-iam-policy-binding web-images \
--location=asia-east1 \
--member="serviceAccount:[email protected]" \
--role="roles/artifactregistry.reader"
Storage IAM 陷阱
PCD 考試常見陷阱:給 Cloud Run service roles/storage.objectViewer 來拉 gcr.io。GCR-to-AR redirect 之後這招會失效,因為底層 GCS bucket 已不在請求路徑上。正解是給轉址後的 repo 加 roles/artifactregistry.reader。
CMEK 加密 — 客戶自管金鑰
預設情況下,Artifact Registry 用 Google-managed key 在靜態時加密(不收費)。對受規範產業——金融、醫療、公部門——可在建立 repo 時綁定 Cloud KMS 的 Customer-Managed Encryption Key(CMEK)。
設定方式
gcloud artifacts repositories create regulated-images \
--location=asia-east1 \
--repository-format=docker \
--kms-key=projects/sec-prj/locations/asia-east1/keyRings/ar/cryptoKeys/ar-key
限制條件
- 區域必須一致。 KMS 金鑰必須與 repo 在同一個 region(或對應的 multi-region superset)。
asia-east1repo 不能用us-central1KMS key。 - Service Agent 綁定。 Artifact Registry 的 Service Agent(
service-PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com)需要在金鑰上有roles/cloudkms.cryptoKeyEncrypterDecrypter。 - 撤銷金鑰 = 立即斷拉。 停用金鑰會在數分鐘內讓所有 pull 失敗,錯誤碼為
PERMISSION_DENIED。 - 金鑰指派不可變更。 既有 repo 無法換綁 CMEK key——只能新建 repo 再遷移。
CMEK 在 multi-region repo 的情境下,必須使用對應的 multi-region KMS key。us multi-region 的 repo 不能用 us-central1 的 region key,即便 us-central1 屬於 us 範圍。這條「區域對齊」陷阱在 PCD CMEK 題裡反覆出現。
VPC Service Controls 與私有連線
對於不允許走公網的工作負載,Artifact Registry 支援 VPC Service Controls(VPC-SC) 與 Private Google Access。
VPC-SC 整合
Artifact Registry 是 VPC-SC 支援服務。將它納入 service perimeter 後,即便呼叫者 IAM 有效,只要來源不在 perimeter 內,pull/push 都會被拒絕。Perimeter 內:透過 Cloud Interconnect + Private Google Access 從地端來的 build、與 Cloud Build private pool,都能正常拉映像;perimeter 外的筆電則會收到 RESOURCE_NOT_IN_VPC_SC_PERIMETER。
Private Service Connect 端點
若要做到零外網 egress,可以為 pkg.dev 設定 PSC endpoint。內部流量透過 VPC 內的私有 VIP 抵達 Artifact Registry,工作負載不需要對外 IP,可滿足 constraints/compute.vmExternalIpAccess 組織政策。
Cloud Build Private Pools
Cloud Build 的 private pool 可置入你的 VPC,並以 --peered-network 設定,builder 透過私有 IP 拉 base image、推輸出。受規範 CI 的建議架構就是這套。
Container Analysis — 漏洞掃描
當你推送一個 Docker 映像,Container Analysis(屬於 Artifact Analysis)會比對上游漏洞資料庫(Debian、Ubuntu、Alpine、Red Hat、Maven、npm、Go module 等)自動掃 CVE——前提是已啟用該服務。
掃描模式
- On-Push Scanning — 推送時立即掃描。啟用 Container Scanning API(
containerscanning.googleapis.com)即可觸發。Finding 寫入 Container Analysis,並在 Artifact Registry UI 可查。 - Continuous Analysis — 持續性掃描,上游漏洞資料庫新增 CVE 時,會對 registry 內既有映像重新掃描,自最後一次 pull 起持續 30 天。30 天沒人拉就停止再掃。代表常被生產線拉的映像會持續被監控,被棄置的測試映像最終會脫離掃描範圍。
Vulnerability Findings API
每個 finding 都是綁定該映像 digest 的 Occurrence,欄位包含:cveId、severity(CRITICAL / HIGH / MEDIUM / LOW)、fixAvailable、affectedPackage、affectedVersion、fixedVersion。程式化存取:gcloud artifacts vulnerabilities list-pkgvulnerabilities。
嚴重度 SLO
常見政策:只要存在 CRITICAL 且 fixAvailable=true,就阻擋部署。這條規則由 Binary Authorization 落實,不靠人工把關。
口訣: 啟用 containerscanning.googleapis.com → push 觸發 on-push 掃描 → finding 寫成 Container Analysis Occurrence → continuous analysis 在「最後一次 pull 後 30 天」內持續再掃 → 用 gcloud artifacts vulnerabilities list-pkgvulnerabilities 查詢 → 用 Binary Authorization attestor 強制執行。
Binary Authorization — 部署時的政策強制
漏洞掃描只是「告知」,Binary Authorization 才是「強制」。它是 GKE、Cloud Run、Anthos、Cloud Run for Anthos 的部署時 admission controller,只要映像不符合政策,pod 直接禁止啟動。
核心物件
- Attestor — 具名實體(例如
built-by-cloud-build、vuln-scan-passed),持有一支公開 PGP/PKIX 金鑰。 - Attestation — 對特定映像 digest 通過某項檢查的簽章宣告,存為 Container Analysis Occurrence。
- Policy — 綁定到 GKE cluster 或 Cloud Run service:「任何映像都必須通過 A 與 B 兩個 attestor,
evaluationMode = REQUIRE_ATTESTATION」。
典型供應鏈流程
- Cloud Build 建置映像並推到 Artifact Registry。
- 推送觸發 Container Analysis 漏洞掃描。
- Cloud Build 的下一個 step 查詢漏洞結果;若無 CRITICAL,呼叫
gcloud beta container binauthz attestations sign-and-create由vuln-scan-passedattestor 簽出 attestation。 - 部署步驟推到 GKE。Binary Authorization admission webhook 檢查 digest,看到合法 attestation 就放行;缺 attestation 就拒絕,事件寫入 Cloud Audit Logs。
緊急通行與 Continuous Validation
- Break-glass deployments — 在工作負載加上
alpha.image-policy.k8s.io/break-glass: "true"註記可繞過強制,但會以高嚴重度事件被記錄。 - Continuous Validation(CV) — 對運行中的 pod 持續比對最新政策,若 pod 不再合規(例如 attestation 已被撤銷)就在 Cloud Logging 發出事件。
PCD 考題裡 Binary Authorization 最常見的陷阱是「以為它會在部署時掃描映像」。它不會。 Binary Authorization 是「政策檢查器」,只看 digest 上是否已存在 attestation。如果 pipeline 忘了簽,再安全的映像也部不了。正確修法是在 Cloud Build 的 deploy step 之前加 binauthz sign-and-create,而不是去放寬政策。
清理政策 — 自動垃圾回收
CI 每次 commit 都推一個 tagged 映像,儲存成本很快會失控。Artifact Registry 支援清理政策(cleanup policies),可自動刪除或 dry-run 舊產出物。
政策類型
- Keep policy — 保護符合條件的產出物不被刪。例:保留所有
prod-*或v[0-9]+.[0-9]+.[0-9]+的映像。 - Delete policy — 刪除符合條件的產出物。例:刪除超過 14 天的 untagged 映像。
可用條件
tagState—TAGGED、UNTAGGED、ANY。tagPrefixes— 依 tag 前綴 list 匹配。versionAge—30d、90d,只刪除超過 N 天的版本。packageNamePrefixes— 依套件名前綴匹配。mostRecentVersions.keepCount— 每個套件最新 N 個版本保留。
經典 recipe
gcloud artifacts repositories set-cleanup-policies web-images \
--location=asia-east1 \
--policy=cleanup-policy.json
最常見的政策:每個套件保留最新 10 個 tagged 版本,並刪除超過 7 天的 untagged 版本。先以 --dry-run 模式跑 30 天確認沒誤刪生產 tag,再正式啟用。
成本影響
一個團隊跨 50 個 microservice、每次 merge 各推兩個映像,一季可累積數 TB 的 layer;清理政策通常能回收 60-80% 儲存。Standard repo 儲存計費為 $0.10/GB-month。
複寫 — 多區域災難復原
Artifact Registry 支援 multi-region repository,內建地理複寫。
Regional vs Multi-Region
- Regional repository(例:
asia-east1)— 單區儲存、單區可用性 SLA。 - Multi-region repository(例:
us、eu、asia)— 自動跨群組內至少兩個 region 複寫。耐久度更高、讀取覆蓋更廣,但費用較高。
跨 region 複製模式
若需要在多個特定 region 主動有映像(不是用 multi-region 整組),建議的模式是「每個 region 一個 regional repo」,並在 Cloud Build 主推送後立刻用 gcloud artifacts docker tags add 或 crane copy 把新映像複製過去。這樣可以精準控制哪些映像要複寫(例如只複寫 production tag,不複寫 commit-sha tag)。
跨 project 複寫
官方並沒有「跨 project Artifact Registry 複寫」的內建服務。標準做法:給目的端 project 的 CI SA 在來源 repo 上授予 roles/artifactregistry.reader,再用 gcloud artifacts docker images add-tag 或 crane copy 鏡像過去。OSS 工具如 gcr-mirror 可自動化此流程並支援保留規則。
PCD 考題若描述「us-central1 與 us-east1 之間 fail over、RTO 必須 < 5 分鐘」,正確架構是一個 multi-region us 存放區,不是「兩個 regional repo + Cloud Function trigger 推送時自動複製」。Multi-region 複寫是自動的,比任何自製 copier 都快。
效能、成本與配額
計費維度
- 儲存: standard 與 remote repo 都是 $0.10/GB-month;multi-region 更高。
- 網路 egress: 適用 GCP 標準 egress 費率。同 region 內從 GCE/GKE/Cloud Run 拉取免費。
- Container Analysis: 按掃描映像計費(首次掃描 + continuous analysis)。
- Remote repository upstream fetch: 公開鏡像 fetch 本身免費,付費的是快取後占用的儲存空間。
配額
- 每 project 每 location 最多 1000 個 repo(可申請提高)。
- 單 layer 上傳上限 10 GiB。
- Tag 數量無硬上限,但超過每個套件 10K tag 後清理政策就變得必要。
延遲
同 region 從 Cloud Run / GKE 拉取,已快取 layer 通常毫秒級完成,新 layer 視大小數秒。跨 region 拉取會多 inter-region 延遲與 egress 成本——這也是 multi-region 或 regional-mirror 模式的另一個動機。
FAQ — Artifact Registry
Q1:新 project 還可以用 gcr.io 嗎?
不建議。Container Registry 已棄用,新 repo 一律建立在 Artifact Registry 的 *-docker.pkg.dev 主機名下。既有 gcr.io 透過 redirect 仍可運作,但新功能——CMEK、清理政策、remote repository——只在 Artifact Registry 才有。
Q2:Docker 推送要怎麼認證?
在工作站或 CI runner 上跑一次 gcloud auth configure-docker LOCATION-docker.pkg.dev,把 Google Cloud credential helper 寫進 ~/.docker/config.json 即可。Cloud Build 內部會自動處理 credential helper。
Q3:一個 repo 能不能同時放 Docker 與 Maven?
不行。每個 repo 在建立時就綁定唯一一種格式。多數團隊會「每個 region、每種格式」各建一個 repo(例:web-images 給 Docker、java-libs 給 Maven)。
Q4:roles/artifactregistry.reader 與 roles/storage.objectViewer 差在哪?
GCR-to-AR redirect 之後,只有 roles/artifactregistry.reader 有效。舊的 roles/storage.objectViewer on artifacts.*.appspot.com bucket 不再授權拉取,因為那個 bucket 已不在請求路徑上。
Q5:怎麼阻擋有漏洞的映像被部署?
啟用 Container Analysis(containerscanning.googleapis.com)在推送時掃描,再用 Binary Authorization 設定一個 attestor,只在「零 CRITICAL」時簽章;部署目的地(GKE、Cloud Run)就會拒絕任何沒有 attestation 的映像。
Q6:CMEK 會不會拉慢 pull?
幾乎不會。解密在儲存層由硬體後端的 KMS 完成,延遲是次毫秒級。真正的風險是金鑰被撤銷——所有 pull 會立即失敗。
Q7:可以把 Docker Hub 鏡像化避開 rate limit 嗎?
可以。建立一個 remote repository,--remote-repo-config-file 指向 Docker Hub。之後所有 pull 都先經過你的 Artifact Registry,首次 miss 後即快取;後續拉取就不再受 Docker Hub rate limit 限制。
PCD 結語
PCD 考試遇到關鍵字如 「私有套件倉庫」、「漏洞掃描」、「簽章式 image attestation」、「防止 dependency confusion」、「容器映像同時要 CMEK 與私有連線」,答案幾乎都是 Artifact Registry + Container Analysis + Binary Authorization + VPC-SC 的組合。把這四件套記熟,多數題目幾乎自動解開。