デプロイ方式とは、稼働中のシステムを旧版から新版へ入れ替える進め方のことで、代表的なものは一括・ローリング・ブルーグリーン・カナリアの4つ、これに機能フラグの併用を加えた5つです。 違いは「追加で何台いるか」「止まる時間があるか」「どうやって元に戻すか」「新版と旧版が同時に動くか」の4点に集まります。

この記事は方式を選ぶところに絞り、5方式の比較表、方式ごとのシーケンス図、Kubernetes のマニフェスト、台数と所要時間の計算、切り戻し判断基準の記入テンプレート、新旧が同時に動く間のデータベース変更の順番をまとめます。

確認環境(2026-10-06):Ubuntu 24.04。マニフェストは kubernetes-validate 1.36.0(Kubernetes 1.36 のスキーマ)の厳密モードで検査、計算例は Python 3.11.15 で実行、SQL は PostgreSQL 16.15 で実行、図は @mermaid-js/mermaid-cli 11.14.0 で描画できることを確認しています。Kubernetes の既定値は公式ドキュメントの Deployments のページの記載です。

この記事の結論

  • 切り戻しの速さを優先するなら、ブルーグリーン。 振り分け先を戻すだけで旧版に戻ります。そのかわり、切り替えの間はふだんの2倍の台数を使います。
  • 影響範囲を絞って確かめたいなら、カナリア。 一部のリクエストだけを新版に流し、数値を見てから広げます。
  • 追加の台数を抑えたいなら、ローリング。 数台ずつ入れ替えるので、追加は1台からで済みます。
  • 止めてよい時間帯があり、新旧を同時に動かしたくないなら、一括。 仕組みがいちばん単純です。
  • 「置く」と「見せる」を分けたいなら、機能フラグを併用。 デプロイは上のどれかで行い、公開はフラグで切り替えます。

デプロイ方式の選び方の早見表

優先したいこと 選ぶ方式 理由
切り戻しを数秒〜数十秒で終えたい ブルーグリーン 旧版を動かしたまま残すので、振り分け先を戻すだけ
新版の影響を一部の利用者にとどめて確かめたい カナリア 新版に流す割合を 10% などに絞れる
追加の台数を少なくしたい ローリング 追加は maxSurge で指定した台数だけ
新旧の混在を避けたい(データ形式が大きく変わるなど) 一括 旧版を止めてから新版を起動する
利用者への公開日をデプロイ日と別にしたい 機能フラグ併用 デプロイ後にフラグで公開する
まず標準の方法で始めたい ローリング Kubernetes の Deployment の既定の方式

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「デプロイ方式の種類と違い|ブルーグリーン・カナリア・ローリング比較」

5方式の比較表(必要台数・停止時間・切り戻し・新旧混在)

ふだん N 台で動かしているシステムを入れ替える場合で比べます。

方式 入れ替え中の最大台数 停止時間 切り戻し手順 新旧の混在
一括(Recreate) N あり(旧版の停止から新版の準備完了まで) 旧版を一括でデプロイし直す(もう一度止まる) なし
ローリング N + maxSurge なし(maxUnavailable の分だけ処理できる台数が減る) 旧版へ向けてもう一度ローリングする あり(入れ替えの間ずっと)
ブルーグリーン 2N なし 振り分け先を旧版へ戻す アプリは切り替えの瞬間だけ。DB は共有するのであり
カナリア N + カナリアの台数 なし 新版の割合を 0% に戻す(カナリアを 0 台にする) あり(意図して混在させる)
機能フラグ併用 デプロイに使った方式と同じ なし フラグをオフに戻す(再デプロイなし) 同じ版の中に新旧のコードが同居

表計算ソフトに貼れる形(タブ区切り)です。

方式  入れ替え中の最大台数  停止時間    切り戻し手順  新旧の混在
一括(Recreate)    N   あり  旧版を一括でデプロイし直す   なし
ローリング   N + maxSurge    なし  旧版へ向けてもう一度ローリング あり
ブルーグリーン 2N  なし  振り分け先を旧版へ戻す アプリは切り替えの瞬間だけ・DBはあり
カナリア    N + カナリアの台数 なし  新版の割合を0%に戻す あり
機能フラグ併用 デプロイ方式と同じ   なし  フラグをオフに戻す   同じ版に新旧のコードが同居

