Skip to content

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 approval

Key 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

yaml
# 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: production

Creating Targets

bash
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.yaml

Deployment Strategies

1. All-at-Once (Immediate)

yaml
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% traffic

Risk: If new version has bug, 100% traffic affected immediately

Use case: Development, non-critical services

2. Canary Strategy

yaml
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: 100

Execution:

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% traffic

Monitoring: 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

yaml
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 green

Execution:

Blue (old): 100% traffic
Green (new): Created, tests run against green
    ↓ (if tests pass)
Blue (old): 0% traffic
Green (new): 100% traffic

Advantage: Zero-downtime, instant cutover

Disadvantage: Requires 2x resources during transition


Approval Gates & Manual Review

yaml
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: false

Approval workflow:

bash
# 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-central1

Integration with Cloud Build

Unified Pipeline: Build → Deploy

yaml
# 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 complete

Real-World: Canary Deployment with Monitoring

Setup

yaml
# 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-cluster

Monitoring Between Phases

Cloud Deploy integrates with Cloud Monitoring:

yaml
# 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 fails

Example metrics to monitor:

  • Error rate (should stay < 1%)
  • Latency (p99 latency should stay similar)
  • Resource utilization (CPU, memory)

Rollback Mechanism

If deployment detects issue:

bash
# 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-central1

Rollback happens by:

  1. Reverting to previous image SHA256
  2. Reapplying previous Kubernetes manifests
  3. 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)

References