Mở đầu — vì sao bài này quan trọng
Hãy tưởng tượng bạn là kỹ sư vận hành của một sàn thương mại điện tử Việt Nam. Đúng 20 giờ tối thứ Sáu — giờ cao điểm mua sắm — bạn cần đưa một phiên bản mới của ứng dụng lên production. Nếu bạn "tắt hệ thống, cập nhật, rồi bật lại", khách hàng sẽ thấy trang trắng trong vài phút, giỏ hàng bị mất, và bộ phận chăm sóc khách hàng ngập trong khiếu nại. Ngược lại, nếu bạn biết cách triển khai đúng, hàng chục nghìn người dùng vẫn mua sắm bình thường mà không hề hay biết rằng phần mềm bên dưới vừa được thay mới hoàn toàn.
Đó chính là lý do deployment strategy (chiến lược triển khai) tồn tại. Trong toàn bộ khóa CI/CD này, các bài trước đã giúp bạn hiểu pipeline tự động đưa code từ commit đến môi trường chạy thật. Nhưng "đưa lên như thế nào" mới là phần quyết định trải nghiệm người dùng và mức độ an toàn của hệ thống. Cùng một artifact, cùng một pipeline, nhưng cách bạn thay thế phiên bản cũ bằng phiên bản mới có thể là khác biệt giữa một đêm ngủ ngon và một sự cố phải huy động cả team lúc nửa đêm.
Bài này tập trung riêng vào các chiến lược triển khai (deployment strategies) ở góc độ tổng quan — cách các mô hình khác nhau đánh đổi giữa tốc độ, chi phí, rủi ro và trải nghiệm người dùng. Bạn sẽ nắm được bức tranh toàn cảnh để chọn đúng chiến lược cho từng bối cảnh. Các bài sau (Rolling Update chi tiết, Blue-Green, Canary, Feature Flags, Rollback) sẽ đào sâu từng chiến lược, nên ở đây tôi sẽ giúp bạn có tấm bản đồ tư duy trước khi đi vào từng con đường cụ thể.
Khái niệm cốt lõi
Trước hết, cần phân biệt hai khái niệm hay bị nhầm: release và deployment. Deployment là hành động kỹ thuật đưa mã mới lên máy chủ. Release là việc phiên bản mới thực sự phục vụ người dùng. Một số chiến lược cho phép bạn deploy code lên server nhưng chưa release cho khách — đây là chìa khóa của nhiều kỹ thuật an toàn.
Mọi chiến lược triển khai đều xoay quanh việc cân bằng bốn yếu tố: downtime (thời gian gián đoạn), rủi ro (bao nhiêu người bị ảnh hưởng nếu bản mới lỗi), chi phí hạ tầng (cần bao nhiêu máy chủ dư thừa), và tốc độ rollback (quay lui nhanh hay chậm). Không có chiến lược "tốt nhất" tuyệt đối — chỉ có chiến lược phù hợp nhất với bối cảnh của bạn.
Recreate — dừng cũ, bật mới
Đây là chiến lược đơn giản nhất và cũng nguyên thủy nhất: tắt toàn bộ phiên bản cũ, sau đó khởi động phiên bản mới. Ưu điểm là dễ hiểu, không cần phiên bản cũ và mới cùng tồn tại, phù hợp khi hai phiên bản không thể chạy song song (ví dụ thay đổi schema database không tương thích ngược). Nhược điểm rõ ràng: có downtime. Trong khoảng vài giây đến vài phút, hệ thống hoàn toàn không phục vụ. Chiến lược này chỉ chấp nhận được với ứng dụng nội bộ, công cụ admin, hoặc hệ thống có cửa sổ bảo trì được thông báo trước.
Rolling Update — thay thế dần từng phần
Đây là chiến lược mặc định của Kubernetes và là lựa chọn phổ biến nhất cho ứng dụng web hiện đại. Thay vì thay tất cả cùng lúc, bạn thay thế các instance (bản chạy) từng cái một hoặc từng nhóm nhỏ. Giả sử bạn có 10 pod đang chạy phiên bản v1: hệ thống sẽ tạo 1 pod v2, chờ nó sẵn sàng, tắt 1 pod v1, rồi lặp lại cho đến khi cả 10 pod đều là v2.
Ưu điểm nổi bật:
- Zero downtime — luôn có instance phục vụ trong suốt quá trình.
- Rollback dễ — nếu phát hiện lỗi giữa chừng, bạn có thể dừng quá trình cập nhật lại; số instance lỗi mới ở mức tối thiểu.
- Không cần nhân đôi hạ tầng — chỉ cần dư một chút dung lượng để tạo instance mới trong lúc chuyển đổi.
Blue-Green — hai môi trường song song
Bạn duy trì hai môi trường giống hệt nhau: Blue (đang phục vụ) và Green (đứng chờ). Bạn deploy phiên bản mới lên Green, kiểm thử kỹ trên môi trường thật nhưng chưa có traffic khách, rồi chuyển toàn bộ traffic từ Blue sang Green chỉ bằng thao tác đổi router/load balancer. Nếu có sự cố, chỉ cần chuyển ngược lại Blue — rollback gần như tức thì.
Đánh đổi: bạn cần gấp đôi hạ tầng trong thời gian chuyển đổi, và toàn bộ người dùng chuyển sang bản mới cùng lúc (rủi ro tập trung vào thời điểm switch).
Canary — thử nghiệm với một nhóm nhỏ
Lấy cảm hứng từ "chim hoàng yến trong mỏ than", canary cho phép bạn đưa phiên bản mới đến một tỷ lệ nhỏ người dùng trước (ví dụ 5%), quan sát các chỉ số (lỗi, độ trễ, tỷ lệ chuyển đổi đơn hàng), rồi tăng dần 25%, 50%, 100% nếu ổn. Đây là chiến lược an toàn nhất về mặt rủi ro vì sự cố (nếu có) chỉ ảnh hưởng phần nhỏ người dùng. Đổi lại, nó phức tạp hơn và đòi hỏi hệ thống giám sát (observability) tốt để "đọc" được tín hiệu từ nhóm canary.
Tình huống thực tế
Ví dụ 1: Tiki và bài học đêm Flash Sale
Giả sử đội kỹ thuật của một sàn TMĐT lớn tại Việt Nam (tương tự Tiki) chuẩn bị cho đợt sale 12/12 với dự kiến 200.000 người dùng đồng thời. Ban đầu, họ dùng chiến lược Recreate cho service tính giá khuyến mãi vì nó đơn giản. Trong một lần cập nhật giữa ngày, họ tắt service để deploy — mất 90 giây. Trong 90 giây đó, hàng nghìn đơn hàng bị lỗi "không tính được giá", khách bỏ giỏ hàng, và doanh thu ước tính thất thoát vài trăm triệu đồng chỉ trong hơn một phút.
Sau sự cố, họ chuyển service này sang Rolling Update trên Kubernetes với cấu hình maxUnavailable: 0, maxSurge: 2 — nghĩa là không được phép có instance nào ngừng phục vụ, luôn tạo trước 2 instance mới. Kết quả: các lần deploy sau đó trong giờ cao điểm không còn gây gián đoạn.
Bài học: Recreate rẻ và đơn giản, nhưng downtime trong giờ vàng có chi phí kinh doanh khổng lồ. Với dịch vụ doanh thu trực tiếp, zero-downtime không phải "nice to have" mà là bắt buộc.
Ví dụ 2: Một fintech Đông Nam Á dùng Blue-Green cho hệ thống thanh toán
Một công ty fintech giả định tại Singapore/Việt Nam vận hành cổng thanh toán xử lý khoảng 500 giao dịch/phút. Với thanh toán, một lỗi nhỏ ở bản mới có thể gây sai lệch số tiền — hậu quả nghiêm trọng và khó khắc phục. Họ chọn Blue-Green: deploy bản mới lên môi trường Green, chạy bộ smoke test tự động (thử các luồng thanh toán mẫu với tài khoản test), đội QA kiểm tra thủ công 30 phút trên Green, rồi mới chuyển traffic.
Một lần, sau khi switch sang Green, hệ thống giám sát báo tỷ lệ lỗi tăng vọt do một cấu hình kết nối ngân hàng bị sai. Đội trực chỉ mất 8 giây để chuyển router về Blue — người dùng gần như không cảm nhận được sự cố. Nếu dùng Rolling Update, việc rollback sẽ phải cập nhật lại từng instance, mất nhiều phút hơn trong khi lỗi vẫn đang ảnh hưởng khách hàng.
Bài học: Với hệ thống nhạy cảm cần rollback tức thì và cần môi trường kiểm thử giống production, Blue-Green đáng giá chi phí gấp đôi hạ tầng. Chi phí máy chủ dư nhỏ hơn nhiều so với chi phí một sự cố thanh toán.
Ví dụ 3: Grab-style super app dùng Canary cho tính năng gợi ý
Một siêu ứng dụng gọi xe/giao đồ ăn (tương tự Grab) muốn ra mắt thuật toán gợi ý quán ăn mới. Thuật toán này ảnh hưởng trực tiếp đến tỷ lệ đặt đơn — một thay đổi tốt có thể tăng doanh thu, nhưng một thay đổi tệ có thể khiến người dùng không tìm thấy món họ muốn. Họ không dám release cho toàn bộ hàng triệu người dùng ngay.
Họ dùng Canary: ban đầu chỉ 2% người dùng ở TP.HCM nhận thuật toán mới. Đội dữ liệu theo dõi chỉ số "conversion rate" (tỷ lệ mở app đến đặt đơn) trong 24 giờ. Bản mới cho thấy conversion tăng 3%, không có tăng lỗi hay độ trễ. Họ nâng dần lên 10%, 50%, rồi 100% trong vòng một tuần. Nếu chỉ số xấu đi ở bất kỳ bước nào, họ chỉ cần rút traffic canary về 0 — chỉ 2% người dùng từng bị ảnh hưởng.
Bài học: Canary lý tưởng khi bạn cần đo lường tác động thực tế của thay đổi, không chỉ kiểm tra "có lỗi hay không". Nó đòi hỏi observability tốt, nhưng cho phép ra quyết định dựa trên dữ liệu thật từ người dùng thật.
Hướng dẫn từng bước
Đây là quy trình tư duy để chọn và áp dụng một chiến lược triển khai:
Bước 1 — Xác định mức độ chịu đựng downtime. Hỏi: nếu hệ thống ngừng 60 giây, chuyện gì xảy ra? Nếu câu trả lời là "mất tiền/mất khách", loại bỏ Recreate ngay. Nếu là công cụ nội bộ dùng giờ hành chính, Recreate có thể chấp nhận được và tiết kiệm công sức.
Bước 2 — Đánh giá tính tương thích giữa hai phiên bản. Rolling Update và Canary yêu cầu v1 và v2 chạy song song được. Nếu bản mới thay đổi database schema không tương thích ngược, bạn cần hoặc tách migration thành nhiều bước (expand-contract), hoặc dùng Recreate/Blue-Green có kiểm soát.
Bước 3 — Cân nhắc ngân sách hạ tầng. Blue-Green cần gấp đôi tài nguyên tạm thời. Rolling chỉ cần dư một chút. Nếu bạn chạy trên cloud tính tiền theo giờ, chi phí Blue-Green trong 30 phút chuyển đổi thường không đáng kể; nhưng nếu hạ tầng on-premise cố định, gấp đôi máy có thể bất khả thi.
Bước 4 — Chuẩn bị health check và readiness probe. Mọi chiến lược zero-downtime đều dựa vào việc hệ thống biết instance mới đã "sẵn sàng nhận traffic" hay chưa. Trong Kubernetes, hãy cấu hình readinessProbe chính xác — nếu không, load balancer sẽ gửi traffic đến instance chưa khởi động xong và gây lỗi.
Bước 5 — Định nghĩa tiêu chí thành công và cơ chế rollback. Trước khi deploy, hãy quyết định: chỉ số nào cho biết bản mới "khỏe mạnh" (tỷ lệ lỗi < 0.1%, p99 latency < 300ms...) và hành động gì khi vượt ngưỡng. Với Canary, tự động hóa việc này (progressive delivery) là lý tưởng. Với Blue-Green, chuẩn bị sẵn nút "switch về Blue".
Bước 6 — Triển khai thử trên môi trường staging trước. Đừng bao giờ thử một chiến lược mới lần đầu tiên trên production. Chạy toàn bộ luồng deploy + rollback trên staging để đội quen tay.
Lỗi thường gặp & mẹo
Lỗi 1: Quên tính tương thích ngược khi Rolling Update. Vì v1 và v2 cùng chạy, nếu v2 đổi định dạng dữ liệu mà v1 không đọc được (hoặc ngược lại), bạn sẽ gặp lỗi ngẫu nhiên tùy request rơi vào phiên bản nào. Mẹo: luôn deploy theo nguyên tắc "backward compatible trước, xóa code cũ sau".
Lỗi 2: Readiness probe cấu hình sai gây downtime dù dùng Rolling. Nhiều đội tưởng chỉ cần chọn Rolling là có zero-downtime, nhưng nếu probe báo "sẵn sàng" trước khi app thực sự nhận request được, người dùng vẫn thấy lỗi. Mẹo: probe phải kiểm tra cả kết nối database/cache, không chỉ "process còn sống".
Lỗi 3: Blue-Green nhưng quên xử lý session và kết nối đang mở. Khi switch, các kết nối đang xử lý dở trên Blue có thể bị cắt đột ngột. Mẹo: dùng "connection draining" — cho load balancer chờ các request đang chạy trên Blue hoàn tất trước khi tắt hẳn.
Lỗi 4: Canary nhưng nhóm canary không đại diện. Nếu 5% traffic canary toàn là bot hoặc người dùng ở một khu vực đặc thù, chỉ số bạn đo sẽ đánh lừa. Mẹo: chọn nhóm canary ngẫu nhiên và đủ lớn để có ý nghĩa thống kê.
Mẹo tổng quát: Bắt đầu đơn giản. Nhiều startup Việt Nam ban đầu chỉ cần Rolling Update là đủ 90% nhu cầu. Chỉ nâng cấp lên Blue-Green hay Canary khi bạn thực sự có yêu cầu về rollback tức thì hoặc đo lường tác động. Đừng để sự phức tạp của công cụ vượt quá nhu cầu thực tế của sản phẩm.
Bài tập thực hành
- Phân loại tình huống. Với mỗi hệ thống sau, hãy chọn chiến lược phù hợp nhất và giải thích: (a) trang blog nội bộ công ty, (b) API thanh toán ngân hàng, (c) tính năng gợi ý sản phẩm mới trên app TMĐT, (d) service microservice xử lý gửi email không đồng bộ. Viết ra lý do dựa trên bốn yếu tố: downtime, rủi ro, chi phí, tốc độ rollback.
- Thiết kế cấu hình Rolling Update. Giả sử bạn có 8 instance. Hãy viết ra ý nghĩa của cấu hình
maxUnavailablevàmaxSurgemà bạn chọn cho một service quan trọng trong giờ cao điểm, và giải thích quá trình chuyển đổi sẽ diễn ra như thế nào.
- Kịch bản rollback. Bạn đang dùng Blue-Green. Sau khi switch sang Green 5 phút, tỷ lệ lỗi tăng từ 0.1% lên 4%. Hãy viết ra các bước xử lý của bạn theo thứ tự, bao gồm cả việc bạn sẽ điều tra nguyên nhân trước hay rollback trước.
- So sánh chi phí. Hệ thống của bạn chạy 20 instance, mỗi instance 0.5 USD/giờ. Ước tính chi phí hạ tầng dư thừa nếu chuyển đổi Blue-Green mất 40 phút, và so sánh với thiệt hại nếu Recreate gây downtime 3 phút trong giờ cao điểm bán được 50 triệu đồng/phút.
Tóm tắt
Deployment strategy là cách bạn thay thế phiên bản cũ bằng phiên bản mới, và lựa chọn này quyết định trải nghiệm người dùng lẫn mức độ an toàn của hệ thống. Bốn chiến lược cốt lõi bạn cần nắm:
- Recreate: dừng cũ, bật mới. Đơn giản nhưng có downtime — chỉ dùng cho hệ thống chấp nhận gián đoạn.
- Rolling Update: thay thế dần từng instance, zero-downtime, mặc định trong Kubernetes, phù hợp phần lớn ứng dụng web. Yêu cầu tương thích ngược giữa các phiên bản.
- Blue-Green: hai môi trường song song, rollback gần như tức thì, đổi lại cần gấp đôi hạ tầng tạm thời — lý tưởng cho hệ thống nhạy cảm cần switch nhanh.
- Canary: đưa bản mới đến nhóm nhỏ trước, đo lường rồi mở rộng dần, an toàn nhất về rủi ro nhưng đòi hỏi observability tốt.