Cloud Deploy Internal Model — Pipeline, Targets, Releases, Rollouts
Tại sao cần hiểu model này
Hầu hết các tool CD có giao diện giống nhau: chọn artifact, chọn môi trường, bấm deploy. Điều khiến Cloud Deploy khác biệt — và đòi hỏi phải hiểu model bên trong — là cách nó tách biệt các concerns:
- Delivery pipeline định nghĩa con đường artifact đi qua (dev → staging → prod)
- Target định nghĩa nơi đến cụ thể (cluster nào, region nào)
- Release đại diện cho một phiên bản artifact cụ thể, bao gồm cả manifests đã render
- Rollout là một lần thực thi deploy của một release lên một target cụ thể
Sự tách biệt này có ý nghĩa sâu: nó cho phép cùng một Release được deploy lên nhiều Target khác nhau với rollout riêng biệt, mỗi rollout có trạng thái và lịch sử độc lập. Khi rollback, bạn không rollback Pipeline — bạn tạo một Rollout mới trỏ về Release cũ. Hiểu model này giải thích tại sao Cloud Deploy hoạt động theo cách nó hoạt động.
Resource Hierarchy và Quan Hệ Giữa Chúng
Delivery Pipeline
DeliveryPipeline là resource trung tâm — nó định nghĩa promotion sequence: chuỗi các Target mà artifact phải đi qua, theo thứ tự, trước khi đến production.
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: my-app-pipeline
region: us-central1
description: "Pipeline cho my-app: dev → staging → prod"
serialPipeline:
stages:
- targetId: dev-gke
- targetId: staging-gke
profiles: [staging]
- targetId: prod-gke
profiles: [production]
strategy:
canary:
runtimeConfig:
kubernetes:
serviceNetworking: {}
canaryDeployment:
percentages: [10, 50]
verify: trueserialPipeline.stages là ordered list — thứ tự quan trọng. Không thể skip stage (trừ khi được cấu hình) hay promote ngược chiều. Đây là ràng buộc thiết kế có chủ đích: Cloud Deploy muốn đảm bảo mọi Release đều đi qua toàn bộ chuỗi validation trước khi đến production.
profiles trong mỗi stage mapping sang Skaffold profiles — cho phép render khác nhau tùy môi trường (khác số replicas, resource limits, feature flags).
Target
Target định nghĩa runtime environment cụ thể:
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: prod-gke
region: us-central1
requireApproval: true
gke:
cluster: projects/my-project/locations/us-central1/clusters/prod-clusterTarget types được hỗ trợ:
- GKE: Standard cluster, Autopilot cluster, Attached cluster (Anthos)
- Cloud Run: Deploy Cloud Run services
- Custom: Arbitrary deployment target qua custom Cloud Build job
- Multi-target: Deploy đồng thời lên nhiều targets (parallel deploy — không phải serial)
requireApproval: true là field quan trọng: bất kỳ Rollout nào nhắm đến Target này sẽ bị giữ lại ở trạng thái PENDING_APPROVAL cho đến khi một approver có đủ IAM role approve nó. Đây là primary mechanism để tạo manual gate trước production.
Theo tài liệu Cloud Deploy: "Targets must reside in the same project and region as the delivery pipeline." Đây là ràng buộc quan trọng về architecture: không thể có một pipeline deploy cross-project theo cơ chế trực tiếp — cần thiết kế thêm nếu có multi-project requirements.
Release
Release là resource quan trọng nhất xét về semantics. Nó đại diện cho:
- Một tập container images cụ thể (được pin theo digest, không phải tag)
- Rendering source (Skaffold config + manifests tại thời điểm tạo release)
- Rendered manifests cho mỗi Target/profile combination
Khi tạo Release:
gcloud deploy releases create release-v1-2-3 \
--delivery-pipeline=my-app-pipeline \
--region=us-central1 \
--images=my-app=us-central1-docker.pkg.dev/my-project/repo/my-app@sha256:abc123...Cloud Deploy thực hiện render phase: nó gọi skaffold render với images đã cung cấp, tạo ra manifests đã render cho mỗi Stage trong pipeline. Các manifests này được lưu vào Cloud Storage bucket — bucket này do Cloud Deploy tự tạo và quản lý.
Đây là điểm khác biệt quan trọng: Release snapshot cả manifests lẫn images vào một thời điểm cố định. Nếu Skaffold config thay đổi sau khi Release được tạo, Release đó vẫn dùng bản snapshot cũ. Điều này đảm bảo reproducibility: bạn có thể deploy lại cùng Release vào bất kỳ lúc nào và nhận được kết quả giống hệt.
Rollout
Rollout là record của một lần thực thi deploy Release lên Target:
- Mỗi Release có nhiều Rollouts (một per Target khi promote qua pipeline)
- Rollout có lifecycle:
PENDING_APPROVAL→IN_PROGRESS→SUCCEEDED/FAILED/CANCELLED - Mỗi Rollout chứa một hoặc nhiều Phases
- Mỗi Phase chứa một hoặc nhiều Jobs
- Mỗi Job execution là một JobRun (immutable record)
Release release-v1-2-3
├── Rollout rollout-dev-001 (Target: dev-gke, trạng thái: SUCCEEDED)
│ └── Phase deploy
│ └── Job deploy-job → JobRun [SUCCEEDED]
├── Rollout rollout-staging-001 (Target: staging-gke, trạng thái: SUCCEEDED)
│ └── Phase deploy
│ └── Job deploy-job → JobRun [SUCCEEDED]
└── Rollout rollout-prod-001 (Target: prod-gke, trạng thái: PENDING_APPROVAL)Rollout là unit of audit: mọi hành động deploy, approve, fail đều được record trên Rollout resource và có thể truy vết trong Cloud Audit Logs.
Lifecycle của Một Deployment — End-to-End
Hiểu lifecycle này giúp debug vấn đề và thiết kế pipeline đúng.
Bước 1: Release Creation & Render Phase
gcloud deploy releases create ... → Cloud Deploy APICloud Deploy nhận request, sau đó:
- Lấy rendering source: Clone Git repo (hoặc download từ Cloud Storage) tại commit được chỉ định. Nếu không chỉ định commit, nó dùng HEAD.
- Archive rendering source: Nén và lưu vào Cloud Storage bucket. Đây là basis cho reproducibility.
- Gọi Cloud Build: Cloud Deploy trigger Cloud Build job để thực thi
skaffold diagnose(validate config) vàskaffold render(render manifests). Cloud Build chạy trong execution environment với Skaffold pre-installed. - Store rendered manifests: Manifests đã render được lưu vào Cloud Storage, tổ chức theo structure:
releases/{release-name}/targets/{target-id}/phases/{phase-name}/manifests/. - Tạo initial Rollout: Cloud Deploy tự động tạo Rollout đầu tiên targeting Stage đầu tiên trong pipeline.
Nếu render fail (Skaffold config sai, manifest lỗi), Release vẫn được tạo nhưng ở trạng thái FAILED. Không có Rollout nào được tạo.
Bước 2: Deploy Phase (Rollout Execution)
Khi Rollout vào trạng thái IN_PROGRESS:
- Cloud Deploy lấy rendered manifests từ Cloud Storage cho target và phase tương ứng.
- Trigger Cloud Build job để thực thi
skaffold apply. skaffold applyapply manifests lên cluster — về bản chất là server-side apply (kubectl apply --server-side).- Nếu có verification configured, trigger verify job sau khi deploy.
- Nếu có post-deploy hooks, chạy sau verification.
- Rollout chuyển sang
SUCCEEDEDkhi tất cả phases/jobs hoàn thành thành công.
Execution Environment: Cloud Build mặc định dùng worker pools trong project của Cloud Deploy. Có thể cấu hình Private Worker Pools để deploy vào private clusters không có public endpoint.
Bước 3: Promotion
Promotion là trigger để tạo Rollout cho Stage tiếp theo:
gcloud deploy releases promote \
--release=release-v1-2-3 \
--delivery-pipeline=my-app-pipeline \
--to-target=staging-gke \
--region=us-central1Hoặc tự động qua Automation (xem Chương 4 của file này, phần Automation).
Promotion tạo một Rollout mới với cùng Release (cùng images, cùng rendered manifests). Rollout mới sẽ:
- Vào trạng thái
PENDING_APPROVALnếu Target córequireApproval: true - Vào trạng thái
IN_PROGRESSngay nếu không có approval requirement
Cloud Storage Artifact Layout
Cloud Deploy tự động tạo và manage một GCS bucket: {project-number}-{region}-clouddeploy. Layout bên trong:
gs://123456789-us-central1-clouddeploy/
└── source/
└── {pipeline-name}/
└── releases/
└── {release-name}/
├── source.tar.gz # Archived rendering source
└── targets/
└── {target-id}/
└── phases/
└── {phase}/
└── manifests/
├── manifest.yaml # Rendered K8s manifests
└── skaffold.yaml # Rendered Skaffold configĐiều quan trọng: bucket này là immutable store cho Release artifacts. Cloud Deploy không sửa hay xóa artifacts sau khi render. Điều này cho phép:
- Inspect bất kỳ Release nào trong quá khứ
- So sánh manifests giữa các Release (diff)
- Audit trail đầy đủ về những gì đã được deploy
Parallel Targets và Multi-Target
Cloud Deploy hỗ trợ triển khai Release đồng thời lên nhiều Targets bằng multiTarget:
serialPipeline:
stages:
- targetId: dev
- targetId: staging
- targetId: multi-region-prod # Multi-targetapiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: multi-region-prod
multiTarget:
targetIds:
- prod-us-central1
- prod-europe-west1Với multi-target, Cloud Deploy tạo một "child Rollout" trên mỗi target con và track chúng như một nhóm. Rollout cha chỉ SUCCEEDED khi tất cả child Rollouts thành công.
Giới hạn cần biết:
- Tối đa 2 targets trong một multi-target (theo docs hiện tại)
- Child rollouts không thể có approval riêng biệt (approval ở mức parent)
- Rollback của parent Rollout sẽ rollback tất cả children
Constraints và Failure Modes Quan Trọng
Region Co-location Requirement
DeliveryPipeline, Targets, và Rollouts phải cùng region. Đây là thiết kế có chủ đích để đảm bảo control plane availability. Cluster GKE có thể ở bất kỳ region nào, nhưng Cloud Deploy resource phải ở cùng region.
Cloud Deploy pipeline (us-central1)
├── Target dev-gke → GKE cluster (us-central1) ✓
├── Target staging-gke → GKE cluster (us-east1) ✓ # Cluster khác region OK
└── Target prod-gke → GKE cluster (asia-east1) ✓ # Cluster khác region OKCloud Build Job Duration
Render và deploy đều chạy qua Cloud Build. Mặc định, Cloud Build job timeout là 60 phút. Nếu deploy phức tạp (nhiều resources, slow rollout), cần cấu hình timeout phù hợp trong execution environment.
Render Failure vs Deploy Failure
Hai loại failure có hành vi khác nhau:
- Render failure: Release ở trạng thái
FAILED. Không có Rollout nào được tạo. Phải tạo Release mới sau khi fix Skaffold config. - Deploy failure: Rollout ở trạng thái
FAILED. Release vẫn valid. Có thể retry Rollout (nếu hỗ trợ) hoặc trigger repair automation.
Phân biệt này quan trọng cho incident response: nếu thấy Release FAILED, vấn đề ở rendering; nếu Rollout FAILED nhưng Release SUCCEEDED, vấn đề ở deployment.
IAM cho Cloud Deploy Service Account
Cloud Deploy cần service account với đủ permissions. Mặc định nó dùng Compute Engine default service account, nhưng production nên dùng dedicated service account với least-privilege:
roles/clouddeploy.jobRunner: Thực thi Cloud Build jobsroles/container.developer: Apply manifests lên GKEroles/artifactregistry.reader: Pull images từ Artifact Registryroles/storage.objectAdmin: Read/write Cloud Storage bucket
Anti-patterns Thường Gặp
Anti-pattern 1: Dùng image tags thay vì digests
# SAI — tag 'latest' là mutable pointer
--images=my-app=us-central1-docker.pkg.dev/project/repo/my-app:latest
# ĐÚNG — digest là immutable
--images=my-app=us-central1-docker.pkg.dev/project/repo/my-app@sha256:abc...Dùng tag thay vì digest phá vỡ reproducibility của Release. Nếu Release được tạo lại (ví dụ retry render), nó có thể pull image khác nếu tag đã được update. Cloud Deploy cho phép dùng tag nhưng khuyến nghị digest cho production.
Anti-pattern 2: Dùng một DeliveryPipeline cho nhiều applications
# SAI — một pipeline cho cả frontend và backend
serialPipeline:
stages:
- targetId: dev
- targetId: staging
- targetId: prodNếu frontend và backend share pipeline, một Release phải chứa cả hai components. Deploy frontend mới đòi hỏi tạo Release với cả backend images (dù backend không thay đổi). Mỗi application nên có pipeline riêng.
Anti-pattern 3: Bỏ qua render phase trong CI
Một số teams chỉ verify Skaffold config locally mà không test render phase trong CI. Vì Cloud Deploy dùng Cloud Build environment để render (không phải local machine), có thể có differences về Skaffold version, build tools. Test render phase trong CI: skaffold render --profile=dev.