「新旧の混在」が「あり」の方式では、新版と旧版が同じデータベースを同時に読み書きします。 この点が、後半の「DB 変更は追加→移行→削除の順に分ける」につながります。

デプロイとリリースの違い

方式を選ぶ前に、2つの言葉を分けておくと整理しやすくなります。

言葉 意味 切り替えるもの 元に戻す方法
デプロイ 新版のプログラムを稼働環境に置いて動かすこと サーバー上のプログラム 旧版を置き直す、振り分け先を戻す
リリース 新しい機能を利用者が使える状態にすること 利用者に見えるかどうか 振り分けの割合やフラグを戻す

一括とローリングでは、デプロイが終わると同時にリリースも終わります。ブルーグリーンは「新版を起動する(デプロイ)」と「振り分け先を切り替える(リリース)」が別の操作になり、カナリアはリリースを割合で少しずつ進め、機能フラグはリリースをプログラムの外の設定に移します。

方式 デプロイとリリースの関係
一括 同時
ローリング 同時(台ごとに順に)
ブルーグリーン 分かれる(起動 → 確認 → 切り替え)
カナリア 分かれる(起動 → 割合を段階的に上げる)
機能フラグ併用 分かれる(デプロイ後、好きな日時に公開)

一括デプロイ(Recreate)

旧版をすべて止めてから、新版をすべて起動します。新旧が同時に動かないので、データ形式が大きく変わる変更や、夜間に止められる社内システムに向きます。

sequenceDiagram
    participant U as 利用者
    participant LB as 振り分け
    participant V1 as 旧版(全台)
    participant V2 as 新版(全台)
    U->>LB: リクエスト
    LB->>V1: 旧版が応答
    Note over V1: 旧版をすべて停止
    U->>LB: リクエスト
    LB--xU: 応答できない(停止時間)
    Note over V2: 新版をすべて起動
    U->>LB: リクエスト
    LB->>V2: 新版が応答

Kubernetes では strategy.type を Recreate にします。公式ドキュメントには、Recreate では新しい Pod を作る前に既存の Pod がすべて終了されると書かれています。

# 一括(Recreate):旧版をすべて止めてから新版を起動する
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 10
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.1.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080

切り戻しは、イメージを旧版に戻して同じ操作をもう一度行います。切り戻しでも同じだけ止まるので、止めてよい時間を「入れ替え+切り戻し」の2回分で見ておきます。

ローリングデプロイ

数台ずつ振り分けから外し、新版に入れ替えて戻す、を繰り返します。追加の台数が少なく、止まる時間もありません。 Kubernetes の Deployment は、何も指定しなければこの方式(RollingUpdate)です。

sequenceDiagram
    participant LB as 振り分け
    participant A as 1〜3台目
    participant B as 4〜6台目
    participant C as 7〜10台目
    Note over A,C: 全台が旧版
    LB-->>A: 振り分けから外す
    Note over A: 新版に入れ替え
    A->>LB: 準備完了(戻す)
    Note over A,C: 新版と旧版が混在
    LB-->>B: 振り分けから外す
    Note over B: 新版に入れ替え
    B->>LB: 準備完了(戻す)
    LB-->>C: 振り分けから外す
    Note over C: 新版に入れ替え
    C->>LB: 準備完了(戻す)
    Note over A,C: 全台が新版
# ローリング:少しずつ入れ替える(Deployment の既定の方式)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 10
  minReadySeconds: 10
  progressDeadlineSeconds: 600
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.1.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
項目 意味 既定値(公式ドキュメントの記載)
maxSurge 指定した台数を超えて作ってよい Pod の数 25%(割合は切り上げで台数に直す)
maxUnavailable 入れ替え中に使えなくてよい Pod の数 25%(割合は切り捨てで台数に直す)
minReadySeconds 準備完了のあと、利用可能と見なすまで待つ秒数 0
progressDeadlineSeconds 進まないときに「進行していない」と報告するまでの秒数 600
revisionHistoryLimit 切り戻し用に残す以前の ReplicaSet の数 10

切り戻しは次のコマンドです。直前の版へ向けて、同じローリングがもう一度走ります。

kubectl rollout undo deployment/web
kubectl rollout status deployment/web

切り戻しにも入れ替えと同じだけ時間がかかる点が、ブルーグリーンとの違いです。

ブルーグリーンデプロイ

