K8s Canary Deployment
Có nhiều chiến lược triển khai (deployment strategy) được áp dụng khi đưa một phiên bản mới của ứng dụng lên môi trường thực tế (production). Các chiến lược triển khai phổ biến là recreate, ramped, blue/green, canary, A/B testing, shadow… Mỗi chiến lược triển khai đều có điểm mạnh và yếu riêng. Việc lựa chọn chiến lược nào sẽ tuỳ thuộc vào bài toán cụ thể của từng loại ứng dụng. Đối với các services trong VinID Platform, mỗi rủi ro gặp phải khi triển khai ở môi trường Production sẽ có sự ảnh hưởng rất lớn đến toàn bộ hệ thống, cũng như trải nghiệm người dùng. Vậy nên, áp dụng các giải pháp an toàn cho các trường hợp này là ưu tiên hàng đầu và là điều quan trọng cần phải làm. Bài viết này tập trung vào việc tìm hiểu xem Canary deployment là gì, đã và đang áp dụng ở VinID Platform thế nào. Qua đó hiểu được lí do VinID Platform, cũng như các ông lớn công nghệ như Google, Facebook, Amazon đều lựa chọn Canary khi triển khai hệ thống lớn của mình.
Cụ thể trong bài toán thiết kế hệ thống Notification Center, được sử dụng để gửi email, SMS, push notification … Là service đầu cuối, nhận yêu cầu liên tục từ hàng chục các micro-services khác của VinID. Khi triển khai Notification Center, một sai sót nhỏ có thể ảnh hưởng đến toàn bộ hệ thống SuperApp của VinID. Đảm bảo được zero downtime, giảm mức độ ảnh hưởng và có thể kịp thời rollback là tiêu chí hàng đầu trong việc chọn chiến lược triển khai.
Mỗi chiến lược triển khai đều có điểm mạnh và yếu riêng. Việc lựa chọn chiến lược nào sẽ tuỳ thuộc vào tình hình và bài toán cụ thể của từng loại ứng dụng
Chuyển dần các traffic sang version mới, đo đạc thông số để đánh giá mức độ rủi ro để có thể quyết định rollback kịp thời là điểm mạnh của Canary deployment
Canary là chiến lược triển khai từng phần. Khi phiên bản mới được triển khai (v2), các traffic sẽ được chuyển dần từ phiên bản cũ (v1) qua v2. Các traffic này sẽ được phân chia theo tỷ trọng (weight), tăng dần theo mỗi bước (step). Sau mỗi bước sẽ đánh giá chất lượng của v2 so với v1, việc đánh giá này tuỳ thuộc vào ngữ cảnh sẽ là tỉ lệ lỗi, hiệu năng (performance), độ trễ (latency).
Ví dụ có thể chia làm 5 bước, giảm dần tỉ trọng các traffic vào v1, đồng thời tăng tỉ trọng các traffic vào v2:
- Bước 1: 90% request vào v1, 10% request vào v2
- Bước 2: 80% request vào v1, 20% request vào v2
- Bước 3: 70% request vào v1, 30% request vào v2
- Bước 4: 60% request vào v1, 40% request vào v2
- Bước 5: 50% request vào v1, 50% request vào v2
Sau mỗi bước sẽ kiểm tra số lượng các request bị lỗi (http code 5xx) và tốc độ phản hồi có đúng mục tiêu không (P99 dưới 500ms). Nếu kết quả không như mong muốn sẽ đẩy các traffic vào v1 như cũ và loại bỏ v2. Nếu kết quả phù hợp thì sẽ quyết định sử dụng v2 và loại bỏ v1.
Với chiến lược đó, canary sẽ giúp kiểm soát tốt chất lượng của phiên bản mới, kịp thời đánh giá chất lượng và đưa ra quyết định chính xác khi xác nhận phiên bản mới (promote new version).
Việc thực hiện đánh giá theo từng bước dẫn đến quá trình rollout một phiên bản mới có thể mất đến vài chục phút đến vài tiếng đồng hồ tuỳ ngữ cảnh.
Kubernetes cung cấp các giải pháp về triển khai hệ thống micro-services thông qua các Object cơ bản: Ingress, Service, Pod, Deployment, ReplicaSet …
Chiến lược triển khai Canary có thể áp dụng được bằng cách sử dụng RepliaSet để cân đối weight và cơ chế label selector của Service để phân tải vào các Pod.
Tuy nhiên, việc đưa ra quyết định rollout hay rollback của Canary phụ thuộc lớn vào việc đánh giá chất lượng thông qua các metrics. Sử dụng Service Mesh như Istio sẽ giúp thu thập các metrics theo chuẩn chung, đầy đủ và dễ dàng hơn rất nhiều.
Ngoài ra, Virtual Service của Istio có thể kiểm soát và điều hướng các traffic dễ dàng theo weight, hoặc nhiều tiêu chí khác.
Flagger là bộ công cụ giúp thực hiện quá trình canary deployment một cách hoàn toàn tự động. Flagger giúp đơn giản hoá quá trình triển khai Canary với một vài thiết lập cơ bản. Mỗi khi có sự thay đổi về Deployment Spec, Secret hay ConfigMap, Flagger sẽ trigger quá trình triển khai Canary tự động. Tổng hợp các metrics được thu thập qua Istio từ Prometheus, Flagger sẽ đánh giá chất lượng của Canary và đưa ra quyết định rollout/rollback/promote candidate version.
apiVersion: flagger.app/v1alpha3
kind: Canary
metadata:
name: my-app
namespace: dev
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
progressDeadlineSeconds: 60
autoscalerRef:
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
name: my-app
service:
match:
- uri:
prefix: /context-path
port: 80
targetPort: 8080
gateways:
- internal-gateway.istio-system.svc.cluster.local
hosts:
- abc.xyz
appendHeaders:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
canaryAnalysis:
# schedule interval
interval: 30s
# max number of failed metric checks before rollback
threshold: 5
# max traffic percentage routed to canary
# percentage (0-100)
maxWeight: 50
# canary increment step
# percentage (0-100)
stepWeight: 10
metrics:
- name: request-success-rate
# minimum req success rate (non 5xx responses)
# percentage (0-100)
threshold: 99
interval: 1m
- name: request-duration
# maximum req duration P99
# milliseconds
threshold: 500
interval: 30s
webhooks:
- name: "acceptance tests"
type: pre-rollout
url: http://loadtester.test/
timeout: 5m
metadata:
type: "bash"
cmd: "./newman.sh"
- name: "load test"
url: http://loadtester.test/
timeout: 10m
metadata:
type: "bash"
cmd: "./k6.sh"
- Confirm-rollout: Hook trước quá trình scaling up Canary deployment. Có thể dùng để thực hiện việc xác nhận triển khai thủ công. Pre-rollout: Hook trước khi đưa các traffic vào Canary. Có thể chạy các acceptance tests để xác định service đã hoạt động đúng hay không,
- nếu kết quả test không đạt, Flagger sẽ thực hiện rollout. Việc này sẽ đảm bảo chất lượng của service là tốt nhất, phát hiện sớm các lỗi logic bằng bộ test cases được xây dựng đầy đủ.
- Rollout: Hook trong quá trình phân tích trước khi kiểm tra các metrics ở mỗi bước thay đổi tỷ trọng traffic vào Canary. Có thể chạy các load test để tăng số lượng tải về hệ thống, nhằm bộc lộ các điểm yếu về hiệu năng.
- Confirm-promotion: Hook sau khi quá trình promotion kết thúc. Có thể dùng để thực hiện việc xác nhận thủ công việc cho phép triển khai hoàn toàn phiên bản mới.
- Post-rollout: Hook sau khi toàn bộ quá trình đã kết thúc. Có thể dùng để gửi thông báo về quá trình triển khai thành công hay thất bại.
LoadTester là một trong các bộ công cụ của Flagger, chứa các công cụ phục vụ cho quá trình automation test như Helm test, BATS (Bash Automated Testing System), nGrinder, ghz, hey … Tuy nhiên, để hướng tới việc tăng tốc độ phát triển và triển khai các kịch bản test đa dạng trên một nền tảng duy nhất, chúng tôi tích hợp thêm hai công cụ là Postman và K6.
WIP
All rights reserved