3秒でわかる
サービスを止めずに新しいバージョンへ入れ替える手法。切り替えの前後でエラー応答が増えないことを条件に手順を組み立てます。
30秒図解
もう少し詳しく
どういうものか
ゼロダウンタイムデプロイは、稼働中のサービスを停止させずに新しいバージョンへ入れ替える手法の総称です。判断基準は単純で、切り替えの前後を通してエラー応答が増えないことです。古いプロセスを落としてから新しいプロセスを起動する素朴な手順では、その間の数秒から数十秒がそのまま停止時間になります。
なぜ必要か
24時間使われるサービスでは、深夜のメンテナンス時間を確保できません。1日に何度も出す運用に切り替えるほど、1回あたりの停止時間が積み上がります。停止させずに出せる状態を作ると、リリースが怖くなくなり、結果として1回の変更量が小さくなって障害も減ります。
具体例
代表的なやり方は次の3つです。ローリングは台数を分けて順に入れ替える方法、ブルーグリーンは新旧2系統を並べてロードバランサの向き先を切り替える方法、カナリアは新バージョンへ流す割合を少しずつ上げる方法です。
[ブルーグリーンの切り替え]
┌── blue v1 (現行) ──┐
利用者 ─ LB │ │ ← 向き先を green へ切り替える
└── green v2 (待機) ──┘
↑ <a href="/glossary/health-check" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">ヘルスチェック</a>が通ってから切り替える# ロードバランサから外してから止める、という順序が要点
<a href="/glossary/curl" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">curl</a> -X POST http://lb.internal/drain?node=app01
sleep 15 # <a href="/glossary/process-flow" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">処理</a>中の<a href="/glossary/http-request" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">リクエスト</a>を捌き切る
sudo systemctl restart app
curl -fsS http://app01:3000/health && curl -X POST http://lb.internal/enable?node=app01つまずきやすいところ
アプリ側の入れ替えだけを考えて、DBスキーマの変更で止めてしまう例が多く見られます。新旧のバージョンが同時に動く時間帯が必ずあるため、その間はどちらのコードでも動くスキーマである必要があります。列名の変更は、追加、両方書き込み、読み替え、削除の4段階に分けます。また、終了シグナルを受けたら即座に落ちる実装だと、処理中のリクエストが切られます。SIGTERMを受け取ってから接続を閉じるまでの猶予を設けます。
覚え方
止めない仕組みの本体は、新旧が同時に動く時間に耐えられるかどうかです。コードとスキーマの両方を、1つ前のバージョンと共存できる形で出す、と覚えておくと手順の設計を誤りません。
可用性を数字で語るときは、月あたりの許容停止時間に直すと判断しやすくなります。