旧版(ブルー)と同じ台数の新版(グリーン)を横に並べ、確認が済んだら振り分け先を一度に切り替えます。旧版を動かしたまま残すので、戻すときも振り分け先を変えるだけです。

sequenceDiagram
    participant U as 利用者
    participant LB as 振り分け
    participant B as ブルー(旧版10台)
    participant G as グリーン(新版10台)
    U->>LB: リクエスト
    LB->>B: 旧版が応答
    Note over G: 新版を10台起動し、内部から動作確認
    Note over LB: 振り分け先をグリーンへ切り替え
    U->>LB: リクエスト
    LB->>G: 新版が応答
    Note over B: しばらく残す(切り戻し用)
    alt 問題が見つかった
        Note over LB: 振り分け先をブルーへ戻す
        LB->>B: 旧版が応答
    else 問題なし
        Note over B: ブルーを片付ける
    end

Kubernetes では、Deployment を2つ作り、Service の selector を書き換えて切り替える形にできます。

# ブルーグリーン:旧版(blue)と新版(green)を同じ台数で並べ、Service の selector で切り替える
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-blue
spec:
  replicas: 10
  selector:
    matchLabels:
      app: web
      color: blue
  template:
    metadata:
      labels:
        app: web
        color: blue
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.0.0
          ports:
            - containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-green
spec:
  replicas: 10
  selector:
    matchLabels:
      app: web
      color: green
  template:
    metadata:
      labels:
        app: web
        color: green
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.1.0
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
    color: blue   # ここを green に書き換えると切り替わる。blue に戻せば切り戻し
  ports:
    - port: 80
      targetPort: 8080

切り替えと切り戻しは、Service の selector を書き換えるだけです。コマンドの形は、公式ドキュメントの Deployments のページにある kubectl patch・kubectl scale・kubectl rollout の書き方に合わせています。

# 切り替え(グリーンへ)
kubectl patch service/web -p '{"spec":{"selector":{"app":"web","color":"green"}}}'

# 切り戻し(ブルーへ)
kubectl patch service/web -p '{"spec":{"selector":{"app":"web","color":"blue"}}}'

切り替えのあと、ブルーをいつまで残すかを先に決めておきます(例:翌営業日の正午まで)。残している間は2倍の台数を使います。

カナリアリリース

新版を少数だけ起動し、一部のリクエストだけを流して、エラー率や応答時間を旧版と見比べます。基準を満たしたら割合を上げ、外れたら 0% に戻します。

sequenceDiagram
    participant U as 利用者
    participant LB as 振り分け
    participant S as 安定版(旧版)
    participant K as カナリア(新版)
    Note over K: 新版を1台だけ起動
    U->>LB: リクエスト 100件
    LB->>S: 90件
    LB->>K: 10件
    Note over LB,K: エラー率と応答時間を見比べる
    alt 基準を満たす
        Note over LB: 新版の割合を 50% → 100% へ
        LB->>K: すべて新版へ
    else 基準を外れた
        Note over LB: 新版の割合を 0% に戻す
        LB->>S: すべて旧版へ
    end

Kubernetes の公式ドキュメント(Managing Workloads)には、track: stable と track: canary のラベルを付けた2つの Deployment を作り、Service の selector には track を書かずに両方へ振り分ける例が載っています。同じ考え方で、安定版9台・カナリア1台にしたものが次のマニフェストです。

# カナリア:安定版 9 台に新版 1 台を混ぜる(Service は track を見ずに両方へ振り分ける)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-stable
spec:
  replicas: 9
  selector:
    matchLabels:
      app: web
      track: stable
  template:
    metadata:
      labels:
        app: web
        track: stable
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.0.0
          ports:
            - containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
      track: canary
  template:
    metadata:
      labels:
        app: web
        track: canary
    spec:
      containers:
        - name: web
          image: registry.example.com/web:1.1.0
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web      # track を書かないので stable と canary の両方が対象になる
  ports:
    - port: 80
      targetPort: 8080

この形では、新版に流れる割合は台数の比で決まります(9台と1台なら約 10%)。1% のような細かい割合にしたいときは、台数の比ではなく、振り分け側で重みを指定できる仕組みを使います。

# 広げる:カナリアを増やし、安定版を減らす
kubectl scale deployment/web-canary --replicas=5
kubectl scale deployment/web-stable --replicas=5

# 切り戻し:カナリアを 0 台にする
kubectl scale deployment/web-canary --replicas=0
kubectl scale deployment/web-stable --replicas=10

