Progressive Delivery Strategies — Canary & Blue-Green
Tại sao Progressive Delivery Quan Trọng
Deploy thẳng tất cả traffic lên version mới (rolling update mặc định của Kubernetes) có rủi ro: nếu version mới có bug, 100% users bị ảnh hưởng ngay khi rollout hoàn thành. Progressive delivery giải quyết bằng cách kiểm soát tốc độ rollout: chỉ expose một phần nhỏ traffic lên version mới trước, validate, rồi mới expand.
Cloud Deploy hỗ trợ hai chiến lược: canary (tăng dần traffic percentage) và blue-green (parallel environments, atomic cutover). Hiểu cơ chế bên trong của từng chiến lược là điều kiện để thiết kế đúng và debug khi vấn đề xảy ra.
Canary Deployment — Cơ Chế Bên Trong
Ba loại canary configuration
Theo tài liệu Cloud Deploy, có ba cấu hình canary:
1. Automated canary: Cloud Deploy tự động tạo infrastructure cho traffic splitting. Người dùng chỉ cần chỉ định percentages.
2. Custom-automated canary: Người dùng chỉ định chi tiết phase, nhưng Cloud Deploy vẫn tự động manage infrastructure.
3. Custom canary: Full control — người dùng define tất cả, kể cả cách traffic splitting được thực hiện. Hoạt động với mọi target type.
Traffic Splitting Mechanics — GKE
Trên GKE, Cloud Deploy hỗ trợ hai cơ chế traffic splitting:
Service Networking (Kubernetes Services):
strategy:
canary:
runtimeConfig:
kubernetes:
serviceNetworking:
deployment: my-app
service: my-app-svcCơ chế này dùng replica count manipulation. Giả sử canary percentage là 10% và total replicas là 10:
- Cloud Deploy duy trì stable Deployment (version cũ): 9 replicas
- Tạo canary Deployment (version mới): 1 replica
- Cả hai Deployments dùng chung
Serviceselector → traffic được phân phối theo tỷ lệ số replicas
Giới hạn của cơ chế này: Tỷ lệ traffic phụ thuộc replica count, không phải request-based weights. Với replicas nhỏ (ví dụ 3 replicas), không thể đạt chính xác 10% — bạn chỉ có thể làm 33% (1/3) hay 0%. Đây là fundamental constraint của Service-based routing.
Gateway API (Kubernetes Gateway):
strategy:
canary:
runtimeConfig:
kubernetes:
gatewayServiceMesh:
httpRoute: my-app-route
service: my-app-svc
deployment: my-appVới Kubernetes Gateway API (HTTPRoute), traffic splitting được thực hiện ở tầng load balancer:
# Cloud Deploy tự động tạo/update HTTPRoute với weights:
spec:
rules:
- backendRefs:
- name: my-app-stable-svc
weight: 90 # Version cũ: 90%
- name: my-app-canary-svc
weight: 10 # Version mới: 10%Đây là request-based weight, không phụ thuộc replica count. Bạn có thể đạt chính xác bất kỳ percentage nào với bất kỳ số replicas nào. Tuy nhiên yêu cầu:
- GKE Dataplane V2 (Cilium) hoặc Cloud Service Mesh (Istio) để xử lý HTTPRoute
- Gateway controller được cài đặt trong cluster
Traffic Splitting trên Cloud Run
Cloud Run có cơ chế traffic splitting native — không cần Service Networking hay Gateway API:
strategy:
canary:
runtimeConfig:
cloudRun:
automaticTrafficControl: true
canaryDeployment:
percentages: [25, 50, 75]Cloud Deploy deploy revision mới của Cloud Run service, sau đó update traffic split config:
my-service:
revision-stable: 75% # Version cũ
revision-canary: 25% # Version mới (phase canary-25)Cloud Run native traffic splitting là request-based và rất chính xác. Đây là lý do Cloud Run canary đơn giản hơn GKE canary về mặt cơ chế.
Canary Phases
Với configuration percentages: [10, 50], Cloud Deploy tạo 3 phases:
Rollout phases:
1. canary-10 → Deploy version mới lên 10% traffic
2. canary-50 → Advance lên 50% traffic
3. stable → Deploy version mới lên 100%, version cũ bị xóaMỗi phase là một independent job có thể:
- Succeed → advance tự động hoặc manual promotion
- Fail → trigger repair automation hoặc manual intervention
- Timeout → treated as fail
Giữa các phases có thể có verify job: test suite chạy sau khi traffic đạt percentage mới, kiểm tra metrics, errors, latency. Nếu verify fail, rollout không advance.
Stable Phase — End State
Phase stable là khi canary "graduates" thành full deployment:
- Version mới được deploy như full Deployment (thay thế stable Deployment cũ)
- Canary Deployment bị xóa
- Traffic split resource (HTTPRoute/Service) được cleanup
Sau phase stable, cluster ở cùng trạng thái như một rolling update thông thường — không còn parallel Deployments, không còn traffic split configuration.
Blue-Green Deployment — Cơ Chế Bên Trong
Khái niệm cốt lõi
Blue-green deployment duy trì hai environments song song (blue = version cũ, green = version mới):
- Cả hai environments hoàn toàn functional và ready để serve traffic
- Tại một thời điểm cụ thể (cutover), traffic được chuyển từ blue sang green atomically (nhanh, không progressive)
- Blue environment được giữ lại sau cutover để phục vụ rollback nhanh
Khác canary ở điểm quan trọng: trong canary, users thật nhận version mới ở mỗi bước. Trong blue-green, không có users nào nhận version mới cho đến khi cutover hoàn tất.
Blue-Green trên GKE
strategy:
blueGreen:
serviceNetworking:
deployment: my-app
service: my-app-svc
autoUpdateServices: true
stableCutbackDuration: 60s # Thời gian giữ blue sau khi green rollout
predeploy:
phases: [predeploy]
postdeploy:
phases: [postdeploy]Flow của một blue-green rollout trên GKE:
Phase 1: predeploy (hooks chạy trước deploy)
Phase 2: deploy-green
→ Cloud Deploy tạo Deployment mới: {original-name}-green
→ Deployment mới rollout hoàn toàn (all replicas ready)
→ Service KHÔNG được update → traffic vẫn đến blue (version cũ)
Phase 3: verify (optional — test green trực tiếp qua canary endpoint)
Phase 4: postdeploy (hooks)
Cutover (manual advance hoặc automatic):
→ Service selector được update để trỏ sang green Deployment
→ stableCutbackDuration: giữ blue Deployment trong N seconds
→ Sau stableCutbackDuration: blue Deployment bị xóaStable cutback duration là thời gian sau khi cutover mà blue Deployment còn tồn tại. Trong khoảng thời gian này, rollback là instant (chỉ cần update Service selector trở lại). Sau khi hết thời gian, rollback yêu cầu deploy lại từ stable Rollout.
Blue-Green trên Cloud Run
strategy:
blueGreen:
trafficSplit: 100 # 100% traffic đến version mới sau cutover
disablePodOverprovisioning: falseCloud Run blue-green đơn giản hơn:
- Cloud Deploy deploy revision mới (green) nhưng set traffic = 0%
- Sau verify (nếu có), update traffic split: green 100%, blue 0%
- Blue revision được giữ lại (Cloud Run không tự xóa revision)
Khi nào dùng Blue-Green
Blue-green phù hợp khi:
- Database schema changes: Version mới cần schema mới, version cũ không tương thích ngược. Bạn muốn test version mới với 0 traffic thực trước khi cutover.
- Breaking API changes: Không thể có cả hai versions cùng serve traffic vì chúng không compatible.
- Batch jobs/workers: Không muốn partial traffic split — muốn atomic switch.
Blue-green không phù hợp khi:
- Resources cost là concern: duy trì 2x capacity trong suốt thời gian deploy
- Stateful applications với local state: chuyển traffic đột ngột có thể lost in-flight requests
Canary vs Blue-Green vs Rolling Update
| Tiêu chí | Rolling Update | Canary | Blue-Green |
|---|---|---|---|
| Traffic exposure | 100% ngay khi pod mới up | Tăng dần (10% → 50% → 100%) | 0% cho đến cutover |
| Cost trong deploy | 1x | ~1x + overhead nhỏ | ~2x |
| Rollback speed | Chậm (rolling rollback) | Nhanh (revert traffic split) | Instant (revert Service selector) |
| Phát hiện lỗi | Sau khi nhiều users bị ảnh hưởng | Sớm, trên subset nhỏ | Chỉ trong test phase trước cutover |
| Database compat | Cần backward compat | Cần backward compat | Có thể không cần (deploy xong rồi mới switch) |
| Phức tạp | Thấp | Trung bình | Cao |
Canary Analysis — Verify Phase Integration
Cloud Deploy hỗ trợ automated analysis trong canary phases để quyết định có advance hay không:
strategy:
canary:
canaryDeployment:
percentages: [10, 50]
verify: true # Enable verify phase sau mỗi canary stepVerify phase là một Job chạy sau khi traffic đạt percentage target. Nó thực thi analysis logic được định nghĩa trong Skaffold's verify section:
# skaffold.yaml
verify:
- name: check-error-rate
container:
name: error-rate-checker
image: my-error-checker-image
command: ["/bin/check-errors.sh"]
args: ["--threshold=0.01", "--window=5m"]Analysis job có thể:
- Query Cloud Monitoring metrics API
- Call external analysis service (Argo Rollouts analysis template pattern)
- Run integration test suite
- Check SLO compliance
Nếu verify job exit với code 0 → rollout advances. Non-zero exit → rollout fails, trigger rollback repair (nếu configured).
Failure Modes và Rollback trong Canary
Failure trong canary phase
Nếu canary-10 phase fail:
- Traffic vẫn đang split: 10% green, 90% stable
- Rollout trạng thái:
FAILED - Cloud Deploy không tự động revert traffic trừ khi Automation repair configured
- Engineer phải manually cancel rollout (revert traffic) hoặc trigger repair automation
Repair Automation (xem thêm file 04):
# Automation: tự động rollback khi rollout fail
rules:
- name: rollback-on-failure
rollbackRule:
sourceRunId: latestTại sao canary rollback không instant bằng blue-green
Trong canary với Service Networking, rollback = xóa canary Deployment và adjust replica counts. Quá trình này mất thời gian (Kubernetes terminate pods, scale down). Trong blue-green, rollback chỉ là update Service selector — milliseconds.
Các Ràng Buộc Kỹ Thuật Quan Trọng
GKE Canary với Service Networking: Minimum Replicas
Như đã phân tích, với serviceNetworking, traffic ratio = replica ratio. Muốn 10% canary với accuracy, cần ít nhất 10 replicas tổng. Nếu chỉ có 3 replicas, canary percentage options thực tế là: 33%, 67%, hoặc không canary.
Giải pháp: dùng Gateway API với HTTPRoute để có exact percentage control không phụ thuộc replica count.
Stateful Session Trong Canary
Nếu application dùng sticky sessions (session affinity), canary có thể không đúng: một user đã "dính" với stable pod có thể never được route sang canary pod. Analyze này sẽ không đại diện cho toàn bộ users.
Giải pháp: tắt session affinity trong thời gian canary, hoặc dùng header-based routing để explicitly route một subset users sang canary.
Database Migration và Canary
Canary ngầm giả định cả hai versions (stable + canary) chạy đồng thời và tương thích với cùng database state. Nếu version mới cần database migration:
- Migration phải backward-compatible (expand-and-contract pattern)
- Không drop columns cho đến khi toàn bộ traffic đã chuyển sang version mới
- Blue-green phù hợp hơn cho scenarios này vì deploy xong rồi mới switch traffic