ECS のローリング・ブルー/グリーン・リニア・カナリアの違い ── ALB 配下のサービスを止めずに入れ替える

目次

概要

ALB の後ろで動く Amazon ECS のサービスを新しいバージョンに更新するとき、「利用者のアクセスを止めたくない」「でも追加の設備やコストは増やしたくない」という条件はよくあります。ECS には、サービスを更新するときのデプロイ方式として ローリング更新、ブルー/グリーン、リニア、カナリア があり、どれを選ぶかで、止まらずに入れ替わるか、新旧を並べて検証できるか、何を追加で用意するかが変わります。

この記事では、4 つのデプロイ方式の仕組みと、それぞれに必要なリソース・向いている場面を整理します。実践では、ALB 配下の Fargate のサービスをローリング更新で新しいタスク定義に切り替え、ALB へのアクセスがエラーを出さずに v1 から v2 へ入れ替わる様子を確かめます。

ローリング更新: 新しいタスクが正常になってから、古いタスクを外して止める
ローリング更新: 新しいタスクが正常になってから、古いタスクを外して止める
クラウドおさる

見張り台の当番猿を交代させるとき、全員いっぺんに降ろしたら山が無防備になるでござる。新しい当番が上がってから古い当番が降りる。その交代の仕方を ECS で確かめるでござるよ。

この記事のメリット

  • ECS のローリング更新で、タスクがどの順番で入れ替わるかを説明できるようになる
  • 最小実行タスク(minimumHealthyPercent)と最大実行タスク(maximumPercent)の決め方が分かる
  • ブルー/グリーン・リニア・カナリアに必要なリソースと、ローリング更新との違いを整理できる
  • 「無停止・低コスト」「本番前に検証」「少しずつ移行」などの要件から、デプロイ方式を選べるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

サービスの更新とデプロイ

ECS のサービスは、指定したタスク定義からタスクを決まった数(必要なタスク数)だけ動かし続けます。サービスのタスク定義のリビジョンやコンテナイメージを変えて更新すると、ECS は デプロイ を開始し、動いているタスクを新しい設定のタスクに置き換えます。どう置き換えるかを決めるのがデプロイ方式です。

デプロイ方式入れ替え方
ローリング更新古いタスクを少しずつ新しいタスクに置き換える。ALB のターゲットグループは 1 つのまま
ブルー/グリーン新しいリビジョン(グリーン)を古いリビジョン(ブルー)と並べて起動し、検証してから本番のトラフィックを一度に切り替える
リニアグリーンを起動し、本番のトラフィックを同じ割合ずつ(例: 10% ずつ)段階的に移す
カナリアグリーンを起動し、まず一部(例: 10%)だけを移して様子を見てから、残りを一度に移す

ブルー/グリーン・リニア・カナリアは、以前は AWS CodeDeploy と組み合わせて実現していましたが、現在は ECS の機能として直接使えます(CodeDeploy を使う方式も残っていますが、ECS のドキュメントでは ECS のブルー/グリーンデプロイの利用が推奨されています)。

ローリング更新の進み方

ローリング更新で一度に増やしたり減らしたりするタスクの数は、サービスのデプロイ設定の 2 つの値で決まります。

設定意味計算
最小実行タスク %(minimumHealthyPercent)デプロイ中に、正常な状態で動いていなければならないタスク数の下限必要なタスク数 × 割合(切り上げ)
最大実行タスク %(maximumPercent)デプロイ中に、同時に動かしてよいタスク数の上限必要なタスク数 × 割合(切り捨て)

たとえば必要なタスク数が 2、最小 100%・最大 200% なら、ECS は古いタスク 2 つを動かしたまま新しいタスクを 2 つ起動します。新しいタスクが ALB のターゲットグループに登録され、ヘルスチェックに合格してから、古いタスクをターゲットグループから外し(登録解除の遅延の間に処理中のリクエストを終わらせる)、停止します。常に正常なタスクが 2 つ以上いるので、利用者のアクセスは止まりません。

逆に最小を 0% にすると、ECS は新しいタスクを起動する前に古いタスクを全部止められます。タスク数の上限を増やさずに済みますが、入れ替えの間はサービスが止まります。

クラウドおさる

最小 100%・最大 200% は「新しい当番が全員見張り台に上がってから、古い当番が降りる」交代でござるな。見張り台の席(タスクの上限)に余裕があるぶん、山はずっと見張られているのでござる。