機能フラグの併用

機能フラグ(フィーチャーフラグ)は、新しい機能をオフの状態でデプロイしておき、設定の切り替えで公開する方法です。デプロイそのものは、ここまでの4方式のどれかで行います。

sequenceDiagram
    participant D as 開発者
    participant P as 稼働環境
    participant F as フラグ設定
    participant U as 利用者
    D->>P: 新機能をオフのままデプロイ
    U->>P: リクエスト
    P->>F: 新機能はオンか
    F-->>P: オフ
    P-->>U: これまでの画面
    D->>F: オンに変更(リリース)
    U->>P: リクエスト
    P->>F: 新機能はオンか
    F-->>P: オン
    P-->>U: 新しい画面
    Note over D,F: 問題があればフラグをオフに戻す(再デプロイなし)
向いている変更 向かない変更
画面や処理の追加など、if で分けられる機能 ランタイムやライブラリの版上げ
公開日が決まっている機能 テーブル構造の変更そのもの
一部の利用者から先に見せたい機能 起動時にしか読まれない設定の変更

フラグで戻せるのは、フラグで囲んだ範囲だけです。 プログラム全体に関わる変更は、デプロイ方式の切り戻しで戻します。

必要台数と所要時間の計算例

ふだん10台、1台の起動から準備完了まで60秒、旧版が処理中のリクエストを終えて止まるまで30秒、カナリアの1段階で様子を見る時間を600秒とした例です。数値はすべて例で、自分のシステムの値に書き換えて使います。

import math

def rolling_plan(n, max_surge="25%", max_unavailable="25%"):
    """Kubernetes の既定と同じ丸め(maxSurge は切り上げ、maxUnavailable は切り捨て)"""
    def to_abs(v, up):
        if isinstance(v, str) and v.endswith("%"):
            x = n * int(v[:-1]) / 100
            return math.ceil(x) if up else math.floor(x)
        return int(v)
    return to_abs(max_surge, True), to_abs(max_unavailable, False)

def rolling_rounds(n, surge, unavail):
    """1 巡 = 「新版を起動して準備完了になるまで」として、何巡で入れ替わるかを数える"""
    old, new_ready, rounds, peak, low = n, 0, 0, n, n
    while new_ready < n:
        # 使える台数が n - unavail を下回らない範囲で旧版を止める
        stop = min(old, max(0, old + new_ready - (n - unavail)))
        old -= stop
        low = min(low, old + new_ready)
        # 合計が n + surge を超えない範囲で新版を起動する
        start = min(n - new_ready, (n + surge) - (old + new_ready))
        peak = max(peak, old + new_ready + start)
        new_ready += start
        rounds += 1
    return rounds, peak, low

N = 10          # ふだんの台数
BOOT = 60       # 1 台が起動して準備完了になるまでの秒数(例)
STOP = 30       # 旧版が処理中のリクエストを終えて止まるまでの秒数(例)
WATCH = 600     # カナリアの 1 段階で様子を見る秒数(例)

print("方式\t最大台数\t追加台数\t所要時間(秒)\t停止時間(秒)")
print(f"一括\t{N}\t0\t{STOP + BOOT}\t{STOP + BOOT}")
for ms, mu in [("25%", "25%"), (1, 0), ("100%", 0)]:
    s, u = rolling_plan(N, ms, mu)
    r, peak, low = rolling_rounds(N, s, u)
    print(f"ローリング(maxSurge={ms},maxUnavailable={mu})\t{peak}\t{peak - N}\t{r * BOOT}\t0(最少{low}台で処理)")
print(f"ブルーグリーン\t{2 * N}\t{N}\t{BOOT}\t0")
stages = [10, 50, 100]
print(f"カナリア({'→'.join(str(x) + '%' for x in stages)})\t{N + 1}\t1\t{BOOT + WATCH * (len(stages) - 1) + BOOT * 2}\t0")

print()
print("台数\tmaxSurge=25%\tmaxUnavailable=25%\t巡数\t最大台数\t最少台数")
for n in [2, 3, 4, 10, 20]:
    s, u = rolling_plan(n)
    if s == 0 and u == 0:
        print(n, s, u, "進まない", sep="\t"); continue
    r, peak, low = rolling_rounds(n, s, u)
    print(n, s, u, r, peak, low, sep="\t")
