ブルーグリーンデプロイメント - ダウンタイムゼロのリリース

14分 で読める | 2025.01.10

公式ドキュメント

ブルーグリーンデプロイメントとは

ブルーグリーンデプロイメントは、2つの同一環境(Blue/Green)を用意し、トラフィックを瞬時に切り替えるデプロイ手法です。ダウンタイムゼロでリリースでき、問題発生時は即座にロールバックできます。

flowchart TB
 LB["ロードバランサー"]

 subgraph Blue["Blue環境(現行)"]
 B1["サーバー 1"]
 B2["サーバー 2"]
 end

 subgraph Green["Green環境(新版)"]
 G1["サーバー 1"]
 G2["サーバー 2"]
 end

 LB -->|"100%"| Blue
 LB -.->|"0%"| Green

 style Blue fill:#4a9eff
 style Green fill:#48bb78

デプロイ戦略の比較

戦略ダウンタイムロールバックコスト複雑さ
ローリング最小遅い
ブルーグリーンゼロ即座
カナリアゼロ即座
A/Bテストゼロ即座

実装パターン

AWS ALB + ECS

// AWS CDKでの実装
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';

// Blue/Green用のターゲットグループ
const blueTargetGroup = new elbv2.ApplicationTargetGroup(this, 'Blue', {
 port: 80,
 protocol: elbv2.ApplicationProtocol.HTTP,
 targetType: elbv2.TargetType.IP,
 healthCheck: {
 path: '/health',
 interval: Duration.seconds(10),
 },
});

const greenTargetGroup = new elbv2.ApplicationTargetGroup(this, 'Green', {
 port: 80,
 protocol: elbv2.ApplicationProtocol.HTTP,
 targetType: elbv2.TargetType.IP,
 healthCheck: {
 path: '/health',
 interval: Duration.seconds(10),
 },
});

// CodeDeployによる自動切り替え
new codedeploy.EcsDeploymentGroup(this, 'DeploymentGroup', {
 service: ecsService,
 blueGreenDeploymentConfig: {
 blueTargetGroup,
 greenTargetGroup,
 listener: albListener,
 terminationWaitTime: Duration.minutes(10),
 },
 deploymentConfig: codedeploy.EcsDeploymentConfig.ALL_AT_ONCE,
});

Kubernetes

# Blue Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
 name: myapp-blue
 labels:
 app: myapp
 version: blue
spec:
 replicas: 3
 selector:
 matchLabels:
 app: myapp
 version: blue
 template:
 metadata:
 labels:
 app: myapp
 version: blue
 spec:
 containers:
 - name: myapp
 image: myapp:v1.0.0
 ports:
 - containerPort: 8080
---
# Service(切り替え対象)
apiVersion: v1
kind: Service
metadata:
 name: myapp
spec:
 selector:
 app: myapp
 version: blue # blueまたはgreenに切り替え
 ports:
 - port: 80
 targetPort: 8080

切り替えスクリプト

#!/bin/bash
# blue-green-switch.sh

CURRENT=$(kubectl get svc myapp -o jsonpath='{.spec.selector.version}')

if [ "$CURRENT" = "blue" ]; then
 NEW_VERSION="green"
else
 NEW_VERSION="blue"
fi

echo "Switching from $CURRENT to $NEW_VERSION"

# ヘルスチェック
kubectl rollout status deployment/myapp-$NEW_VERSION

# 切り替え実行
kubectl patch svc myapp -p "{\"spec\":{\"selector\":{\"version\":\"$NEW_VERSION\"}}}"

echo "Switch complete. Now serving: $NEW_VERSION"

ポイント: 切り替え前に新環境のヘルスチェックを複数回実施し、80%以上成功していることを確認してからトラフィックを移行しましょう。

ヘルスチェックとロールバック

interface DeploymentConfig {
 healthCheckUrl: string;
 healthCheckInterval: number;
 healthCheckThreshold: number;
 rollbackOnFailure: boolean;
}

async function performBlueGreenSwitch(config: DeploymentConfig) {
 const newEnvironment = await getInactiveEnvironment();

 // 新環境のヘルスチェック
 let healthyCount = 0;
 for (let i = 0; i < config.healthCheckThreshold; i++) {
 const isHealthy = await checkHealth(newEnvironment, config.healthCheckUrl);
 if (isHealthy) healthyCount++;
 await sleep(config.healthCheckInterval);
 }

 if (healthyCount < config.healthCheckThreshold * 0.8) {
 if (config.rollbackOnFailure) {
 await rollback();
 throw new Error('Health check failed, rolled back');
 }
 throw new Error('Health check failed');
 }

 // トラフィック切り替え
 await switchTraffic(newEnvironment);

 // 旧環境の保持(ロールバック用)
 console.log('Keeping old environment for 30 minutes');
 setTimeout(() => terminateOldEnvironment(), 30 * 60 * 1000);
}

注意: ブルーグリーンデプロイメントでのDB変更は特に注意が必要です。後方互換性のないスキーマ変更は、旧環境へのロールバックを不可能にします。

データベースマイグレーション

ブルーグリーンデプロイメントでのDB変更は注意が必要です。

flowchart TB
 subgraph Phase1["フェーズ1: 後方互換スキーマ追加"]
 DB1["既存スキーマ"] --> DB2["新カラム追加<br/>(NULL許容)"]
 end

 subgraph Phase2["フェーズ2: アプリ切り替え"]
 App1["旧アプリ"] --> App2["新アプリ<br/>(両方対応)"]
 end

 subgraph Phase3["フェーズ3: クリーンアップ"]
 DB3["旧カラム削除"]
 end

 Phase1 --> Phase2 --> Phase3
-- フェーズ1: 後方互換性のある変更
ALTER TABLE users ADD COLUMN new_email VARCHAR(255);

-- フェーズ2: データ移行(バックグラウンド)
UPDATE users SET new_email = email WHERE new_email IS NULL;

-- フェーズ3: 旧カラム削除(アプリ切り替え後)
ALTER TABLE users DROP COLUMN email;
ALTER TABLE users RENAME COLUMN new_email TO email;

実践メモ: セッション情報はアプリサーバーではなく外部セッションストア(Redis等)に保存しましょう。環境切り替え時にセッションが失われません。

現場での注意点

  1. セッション管理 - 外部セッションストア(Redis)を使用
  2. キャッシュ無効化 - デプロイ時にキャッシュをクリア
  3. コスト - 2環境分のリソースが必要

関連記事

まとめ

ブルーグリーンデプロイメントは、ダウンタイムゼロと即座のロールバックを実現する強力な手法です。コストは高いですが、本番環境の安定性を重視するシステムには最適です。

参考リソース

← 一覧に戻る
PR
PR
PR
PR