ECS のローリング・ブルー/グリーン・リニア・カナリアの違い ── ALB 配下のサービスを止めずに入れ替える
記事の「実践」を 1 項目ずつ進めるためのページです。AWS マネジメントコンソールで操作したら、右の一覧にチェックを入れてください。チェックはこのブラウザに保存されます。
前提条件
- リージョン:
ap-northeast-1(東京) - 以下のリソースが作成済みであること
まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。
| リソース種別 | リソース名 | 内容 | 作り方の参考 |
|---|---|---|---|
| VPC | soa-ecs-vpc | パブリックサブネット 2 つ(ap-northeast-1a / ap-northeast-1c) | Amazon VPC で仮想ネットワークを構築しサブネットを設定する |
| Application Load Balancer | soa-ecs-alb | インターネット向け。リスナー HTTP:80 で soa-ecs-tg に転送 | ─ |
| ターゲットグループ | soa-ecs-tg | ターゲットタイプ IP、ヘルスチェックのパス /、登録解除の遅延 30 秒 | ─ |
| ECS クラスター | soa-ecs-cluster | Fargate | Amazon ECS と Fargate でコンテナを動かす |
| タスク定義 | soa-web(リビジョン 1) | Apache httpd のコンテナ 1 つ(0.25 vCPU / 0.5 GB)。環境変数 APP_VERSION の値(v1)をページに表示する | 同上 |
| ECS サービス | soa-web-svc | 必要なタスク数 2、ローリング更新、最小実行タスク 100%・最大実行タスク 200%、デプロイサーキットブレーカー(ロールバックあり)、soa-ecs-tg に登録 | 同上 |
※ basics86 の手順はロードバランサーを使わずパブリック IP で公開しています。この記事ではサービスを ALB のターゲットグループに登録します。
作成・変更するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| タスク定義のリビジョン | soa-web(リビジョン 2) | APP_VERSION を v2 にした新しいバージョン |
| ECS サービスの更新 | soa-web-svc | リビジョン 2 へのローリング更新 |
手順 1: サービスのデプロイ設定を確認する
AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。上部の検索バーに ECS と入力し、「Elastic Container Service」を選択します。
左側ナビゲーションの「クラスター」から soa-ecs-cluster を選択し、「サービス」タブで soa-web-svc を選択します。サービスの「デプロイ」タブを開き、「デプロイ設定」セクションで以下を確認します。
- デプロイ戦略: ローリングアップデート
- 最小および最大実行タスク: 最小 100% および最大 200%
- デプロイサーキットブレーカー: オン
「タスク」タブを開き、タスク定義 soa-web:1 のタスクが 2 つ「実行中」になっていることも確認します。
手順 2: ALB へのアクセスを流し続ける
上部の検索バーに EC2 と入力し、「EC2」を選択します。左側ナビゲーションの「ロードバランシング」→「ロードバランサー」で soa-ecs-alb を選択し、「DNS 名」を控えます。
コンソール下部の「CloudShell」をクリックして CloudShell を開き、次のコマンドを実行します。<ALB の DNS 名> は控えた値に置き換えます。1 秒ごとに ALB へアクセスし、時刻・HTTP ステータスコード・ページの内容を表示し続けます。
ALB=<ALB の DNS 名>
while true; do
code=$(curl -s -m 3 -o /tmp/body -w '%{http_code}' "http://$ALB/")
echo "$(date +%T) $code $(cat /tmp/body)"
sleep 1
done
200 <h1>soa-web v1</h1> の行が 1 秒ごとに増えていきます。このタブは開いたまま、次の手順へ進みます。
手順 3: タスク定義の新しいリビジョンを作る
ECS のコンソールに戻り、左側ナビゲーションの「タスク定義」→ soa-web を選択します。リビジョン 1 を開き、右上の「アクション」→「新しいリビジョンの作成」を選択します。
「コンテナ - 1」の「環境変数 - オプション」で、キー APP_VERSION の値を v1 から v2 に変更します。その他の項目は変更せず、画面下部の「作成」をクリックします。
soa-web:2 が作成されたことを確認します。
手順 4: サービスをローリング更新する
「クラスター」→ soa-ecs-cluster →「サービス」タブで soa-web-svc を選択し、「サービスを更新」をクリックします。以下を設定します。
- タスク定義のリビジョン: 入力欄に
2と入力し、候補の「2(最新)」を選択 - 折りたたまれている「デプロイオプション」を展開し、デプロイ戦略が「ローリングアップデート」のままであることを確認(タイルで「ブルー/グリーン」「Canary」「リニア」も選べます)
- その他の項目はデフォルトのまま
「更新」をクリックします。サービスの「デプロイ」タブに移り、デプロイが始まります。
手順 5: タスクの入れ替わりを確かめる
soa-web-svc の「タスク」タブを開き、画面を数回更新します。最大実行タスク 200% の範囲で、古いタスクを残したまま soa-web:2 のタスクが 2 つ起動し、ALB のターゲットに登録されてから soa-web:1 のタスクが止まります。入れ替えは 2〜3 分で終わるので、新旧 4 つが同時に「実行中」の瞬間は見逃しやすいです。終わった後は、soa-web:2 が 2 つ「実行中」、soa-web:1 が 2 つ「停止済み」で並びます。
「イベント」タブを開くと、新しいタスクの起動、ターゲットの登録、古いタスクの接続のドレイン、古いタスクの停止の順にイベントが記録され、最後にサービスが定常状態に達したことが分かります。イベントのメッセージは英語で、ドレインは has begun draining connections on 1 tasks のように表示されます。
手順 6: アクセスが途切れなかったことを確かめる
CloudShell のタブに戻ります。soa-web v1 の行の後に v1 と v2 が混ざる時間があり、やがて soa-web v2 だけになります。その間、ステータスコードはすべて 200 で、タイムアウトや 502 / 503 の行はありません。
Ctrl + C でコマンドを止めます。