方式  最大台数    追加台数    所要時間(秒) 停止時間(秒)
一括  10  0   90  90
ローリング(maxSurge=25%,maxUnavailable=25%)  13  3   120 0(最少8台で処理)
ローリング(maxSurge=1,maxUnavailable=0)  11  1   600 0(最少10台で処理)
ローリング(maxSurge=100%,maxUnavailable=0)   20  10  60  0(最少10台で処理)
ブルーグリーン 20  10  60  0
カナリア(10%→50%→100%)  11  1   1380    0

台数  maxSurge=25%    maxUnavailable=25%  巡数  最大台数    最少台数
2   1   0   2   3   2
3   1   0   3   4   3
4   1   1   2   5   3
10  3   2   2   13  8
20  5   5   2   25  15

ローリングの所要時間は「1巡で起動できる台数ずつ進む」とした単純なモデルです。カナリアは、起動60秒+観察600秒+50%への入れ替え60秒+観察600秒+100%への入れ替え60秒で、1台増やしてから1台減らす進め方を前提にしています。

読み取れること 数字
ローリングは、追加を1台に絞ると時間が延びる maxSurge=1 で 600秒、既定の 25% で 120秒
ローリングで maxSurge を 100% にすると、台数も時間もブルーグリーンと同じになる 最大20台・60秒
既定の 25% のままでは、処理できる台数が一時的に減る 10台構成で最少8台
カナリアは台数は少ないが、観察の時間がそのまま所要時間になる 1380秒のうち 1200秒が観察

新旧が同時に動く間のDB変更は「追加→移行→削除」に分ける

ローリング・カナリアでは入れ替えの間、ブルーグリーンでも切り替えの前後と切り戻しに備える間、新版と旧版が同じデータベースを使います。 そこで、テーブルの変更は「どちらの版から見ても動く」形で3回に分けます。

手順 DB の変更 合わせてデプロイする版 旧版から見て
1. 追加 新しい列(やテーブル)を足す まだ変えない そのまま動く
2. 移行 既存の行を新しい列へ写す 両方の列に書き、新しい列を読む版 そのまま動く
3. 削除 以前の列を消す 以前の列を使わない版が全台に行き渡ってから 旧版はもう残っていない

会員テーブルの列名 tel を phone に変える例を、PostgreSQL 16 で流した結果です。

CREATE TABLE members (id int PRIMARY KEY, name text NOT NULL, tel text);
INSERT INTO members VALUES (1,'山田 太郎','000-0000-0001'),(2,'佐藤 花子','000-0000-0002');

-- 止まる例:新旧が混在している間に、列名を直接変える
BEGIN;
ALTER TABLE members RENAME COLUMN tel TO phone;
SELECT id, name, tel FROM members WHERE id = 1;   -- 旧版が発行する SQL
ROLLBACK;
ERROR:  column "tel" does not exist
LINE 1: SELECT id, name, tel FROM members WHERE id = 1;
                         ^

列名を一度に変えると、まだ残っている旧版の SQL がこのエラーで止まります。3つに分けると次のようになります。

-- 手順1 追加:新しい列を足す(旧版はそのまま動く)
ALTER TABLE members ADD COLUMN phone text;
SELECT id, name, tel FROM members WHERE id = 1;   -- 旧版が発行する SQL

-- 手順2 移行:両方の列に書く版をデプロイし、既存の行を写す
INSERT INTO members (id, name, tel, phone) VALUES (3,'鈴木 次郎','000-0000-0003','000-0000-0003');
UPDATE members SET phone = tel WHERE phone IS NULL;
SELECT count(*) AS 未移行 FROM members WHERE phone IS DISTINCT FROM tel;
SELECT id, name, phone FROM members ORDER BY id;  -- 新版が発行する SQL

-- 手順3 削除:旧版が1台も残っていないことを確かめてから列を消す
ALTER TABLE members DROP COLUMN tel;
ALTER TABLE
 id |   name    |      tel      
----+-----------+---------------
  1 | 山田 太郎 | 000-0000-0001
(1 row)

INSERT 0 1
UPDATE 2
 未移行 
--------
      0
(1 row)

 id |   name    |     phone     
----+-----------+---------------
  1 | 山田 太郎 | 000-0000-0001
  2 | 佐藤 花子 | 000-0000-0002
  3 | 鈴木 次郎 | 000-0000-0003
(3 rows)

ALTER TABLE

