Cloud Deploy & Managed Delivery Strategies
Tại sao quan trọng
Sau khi image được built, scanned, và attested, next step: deploy to targets (GKE, Cloud Run, Compute Engine).
Nhưng deployment không đơn giản là "push image and hope":
- Phải deploy tới multiple environments (dev, staging, prod)
- Phải minimize risk (gradual rollouts, not all-at-once)
- Phải có approval gates (không ai có thể unilaterally deploy prod)
- Phải support rollbacks (nếu deployment fail, revert quickly)
Cloud Deploy là managed service giải quyết những concern này. Nó định nghĩa delivery pipelines với multiple targets, supports canary/blue-green strategies, và integrates với Binary Authorization.
Cloud Deploy Architecture
Delivery Pipeline Model
[Release] → [Target: dev] → [Target: staging] → [Target: prod]
↓ ↓ ↓
Auto-deploy Auto-deploy Requires approvalKey concepts:
- Pipeline: Định nghĩa promotion sequence (dev → staging → prod)
- Release: Cụ thể artifact version (e.g., image SHA256:abc123)
- Target: Deployment destination (GKE cluster, Cloud Run service)
- Rollout: Association của release tới target
Setup: Delivery Pipeline Configuration
# deploy.yaml
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: my-app-pipeline
description: "Delivery pipeline for my-app"
serialPipeline:
stages:
- targetId: dev
profiles: [dev]
- targetId: staging
profiles: [staging]
# Optional: require approval before rolling out to staging
# deployParameters:
# - requireApproval: true
- targetId: prod
profiles: [prod]
deployParameters:
- requireApproval: true # ALWAYS require approval for prod
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: dev
location: us-central1
description: "Development GKE cluster"
gke:
cluster: projects/PROJECT_ID/locations/us-central1-a/clusters/dev-cluster
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: prod
location: us-central1
description: "Production GKE cluster"
gke:
cluster: projects/PROJECT_ID/locations/us-central1-a/clusters/prod-cluster
namespace: productionCreating Targets
gcloud deploy targets create dev \
--gke-cluster=projects/PROJECT_ID/locations/us-central1-a/clusters/dev-cluster \
--location=us-central1
gcloud deploy targets create prod \
--gke-cluster=projects/PROJECT_ID/locations/us-central1-a/clusters/prod-cluster \
--location=us-central1
gcloud deploy delivery-pipelines create my-app-pipeline \
--location=us-central1 \
--config=deploy.yamlDeployment Strategies
1. All-at-Once (Immediate)
apiVersion: deploy.cloud.google.com/v1
kind: DeploymentStrategy
metadata:
name: immediate
description: "Deploy all replicas immediately"
standard:
predeploy:
[]
postdeploy:
[]Execution:
Old version: 100% traffic
↓ (immediate)
New version: 100% trafficRisk: If new version has bug, 100% traffic affected immediately
Use case: Development, non-critical services
2. Canary Strategy
apiVersion: deploy.cloud.google.com/v1
kind: DeploymentStrategy
metadata:
name: canary
description: "Canary: 5% → 25% → 100%"
canary:
canaryPhases:
- phase: "5-percent"
percentage: 5
skipMessages:
- "Canary phase 5%"
- phase: "25-percent"
percentage: 25
skipMessages:
- "Canary phase 25%"
- phase: "100-percent"
percentage: 100Execution:
Step 1: 5% traffic to new version
(monitor metrics, logs)
↓ (if healthy, continue)
Step 2: 25% traffic
(monitor further)
↓ (if healthy, continue)
Step 3: 100% trafficMonitoring: Cloud Monitoring + logs between phases
Rollback: If problem detected, revert to previous version
Real example:
Time 0:00 → 5% traffic to v2 (user 1 out of 20 gets v2)
Time 0:10 → Monitoring: Error rate normal, latency normal
Time 0:15 → Increase to 25% (users 1-5 get v2)
Time 0:25 → Monitoring: Still healthy
Time 0:30 → 100% (all users on v2)3. Blue-Green Strategy
apiVersion: deploy.cloud.google.com/v1
kind: DeploymentStrategy
metadata:
name: blue-green
description: "Blue-green deployment"
blueGreen:
activeTrafficPercent: 0 # New (green) gets 0% initially
candidatePercent: 100 # Green gets 100% for validation
# After validation, traffic switches to greenExecution:
Blue (old): 100% traffic
Green (new): Created, tests run against green
↓ (if tests pass)
Blue (old): 0% traffic
Green (new): 100% trafficAdvantage: Zero-downtime, instant cutover
Disadvantage: Requires 2x resources during transition
Approval Gates & Manual Review
serialPipeline:
stages:
- targetId: dev
profiles: [dev]
# Auto-promote to next stage
- targetId: staging
profiles: [staging]
# Requires manual approval before promoting to staging
deployParameters:
- requireApproval: true
- targetId: prod
profiles: [prod]
deployParameters:
- requireApproval: true
- skipApprovedReleases: falseApproval workflow:
# Cloud Build creates release
gcloud deploy releases create v1.0.0 \
--delivery-pipeline=my-app-pipeline \
--region=us-central1
# Manually approve promotion to staging
gcloud deploy releases approve v1.0.0 \
--delivery-pipeline=my-app-pipeline \
--region=us-central1
# Manually approve promotion to prod
gcloud deploy releases promote v1.0.0 \
--delivery-pipeline=my-app-pipeline \
--region=us-central1Integration with Cloud Build
Unified Pipeline: Build → Deploy
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/repo/app:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/repo/app:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/gke-deploy'
args:
- 'run'
- '--filename=k8s/'
- '--image=us-central1-docker.pkg.dev/$PROJECT_ID/repo/app:$SHORT_SHA'
- '--location=us-central1'
- '--config=deploy.yaml'
images: ['us-central1-docker.pkg.dev/$PROJECT_ID/repo/app:$SHORT_SHA']Flow:
Git push
↓
Cloud Build trigger
├─ Build Docker image
├─ Push to Artifact Registry
├─ Create Cloud Deploy release
└─ Auto-promote through pipeline (dev → staging)
(blocks at prod, requires approval)
Manual approval
↓
Promote to prod
↓
Deployment completeReal-World: Canary Deployment with Monitoring
Setup
# deploy.yaml
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: app-pipeline
serialPipeline:
stages:
- targetId: prod
deploymentStrategy:
canary:
canaryPhases:
- phase: "5-percent"
percentage: 5
skipMessages: []
- phase: "100-percent"
percentage: 100
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: prod
location: us-central1
gke:
cluster: projects/PROJECT_ID/locations/us-central1-a/clusters/prod-clusterMonitoring Between Phases
Cloud Deploy integrates with Cloud Monitoring:
# Deployment strategy with monitoring
canary:
canaryPhases:
- phase: "5-percent"
percentage: 5
postdeploy:
- name: "check-error-rate"
# Cloud Deploy queries monitoring to check error rate
# If error rate > threshold, deployment failsExample metrics to monitor:
- Error rate (should stay < 1%)
- Latency (p99 latency should stay similar)
- Resource utilization (CPU, memory)
Rollback Mechanism
If deployment detects issue:
# Automatic rollback (if Monitoring detects anomaly)
gcloud deploy rollouts rollback ROLLOUT_ID \
--delivery-pipeline=app-pipeline \
--release=v1.0.0 \
--region=us-central1
# Manual rollback
gcloud deploy releases promote PREVIOUS_RELEASE_ID \
--delivery-pipeline=app-pipeline \
--region=us-central1Rollback happens by:
- Reverting to previous image SHA256
- Reapplying previous Kubernetes manifests
- Traffic gradually shifted back to old version (if using canary)
Constraints & Limitations
Cloud Deploy Only for Supported Targets
Supported:
- GKE
- Cloud Run
- Compute Engine (GCE instances)
- App Engine
Not directly supported:
- On-premises Kubernetes (but can use Google Distributed Cloud)
Canary Requires Stateless Application
Canary assumes application is stateless:
- Running v1 and v2 simultaneously
- If session affinity needed, more complex
No Automatic Metrics-Based Rollback
Cloud Deploy doesn't automatically rollback based on metrics. You must:
- Implement custom monitoring check
- Or manually trigger rollback
- Or use third-party tools (e.g., Argo Rollouts)