新しいタスクが起動に失敗し続けたときに備えて、デプロイサーキットブレーカー をオンにしておくと、ECS がデプロイを失敗と判定し、ロールバックを選んでいれば最後に成功したリビジョンに戻します。アプリケーションのメトリクスで失敗を判定したいときは、CloudWatch アラームをデプロイに関連付ける方法もあります。

ブルー/グリーン・リニア・カナリアに必要なもの

3 つの方式は、ブルーとグリーンのサービスリビジョンを同時に動かし、ロードバランサー側でトラフィックの向き先を切り替えます。ALB を使う場合は、次のリソースを用意します。

リソース内容
ターゲットグループ 2 つブルー用のプライマリターゲットグループと、グリーン用の代替ターゲットグループ
本番リスナーとリスナールールECS がルールを書き換えてトラフィックの向き先(割合)を切り替える
テストリスナー(任意)本番のトラフィックを移す前に、別のポートでグリーンを検証する
インフラストラクチャの IAM ロールECS がロードバランサーのリソースを操作するためのロール

切り替えの後は ベイク時間 の間ブルーを残しておき、問題があればすぐにブルーへ戻せます。各段階で Lambda 関数による検証や一時停止を差し込む ライフサイクルフック も使えます。その代わり、デプロイ中はブルーとグリーンの両方のタスクが動くので、リソースの使用量が最大で 2 倍になります。

4 つのデプロイ方式で、何が違うか
4 つのデプロイ方式で、何が違うか

デプロイ方式の選び方

要件向いている方式
ほぼ無停止で、追加の設備なしに、もっとも低コストで更新したいローリング更新(最小 100% など、正常なタスクを残す設定)
本番のトラフィックを流す前に新しいバージョンを検証し、問題があればすぐ戻したいブルー/グリーン
本番のトラフィックを少しずつ増やしながら、段階ごとに様子を見たいリニア
まず一部の利用者だけで新しいバージョンを試し、問題がなければ残りを一度に移したいカナリア
クラウドおさる

「止めたくない」だけで、すぐにブルー/グリーンやカナリアを選ぶのは早合点でござる。ターゲットグループ 2 つやリスナールール、IAM ロールの用意が要るのでござる。「コストを抑えて」と言われたら、まずローリング更新でござるぞ。

新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

実践

ハンズオンガイド8 ステップ画面 6 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

ALB 配下の Fargate のサービス soa-web-svc は、タスク定義 soa-web のリビジョン 1(ページに soa-web v1 と表示する)で 2 つのタスクを動かしています。CloudShell から ALB に 1 秒ごとにアクセスし続けながら、タスク定義のリビジョン 2(soa-web v2 と表示する)を作ってローリング更新し、エラーを出さずに入れ替わることを確かめます。

前提条件

  • リージョン: ap-northeast-1(東京)
  • 以下のリソースが作成済みであること

まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。

リソース種別リソース名内容作り方の参考
VPCsoa-ecs-vpcパブリックサブネット 2 つ(ap-northeast-1a / ap-northeast-1c)Amazon VPC で仮想ネットワークを構築しサブネットを設定する
Application Load Balancersoa-ecs-albインターネット向け。リスナー HTTP:80 で soa-ecs-tg に転送─
ターゲットグループsoa-ecs-tgターゲットタイプ IP、ヘルスチェックのパス /、登録解除の遅延 30 秒─
ECS クラスターsoa-ecs-clusterFargateAmazon 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 に登録同上

※「Amazon ECS と Fargate でコンテナを動かす」の手順はロードバランサーを使わずパブリック 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-svc のデプロイ設定(ローリングアップデート・最小 100%・最大 200%)
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 に変更します。その他の項目は変更せず、画面下部の「作成」をクリックします。

新しいリビジョンの作成画面で、環境変数 APP_VERSION を v2 に変更した状態
新しいリビジョンの作成画面で、環境変数 APP_VERSION を v2 に変更した状態

soa-web:2 が作成されたことを確認します。

手順 4: サービスをローリング更新する

「クラスター」→ soa-ecs-cluster →「サービス」タブで soa-web-svc を選択し、「サービスを更新」をクリックします。以下を設定します。

  • タスク定義のリビジョン: 入力欄に 2 と入力し、候補の「2(最新)」を選択
  • 折りたたまれている「デプロイオプション」を展開し、デプロイ戦略が「ローリングアップデート」のままであることを確認(タイルで「ブルー/グリーン」「Canary」「リニア」も選べます)
  • その他の項目はデフォルトのまま