手順3を別のデプロイに分けておくと、手順2までは旧版へ切り戻せます。 列を消したあとは旧版に戻せなくなるので、「削除」は切り戻しの期限が過ぎてから行います。

DB の変更 新旧混在のまま進められるか 進め方
列・テーブルの追加(NULL 可、または既定値あり) 進められる 手順1だけで済む
列名の変更 分ければ進められる 追加→移行→削除
列の型の変更 分ければ進められる 新しい型の列を追加→移行→削除
NOT NULL の追加 分ければ進められる 新版が必ず値を入れるようにしてから制約を付ける
列・テーブルの削除 最後に行う どの版も使っていないことを確かめてから

方式ごとの切り戻し手順と、判断基準の記入テンプレート

方式 切り戻しの操作 かかる時間の目安 先に決めておくこと
一括 旧版を一括でデプロイし直す 入れ替えと同じ(上の例で90秒、その間は止まる) 止めてよい時間を2回分で確保
ローリング kubectl rollout undo 入れ替えと同じ(上の例で120〜600秒) 残す履歴の数(revisionHistoryLimit)
ブルーグリーン 振り分け先を旧版へ戻す 振り分けの切り替えにかかる時間 旧版を残す期限
カナリア 新版の割合を 0% にする 振り分けの切り替えにかかる時間 各段階の割合と観察時間
機能フラグ併用 フラグをオフにする 設定が反映されるまでの時間 フラグの担当者と確認方法

切り戻すかどうかは、デプロイの前に数値で決めておきます。 当日に迷う時間を減らすための記入テンプレートです。

## 切り戻し判断基準(デプロイ前に記入)

- 対象:
- デプロイ方式:
- 切り戻しの操作:
- 切り戻しにかかる時間:
- 切り戻しができなくなる時点(例:以前の列を削除したあと):
- 判断する人:   代わりの人:

| No | 見る指標 | ふだんの値 | 切り戻す基準 | 見る期間 | 確認方法 |
|---|---|---|---|---|---|
| 1 | エラー率(5xx) |  |  |  |  |
| 2 | 応答時間(95パーセンタイル) |  |  |  |  |
| 3 | 主要な操作の成功数 |  |  |  |  |
| 4 | 問い合わせ件数 |  |  |  |  |

- 1つでも基準に当たったら切り戻す/  個以上で切り戻す:
- 基準に当たらないが迷うときの扱い(例:割合を上げずにもう30分見る):

記入例(架空の備品予約システム、カナリアで公開する場合)です。数値は例です。

No 見る指標 ふだんの値 切り戻す基準 見る期間 確認方法
1 エラー率(5xx) 0.1% 新版が 1% を超える 各段階 10分 監視画面で新版と旧版を並べる
2 応答時間(95パーセンタイル) 400ms 新版が旧版の 1.5倍を超える 各段階 10分 監視画面
3 予約登録の成功数 1分あたり 20件 新版側で 5分間 0件 各段階 10分 アプリのログ集計
4 問い合わせ件数 1時間あたり 1件 同じ内容が 3件届く 公開後 2時間 問い合わせ窓口と共有
No  見る指標    ふだんの値   切り戻す基準  見る期間    確認方法
1   エラー率(5xx)   0.1%    新版が1%を超える   各段階10分  監視画面で新版と旧版を並べる
2   応答時間(95パーセンタイル) 400ms   新版が旧版の1.5倍を超える  各段階10分  監視画面
3   予約登録の成功数    1分あたり20件    新版側で5分間0件   各段階10分  アプリのログ集計
4   問い合わせ件数 1時間あたり1件    同じ内容が3件届く   公開後2時間  問い合わせ窓口と共有

似た言葉との違いと、条件から選ぶ判断表

言葉 デプロイ方式との関係
A/B テスト 振り分けの仕組みはカナリアと似ていますが、目的が違います。カナリアは「新版が安定して動くか」、A/B テストは「どちらの案が利用者に選ばれるか」を見ます
ダークローンチ 利用者には見せずに新版を稼働環境で動かすこと。機能フラグをオフにしたデプロイがこれに当たります
イミュータブルな入れ替え 動いているサーバーを書き換えず、新しいサーバーを作って置き換える考え方。ブルーグリーンはこの考え方に沿っています
ローリング再起動 版は変えずに、順番に再起動すること。進め方はローリングデプロイと同じです
条件 選ぶ方式
止めてよい時間帯がある。新旧の混在を避けたい 一括
止められない。台数に余裕が少ない ローリング(maxSurge を小さく)
止められない。切り戻しを最優先にしたい。一時的に2倍の台数を用意できる ブルーグリーン
止められない。新版の影響が読みきれないので少しずつ確かめたい。新旧を比べる監視がある カナリア
公開日を別に決めたい。画面や処理の追加である いずれかの方式+機能フラグ
テーブルの列名や型が変わる どの方式でも、DB 変更を追加→移行→削除に分ける

