Artifact Registry: Architecture & Repository Types
Tại sao quan trọng
Nơi bạn lưu trữ artifacts (Docker images, npm packages, Maven JARs, Python wheels) ảnh hưởng tới:
- Deployment latency: Image pull time từ registry
- Cost: Storage, egress bandwidth
- Security: Access control, vulnerability scanning, artifact governance
- Scalability: Registry performance khi push/pull hàng ngàn images
Artifact Registry là successor của Container Registry — nó cấp rộng hơn: support multiple package formats, tốt hơn governance, tích hợp sâu với Cloud Build.
Chương này dạy bạn architecture bên trong, repository types, cost optimization, và security posture.
Architecture: Artifact Registry Model
Storage Layer
Artifact Registry (logical service)
└─ Regional repositories
├─ us-central1: repo1, repo2
├─ us-east1: repo3
└─ europe-west1: repo4
↓ (backed by)
GCS buckets (internal, managed by Google)
├─ gs://artifacts-us-central1-xxxxx/ (repo1 data)
├─ gs://artifacts-us-central1-xxxxy/ (repo2 data)
└─ ...Key insight: Mỗi repository được backed bởi một managed GCS bucket. Bạn không directly access bucket, nhưng understanding cơ chế này giúp understand storage model.
Regional Architecture
Global Artifact Registry Service (API endpoint)
├─ Repository: us-central1/docker (backing GCS bucket at us-central1)
├─ Repository: us-east1/docker (backing GCS bucket at us-east1)
└─ Repository: europe-west1/docker
Push/Pull traffic:
- Developer ở us-central1 → us-central1 repo (local, fast)
- Developer ở us-east1 → us-east1 repo (local, fast)
- developer ở europe → europe-west1 repo (local, fast)Why regional?
- Data locality: Images stored ở region gần consumers → faster pulls
- Compliance: Dữ liệu stays ở specific geography
- Cost: Egress charges nếu pull từ different region
Repository Types
Artifact Registry supports multiple package formats:
1. Docker (Container Images)
gcloud artifacts repositories create docker-repo \
--repository-format=docker \
--location=us-central1Used for: OCI container images, Docker images
2. Maven (Java)
gcloud artifacts repositories create maven-repo \
--repository-format=maven \
--location=us-central1Used for: Java JAR files, Maven projects
3. npm (JavaScript/Node.js)
gcloud artifacts repositories create npm-repo \
--repository-format=npm \
--location=us-central1Used for: npm packages, Node.js dependencies
4. Python (PyPI)
gcloud artifacts repositories create python-repo \
--repository-format=python \
--location=us-central1Used for: Python wheels, PyPI packages
5. Go
gcloud artifacts repositories create go-repo \
--repository-format=go \
--location=us-central1Used for: Go modules
6. APT/YUM (OS Packages)
gcloud artifacts repositories create apt-repo \
--repository-format=apt \
--location=us-central1Used for: Debian, Ubuntu packages
7. Generic
gcloud artifacts repositories create generic-repo \
--repository-format=generic \
--location=us-central1Used for: Any binary artifact (executables, tarballs, etc.)
Repository Configuration & Organization
Single Project, Multiple Repositories
Best practice: Organize theo type hoặc team:
# Organize by type
gcloud artifacts repositories create docker-prod \
--repository-format=docker --location=us-central1
gcloud artifacts repositories create npm-prod \
--repository-format=npm --location=us-central1
# Or organize by team
gcloud artifacts repositories create team-backend \
--repository-format=docker --location=us-central1
gcloud artifacts repositories create team-frontend \
--repository-format=docker --location=us-central1Naming Convention
{artifact-type}-{environment}[-{team}]
Examples:
- docker-prod
- docker-staging
- npm-internal
- maven-java-services
- python-ml-platformAccess Control (IAM)
# Allow specific service account to push images
gcloud artifacts repositories add-iam-policy-binding docker-prod \
--location=us-central1 \
--member=serviceAccount:cloud-build-pusher@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.writer
# Allow service to pull images
gcloud artifacts repositories add-iam-policy-binding docker-prod \
--location=us-central1 \
--member=serviceAccount:gke-puller@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.readerIntegration with Cloud Build
Automatic Authentication
Cloud Build automatically authenticates to Artifact Registry:
steps:
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'us-central1-docker.pkg.dev/PROJECT_ID/docker-repo/app:latest'
# Authentication handled automatically by Cloud BuildHow?
Cloud Build service account has artifactregistry.writer role → can push/pull automatically.
Multi-Repository Push
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'app:latest', '.']
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'us-central1-docker.pkg.dev/$PROJECT_ID/prod/app:latest'
- 'us-east1-docker.pkg.dev/$PROJECT_ID/prod/app:latest'
# Push to both regionsVirtual Repositories (Aggregation)
Virtual repository groups multiple repositories:
gcloud artifacts repositories create aggregated \
--repository-format=docker \
--location=us-central1 \
--mode=virtual \
--upstream-repositories='docker-prod,docker-staging'Use case: Single pull endpoint serving images từ multiple repositories
Cost Model & Optimization
Storage Cost
$0.026 per GB per month (as of 2026)
Example:
- 10 Docker images @ 500 MB each = 5 GB
- Cost = 5 * $0.026 = $0.13/monthEgress Cost
$0.12 per GB (same region): Free
$0.12 per GB (different region): Paid egress
$0.50+ per GB (to internet): Most expensiveOptimization strategies:
- Collocate images và consumers: If GKE cluster ở us-central1, store images ở us-central1 repo
- Reuse base images: Large base images pulled frequently → cache locally
- Clean up old images: Implement retention policies (see Chapter 6)
Example Cost Scenario
Scenario: 100 deployments per day
Option A: Single large image (1 GB)
- Store ở us-central1
- GKE pulls from us-central1
- Cost: 1 GB storage * $0.026 = $0.026/month
- Egress: Free (same region)
- Total: ~$0.026/month
Option B: Large images spread across 5 regions
- Each region: 1 GB image
- Cost: 5 GB * $0.026 = $0.13/month
- Egress: 100 deployments * 1 GB * $0.12 (cross-region) = $12/month
- Total: ~$12/monthConclusion: Consolidate images to regions where consumers are.
Real-World: Multi-Environment Repository Setup
Scenario
- Backend services: 20+ microservices
- Environments: dev, staging, prod
- Regions: us-central1 (primary), us-east1 (failover), europe-west1
Repository Design
Artifact Registry Repositories:
1. docker-prod-us-central1 (primary production)
├─ Images: app-api, app-worker, app-scheduler
└─ Retention: 30 days
2. docker-staging-us-central1
├─ Images: all services (staging versions)
└─ Retention: 7 days
3. docker-dev-us-central1
├─ Images: developer builds
└─ Retention: 3 days
4. docker-prod-us-east1 (DR replica)
└─ Replicated from docker-prod-us-central1
5. docker-prod-europe-west1 (EMEA region)
└─ Replicated from docker-prod-us-central1Setup Script
# Create primary prod repo
gcloud artifacts repositories create docker-prod \
--repository-format=docker \
--location=us-central1
# Create staging
gcloud artifacts repositories create docker-staging \
--repository-format=docker \
--location=us-central1
# Create dev
gcloud artifacts repositories create docker-dev \
--repository-format=docker \
--location=us-central1
# For DR: replica to us-east1
gcloud artifacts repositories create docker-prod-dr \
--repository-format=docker \
--location=us-east1IAM Setup
# Cloud Build can push to all repos
for repo in docker-prod docker-staging docker-dev; do
gcloud artifacts repositories add-iam-policy-binding $repo \
--location=us-central1 \
--member=serviceAccount:cloud-build@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.writer
done
# GKE prod can pull from prod repo
gcloud artifacts repositories add-iam-policy-binding docker-prod \
--location=us-central1 \
--member=serviceAccount:gke-prod@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.reader
# GKE staging can pull from staging
gcloud artifacts repositories add-iam-policy-binding docker-staging \
--location=us-central1 \
--member=serviceAccount:gke-staging@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.readerAdvanced: Remote Repositories & Caching
Remote Repository (Upstream Caching)
gcloud artifacts repositories create docker-remote \
--repository-format=docker \
--location=us-central1 \
--mode=remote \
--remote-repository-config-enabledUse case: Act as cache for Docker Hub / public registries
# Instead of pulling directly from Docker Hub
# docker pull ubuntu:22.04
# Pull from your remote repo (cached)
# docker pull us-central1-docker.pkg.dev/PROJECT/docker-remote/ubuntu:22.04
# First pull: fetches from Docker Hub, caches ở Artifact Registry
# Subsequent pulls: fast (from local cache)Benefits:
- Control upstream sources
- Cache public images locally
- Faster pulls for frequently used images
- Compliance: All pulls go through your registry
Constraints & Failure Modes
Image Push Fails
ERROR: (gcloud.builds.submit) User does not have permission [artifactregistry.files.create]Solution: Grant service account write permission
gcloud artifacts repositories add-iam-policy-binding docker-repo \
--location=us-central1 \
--member=serviceAccount:builder@PROJECT.iam.gserviceaccount.com \
--role=roles/artifactregistry.writerImage Pull Slow
Possible causes:
- Image pulled from different region
- Image not cached locally
- Network latency
Solution:
- Store images ở region close to consumers
- Use remote repositories for frequently pulled public images
Repository Quota Exceeded
ERROR: Repository quota exceededLimits: Default 1000 repositories per project
Solution: Delete unused repositories
gcloud artifacts repositories delete docker-old --location=us-central1