サービスの更新画面(リビジョン 2 を選択し、デプロイオプションがローリングアップデートの状態)
サービスの更新画面(リビジョン 2 を選択し、デプロイオプションがローリングアップデートの状態)

「更新」をクリックします。サービスの「デプロイ」タブに移り、デプロイが始まります。

手順 5: タスクの入れ替わりを確かめる

soa-web-svc の「タスク」タブを開き、画面を数回更新します。最大実行タスク 200% の範囲で、古いタスクを残したまま soa-web:2 のタスクが 2 つ起動し、ALB のターゲットに登録されてから soa-web:1 のタスクが止まります。入れ替えは 2〜3 分で終わるので、新旧 4 つが同時に「実行中」の瞬間は見逃しやすいです。終わった後は、soa-web:2 が 2 つ「実行中」、soa-web:1 が 2 つ「停止済み」で並びます。

タスク一覧で soa-web:2 が実行中、soa-web:1 が停止済みになった状態
タスク一覧で soa-web:2 が実行中、soa-web:1 が停止済みになった状態

「イベント」タブを開くと、新しいタスクの起動、ターゲットの登録、古いタスクの接続のドレイン、古いタスクの停止の順にイベントが記録され、最後にサービスが定常状態に達したことが分かります。イベントのメッセージは英語で、ドレインは has begun draining connections on 1 tasks のように表示されます。

サービスのイベント(タスクの起動・ターゲットの登録・ドレイン・停止・定常状態)
サービスのイベント(タスクの起動・ターゲットの登録・ドレイン・停止・定常状態)

手順 6: アクセスが途切れなかったことを確かめる

CloudShell のタブに戻ります。soa-web v1 の行の後に v1 と v2 が混ざる時間があり、やがて soa-web v2 だけになります。その間、ステータスコードはすべて 200 で、タイムアウトや 502 / 503 の行はありません。

CloudShell の出力で v1 から v2 へ切り替わり、すべて 200 になっている部分
CloudShell の出力で v1 から v2 へ切り替わり、すべて 200 になっている部分

Ctrl + C でコマンドを止めます。

クラウドおさる

v1 と v2 が混ざる時間があるのが、ローリング更新の特徴でござる。新旧を混ぜたくない、本番の前に v2 だけを試したいなら、そこでブルー/グリーンやカナリアの出番になるのでござるな。

まとめ

デプロイ方式トラフィックの移し方追加で要るもの向いている場面
ローリング更新タスクを少しずつ入れ替える。新旧が混ざる時間があるなし(ターゲットグループ 1 つ)無停止で、もっとも低コストに更新したい
ブルー/グリーン検証してから一度に切り替えるターゲットグループ 2 つ・リスナールール・IAM ロール本番前の検証とすばやいロールバック
リニア同じ割合ずつ段階的に移す同上段階ごとに様子を見ながら移したい
カナリア一部だけ移して様子を見てから、残りを一度に移す同上一部の利用者で先に試したい
  • ローリング更新の入れ替えの速さと安全さは、最小実行タスク %(下限)と最大実行タスク %(上限)で決まる
  • 最小 100%・最大 200% なら、新しいタスクがヘルスチェックに合格してから古いタスクが外れるので、アクセスが止まらない
  • 最小 0% は古いタスクを先に止められるが、入れ替えの間はサービスが止まる
  • デプロイサーキットブレーカーや CloudWatch アラームで、失敗したデプロイをロールバックできる
  • ブルー/グリーン・リニア・カナリアは ECS の機能として使え、デプロイ中はブルーとグリーンが両方動くためリソースが最大で 2 倍になる
クラウドおさる

「止めずに」と「安く」が並んだらローリング更新、「本番前に検証」ならブルー/グリーン、「少しずつ」ならリニアかカナリアでござる。要件の言葉と、追加で要るものの重さを結びつけて覚えるでござるよ。

参照先

キャリア相談
クラウドおさる

独学の先に、AWS の仕事がある ── ジュニアおさるのキャリア相談

CLF には受かったけれど、次に何をすればいいのか分からない。独学で AWS を学ぶジュニアおさるの相談に、株式会社ジェニュイン代表の土肥が答えています。

  • ✓資格はゴールか、CLF の次に何から手を付けるか
  • ✓EC2 の次に作ってみる構成と、IaC・コスト管理
  • ✓実務経験ゼロでも、面接で話せる「これまで」の作り方
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次