確かめて分かったこと

  • 既定の 25% は、台数が少ないと 0 台や 1 台に丸まります。 maxSurge は切り上げ、maxUnavailable は切り捨てなので、2台・3台の構成では「追加1台・使えなくてよい台数0」になり、処理できる台数は減りません。4台以上になると maxUnavailable が1以上になり、入れ替え中に処理できる台数が減ります。
  • ローリングで maxSurge を 100%、maxUnavailable を 0 にすると、最大台数も所要時間もブルーグリーンと同じ数字になりました。 違いは、切り替えを人の判断で止められるかどうかと、切り戻しが振り分けの変更だけで済むかどうかです。
  • カナリアの所要時間のほとんどは観察の時間でした。 上の例では 1380秒のうち 1200秒です。段階の数と観察時間を決めることが、そのまま所要時間の見積もりになります。
  • マニフェストの項目名の書き間違いは、厳密モードの検査で見つかります。 maxSurge を maxSurgee と書いたファイルを検査すると、次のメッセージが出ました。
ERROR bad.yaml did not validate for resource deployment/web against version 1.36: spec.strategy.rollingUpdate: Additional properties are not allowed ('maxSurgee' was unexpected)
  • 列名を直接変えると、旧版の SQL は column "tel" does not exist で止まります。 列を足すだけなら旧版の SQL はそのまま動くので、最初の一歩は必ず「追加」にします。

よくある質問

Q. ブルーグリーンデプロイとカナリアリリースの違いは? A. 切り替え方が違います。ブルーグリーンは全リクエストを一度に新版へ切り替え、カナリアは一部のリクエストから段階的に新版へ移します。切り戻しはどちらも振り分けを戻すだけですが、ブルーグリーンは2倍の台数、カナリアは新旧を見比べる監視が必要です。

Q. ローリングアップデートとブルーグリーンの違いは? A. 追加の台数と切り戻しの速さが違います。ローリングは少ない追加台数で順に入れ替え、戻すときももう一度ローリングします。ブルーグリーンは同じ台数をもう1組用意し、戻すときは振り分け先を変えるだけです。

Q. デプロイとリリースの違いは? A. デプロイは新版を稼働環境に置くこと、リリースは利用者が使える状態にすることです。ブルーグリーン・カナリア・機能フラグは、この2つを別の操作に分けられます。

Q. カナリアリリースで切り戻しできないときは? A. まず、データベースの変更が旧版と合わなくなっていないかを確かめます。列の削除や列名の変更を新版のデプロイと同時に行うと、旧版が動かなくなります。変更を追加→移行→削除に分け、削除は切り戻しの期限のあとに回します。

Q. どの方式から始めればよいですか? A. Kubernetes を使っているなら、既定のローリングから始められます。切り戻しの時間が課題になったらブルーグリーン、影響範囲を絞りたくなったらカナリアを検討します。

まとめ

  • デプロイ方式は、一括・ローリング・ブルーグリーン・カナリアの4つと、機能フラグの併用で整理できます。
  • 比べる軸は、必要台数・停止時間・切り戻し手順・新旧混在の4つです。
  • 切り戻しの速さならブルーグリーン、影響範囲を絞るならカナリア、追加台数を抑えるならローリングを選びます。
  • デプロイ(置く)とリリース(見せる)を分けると、公開の判断と切り戻しがしやすくなります。
  • 新旧が同時に動く間の DB 変更は、追加→移行→削除の順に分けます。 削除は切り戻しの期限のあとです。
  • 切り戻す基準は、デプロイの前に数値で書いておきます。

参考・出典

  • Kubernetes Documentation「Deployments」 https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
  • Kubernetes Documentation「Managing Workloads」(Canary deployments) https://kubernetes.io/docs/concepts/workloads/management/

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「デプロイ方式の種類と違い|ブルーグリーン・カナリア・ローリング比較」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?