← ハンズオン一覧に戻る

AWS Hands-on / Compute

2 台のサーバーへアクセスを振り分ける

同じ内容の Web サーバーを 2 台用意し、その前に「ロードバランサー(Application Load Balancer)」を置いて、届いたアクセスを 2 台へ自動的に振り分けます。利用者は 1 つのアドレスにアクセスするだけで、裏側では複数台が処理を分け合う——その仕組みを自分の手で組み立てます。

● Lv.3 複数のサービスを組み合わせられる人 ⏱ 所要 60〜90 分 すべてコンソールで完結
01 — Prerequisites

はじめる前に

  • 必須AWS アカウントを持っていること
  • 必須マネジメントコンソールにサインインできること
  • 必須EC2 インスタンスを起動し、セキュリティグループで通信を許可した経験があること(このハンズオンは、その基本ができている前提で進めます)
  • あると良いユーザーデータでサーバーの初期設定を自動化したことがある(中身のスクリプトは本文に用意しています)
  • あると良い1 つのリージョンの中に「アベイラビリティーゾーン」という独立した区画が複数あることを知っている

※ このハンズオンは すべてコンソールだけで完結します。サーバーへのログイン(SSH)は使いません。動作確認はすべてブラウザとコンソールの画面で行います。

02 — References

参照する公式ドキュメント

手順に迷ったときや、用語の意味を確かめたいときに開きましょう。

※ リンク切れの場合は、ページタイトルで検索してください。

03 — Background

背景・シナリオ

Web サーバーが 1 台だけだと、心配なことが 2 つあります。ひとつは、その 1 台が止まるとサービス全体が止まってしまうこと。もうひとつは、アクセスが集中したときに1 台だけでは処理しきれなくなることです。どちらも「同じ仕事をするサーバーを複数台にする」ことで和らげられます。

とはいえ、利用者に「混んでいたら 2 番目のサーバーへ」とアドレスを使い分けてもらうわけにはいきません。そこで、サーバーたちの前に「受付」役を 1 つ置き、届いたアクセスを空いているサーバーへ自動で振り分けてもらう——これがロードバランサーです。今回は AWS の Application Load Balancer を使い、2 台の Web サーバーへアクセスを分散します。

利用者は、どのサーバーにつながっているか気にしなくていいの?

はい。利用者がアクセスするのはロードバランサーの 1 つのアドレスだけです。実際にどちらのサーバーが応答したかは、ロードバランサーが裏側で決めるので、利用者は意識する必要がありません。

なぜ 2 台を別々のアベイラビリティーゾーンに置くの?

アベイラビリティーゾーンは、電源やネットワークが分かれた独立した区画です。2 台を別々のゾーンに置くと、片方のゾーンに問題が起きても、もう片方のゾーンのサーバーで処理を続けられます。「同じカゴに卵を盛らない」という考え方です。

Goal

2 台の Web サーバーの前に Application Load Balancer を置き、ロードバランサーのアドレスにブラウザでアクセスすると、再読み込みのたびに 2 台へ振り分けられることを確認する。さらに 1 台を止めても、生きているほうへ振り分けられて表示が続くことを確かめる。

04 — Architecture

つくる構成

ブラウザからのアクセスは、まず Application Load Balancer が受け取ります。ロードバランサーは「ターゲットグループ」に登録された 2 台の EC2 へ、アクセスを順番に振り分けます。2 台は別々のアベイラビリティーゾーンのパブリックサブネットに置きます。

あなたのブラウザ(アクセス先は 1 つだけ)
aws AWS Cloud
Region : ap-northeast-1(東京)
VPC(デフォルト VPC でも可)
Application Load Balancer(受付役・インターネット向け)
届いたアクセスを、ターゲットグループの 2 台へ順番に振り分ける
パブリックサブネット(アベイラビリティーゾーン a)
EC2:web-1
Amazon Linux 2023
Apache 稼働
パブリックサブネット(アベイラビリティーゾーン c)
EC2:web-2
Amazon Linux 2023
Apache 稼働
ロードバランサーは、各サーバーが応答できる状態か(ヘルスチェック)を見張っています。
応答しないサーバーには振り分けず、復活したらまた振り分けに戻します。
05 — Requirements

要件

以下の要件を満たす構成を作り、ブラウザで振り分けを確認してください。

No要件
1リージョンは「東京(ap-northeast-1)」を使用する。
2Web サーバー用の EC2 インスタンスを 2 台起動する。AMI は Amazon Linux 2023、インスタンスタイプは無料利用枠の対象(例:t2.micro / t3.micro)。2 台は別々のアベイラビリティーゾーンのパブリックサブネットに 1 台ずつ置く。名前タグは web-1 / web-2(例)。
3各 EC2 で Apache(httpd)を起動し、どちらのサーバーか見分けられるページ(例:自分のホスト名を表示)を用意する。(用意の仕方は、構築手順で「ユーザーデータ方式」「AMI 方式」の 2 つから選べます)
4セキュリティグループを 2 つに分ける。ロードバランサー用は HTTP(80)を 0.0.0.0/0 から許可。サーバー用は HTTP(80)をロードバランサー用セキュリティグループからのみ許可する。
5ターゲットグループ(対象=インスタンス、HTTP:80)を作り、web-1web-2 を登録する。Application Load Balancer(インターネット向け、2 つのアベイラビリティーゾーンを指定、リスナー HTTP:80)を作成し、このターゲットグループに転送する。
6ターゲットの状態が 2 台とも healthy になったら、ロードバランサーの DNS 名にブラウザでアクセスし、再読み込みすると 2 台に振り分けられる(両方のホスト名が現れる)ことを確認する。
06 — Steps

構築の進め方

「2 台のサーバー → 振り分けの設定 → 受付役のロードバランサー」の順に組み立てます。登場人物が多いので、いま何を作っているかを意識しながら進めましょう。

  1. マネジメントコンソールにサインインし、リージョンを合わせる

    ブラウザで AWS マネジメントコンソールにサインインし、画面右上のリージョンが「アジアパシフィック(東京)ap-northeast-1」になっていることを確認します。

  2. 2 台の Web サーバーを用意する(2 つの方式から選べます)

    同じ内容の Web サーバーを 2 台、別々のアベイラビリティーゾーンに用意します。やり方は次の 方式 A(ユーザーデータ)方式 B(AMI)のどちらかを選んでください。どちらでも、最終的に web-1web-2 が別ゾーンにある状態になれば、以降の手順は共通です。

    方式 A

    ユーザーデータで 2 台を直接セットアップする

    起動のたびにスクリプトで Apache を入れる方法。手軽で、ページの中身を変えたいときに直しやすいのが利点です。

    1. web-1 を起動:EC2 コンソールで「インスタンスを起動」。名前 web-1、AMI は Amazon Linux 2023、タイプは無料利用枠の対象。サブネットをひとつ選び(例:アベイラビリティーゾーン a)、パブリック IP の自動割り当てを有効にします。「高度な詳細」→「ユーザーデータ」に次を貼り付けて起動します。
      ユーザーデータ(web-1・web-2 共通)
      #!/bin/bash
      dnf install -y httpd
      systemctl enable --now httpd
      # どのサーバーが応答したか分かるよう、自分のホスト名を表示する
      echo "<h1>応答したサーバー</h1><p>$(hostname -f)</p>" > /var/www/html/index.html
    2. web-2 を別ゾーンに起動:もう一度「インスタンスを起動」し、名前 web-2 で同じ AMI・タイプ・ユーザーデータを設定します。ポイントは、サブネットを web-1 とは違うアベイラビリティーゾーン(例:ゾーン c)にすること。セキュリティグループは web-1 と同じサーバー用のものを選びます。
      ※ 起動ウィザードで台数を 2 にすると両方が同じゾーンに入ってしまうため、ゾーンを分けたい今回はあえて 1 台ずつ起動します。
    — または —
    方式 B

    AMI に焼いてから 2 台を複製する

    Apache を焼き込んだ自分専用 AMI を 1 つ作り、そこから 2 台を起動する方法。起動が速く、何台でもまったく同じ土台で立てられます。台数が多いほど有利になります。

    1. ベースを 1 台起動:名前 web-base で Amazon Linux 2023・無料利用枠タイプのインスタンスを起動します。ユーザーデータには Apache の導入までを書きます(ページはまだ作りません)。
      ユーザーデータ(web-base =土台づくり)
      #!/bin/bash
      dnf install -y httpd
      systemctl enable --now httpd
    2. AMI を作成:web-base を選び、「アクション」→「イメージとテンプレート」→「イメージを作成」。イメージ名 web-ami で作成し、「AMI」一覧で状態が 利用可能(available) になるまで待ちます(作成後、web-base は使わないので終了してかまいません)。
    3. AMI から 2 台を別ゾーンに起動:「AMI」で web-ami を選び「AMI からインスタンスを起動」。web-1 をゾーン a、web-2 をゾーン c に(1 台ずつ)起動します。Apache は焼き込み済みなので、各起動時のユーザーデータはページを作る 1 行だけにします。
      ユーザーデータ(web-1・web-2 =ページ生成だけ)
      #!/bin/bash
      echo "<h1>応答したサーバー</h1><p>$(hostname -f)</p>" > /var/www/html/index.html
    これが「組み合わせ」の考え方

    変わりにくい土台(Apache)は AMI に焼き、起動ごとに変わる部分(ホスト名のページ)だけ ユーザーデータで入れています。実務でもよく使う、両者の良いとこ取りの形です。

    セキュリティグループはここで 2 つ目を意識

    どちらの方式でも、web-1web-2 に付けるサーバー用セキュリティグループは、あとでロードバランサーからの通信だけを許可する形にします。いったんは作成(または選択)しておき、ルールの調整はこのあとの「サーバー用セキュリティグループを整える」手順で行うと迷いません。

  3. ターゲットグループを作り、2 台を登録する

    EC2 コンソール左メニュー「ロードバランシング」→「ターゲットグループ」→「ターゲットグループの作成」を開きます。ターゲットタイプは「インスタンス」、プロトコルは HTTP : 80、VPC は EC2 を置いたものを選びます。次の画面で web-1web-2 を選び、「保留中として以下を含める」で登録してから作成します。

    ターゲットグループを作成 — タイプの選択(イメージ)

    ターゲットの種類

    インスタンス
    EC2 インスタンスを宛先にする
    IP アドレス
    IP を直接指定する
    Lambda 関数
    関数を宛先にする

    EC2 インスタンスを登録するので「インスタンス」を選びます

    ターゲットグループは「振り分け先の名簿」

    ロードバランサーは、この名簿に載っているサーバーへアクセスを配ります。ヘルスチェック(既定ではパス /)に応答できたサーバーだけが healthy として扱われ、振り分け対象になります。

  4. Application Load Balancer を作成する

    左メニュー「ロードバランサー」→「ロードバランサーの作成」で、Application Load Balancer を選びます。次のように設定します。

    スキームインターネット向け(Internet-facing)
    ネットワークマッピングEC2 を置いた VPC を選び、2 つのアベイラビリティーゾーン(web-1・web-2 を置いたゾーン)のパブリックサブネットにチェック
    セキュリティグループロードバランサー用(HTTP 80 を 0.0.0.0/0 から許可)を指定
    リスナーHTTP : 80 → 先ほど作成したターゲットグループへ転送
    ロードバランサーも複数ゾーンに置く

    ロードバランサー自身も、指定した複数のゾーンにまたがって動きます。だからこそ、片方のゾーンに問題が起きても受付を続けられます。サーバーと同じゾーンを選んでおきましょう。

  5. サーバー用セキュリティグループを「ロードバランサーからのみ許可」に整える

    web-1web-2 に付けたサーバー用セキュリティグループのインバウンドルールを開き、HTTP(80)のソースを、ロードバランサー用セキュリティグループに設定します(ソース欄でセキュリティグループを指定できます)。

    なぜ直接アクセスを閉じるの?

    利用者には必ずロードバランサーを通ってほしいので、サーバーへの直接アクセスは閉じておきます。「サーバーの入口は、受付役からの通信だけ開ける」と、経路が 1 本にそろい、振り分けや見張りも効くようになります。

  6. ターゲットが healthy になるのを待つ

    「ターゲットグループ」の「ターゲット」タブを開き、web-1web-2 の状態を確認します。最初は initial ですが、しばらくするとhealthy に変わります(数分かかることがあります)。

    healthy にならないときは

    多くは「サーバー用セキュリティグループがロードバランサーからの 80 番を許可していない」か「Apache がまだ起動していない」のどちらかです。サーバー用セキュリティグループのルールと、起動からの経過時間を見直しましょう。

  7. ロードバランサーの DNS 名にアクセスして振り分けを確認する

    「ロードバランサー」の詳細画面で「DNS 名」(例:my-alb-1234567890.ap-northeast-1.elb.amazonaws.com)をコピーし、ブラウザで http://<DNS 名> を開きます。再読み込みを何回か繰り返すと、表示されるホスト名が web-1web-2 の間で切り替わり、振り分けが効いていることが分かります。

    仕上げ:1 台止めると何が起きる?

    片方のインスタンスを停止してみましょう。しばらくするとそのサーバーが unhealthy になり振り分けから外れますが、ブラウザでは生きているほうが応答し続けて表示が途切れません。これが複数台にする狙いです(確認後、料金のため停止したままにせず、後片づけまで進めてください)。

07 — Pitfalls

つまずきポイント

初学者がよく引っかかる箇所を先回りでまとめました。答えそのものは載せていませんが、「どこを見直せばよいか」の手がかりとして使ってください。

Pitfall 01 — ターゲットが healthy にならない

「ターゲットの状態が unhealthy や initial のまま変わらない」

ロードバランサーからサーバーへの見張りの通信(ヘルスチェック)が届いていないことが多いです。①サーバー用セキュリティグループが、ロードバランサー用セキュリティグループからの HTTP(80)を許可しているか②各サーバーで Apache が起動しているか(ユーザーデータの 1 行目が #!/bin/bash か)、③ヘルスチェックのパスやポートが、ページのある場所と合っているかを順に見直しましょう。

Pitfall 02 — 何度更新しても同じサーバーばかり表示される

「振り分けされている実感がわかない」

まず2 台とも healthy になっているかを確認しましょう(片方が unhealthy だと、もう片方だけに振り分けられます)。表示が変わりにくいときは、ブラウザのキャッシュが効いている可能性もあるため、スーパーリロード(強制再読み込み)や時間を空けた再読み込みを試してみてください。http:// でアクセスしているか(https:// ではないか)も確認します。

08 — Checklist

完了チェック

要件の再確認ではなく、画面のどこを見れば達成を確認できるかをまとめました。EC2 コンソールとブラウザを開いて、次を順に確かめましょう。

  • 「インスタンス」一覧に web-1web-2 があり、それぞれ異なるアベイラビリティーゾーンに配置されている(一覧の「アベイラビリティーゾーン」列で確認)。
  • 「ターゲットグループ」の「ターゲット」タブで、2 台とも状態が healthy になっている。
  • 「ロードバランサー」の状態が アクティブ(Active) で、「DNS 名」が表示されている。
  • サーバー用セキュリティグループのインバウンドに、HTTP(80)のソースがロードバランサー用セキュリティグループになっている行がある。
  • ブラウザで http://<DNS 名> を開き、再読み込みで web-1web-2 のホスト名が入れ替わって表示される。
  • (仕上げ)1 台を停止すると、しばらくしてそのターゲットが unhealthy になり、ブラウザでは残った 1 台が応答し続ける
09 — Think

考えてみよう

手を動かすことに加えて、次の問いに自分の言葉で答えられるようにしておくと、理解がより深まります。

  1. 2 台を別々のアベイラビリティーゾーンに置きました。もし 2 台とも同じゾーンに置いていたら、どんなときに困るでしょうか。ゾーンを分けたことの意味を考えてみましょう。
    ヒント
    アベイラビリティーゾーンは電源やネットワークが独立した区画です。あるゾーン全体に問題が起きた場面を想像すると、「同じゾーンに 2 台」と「別ゾーンに 1 台ずつ」で結果がどう変わるかが見えてきます。
  2. サーバー用セキュリティグループで、HTTP(80)のソースを「ロードバランサー用セキュリティグループ」に絞りました。もしここを 0.0.0.0/0(どこからでも可)にしてしまうと、どんな問題が考えられるでしょうか。
    ヒント
    サーバーに直接アクセスできてしまうと、ロードバランサーを通さない経路ができます。振り分けや見張り(ヘルスチェック)を通らないアクセスが生まれること、入口が広がることの両面から考えてみましょう。
  3. 今回はアクセスが増えても 2 台のままです。もし利用者がさらに増えたら、どんな手を打てるでしょうか。「手動で台数を足す」以外に、AWS で自動的に台数を増減させる仕組みがないか調べてみましょう。
    ヒント
    混雑に合わせてサーバーの台数を自動で増やしたり減らしたりする仕組み(オートスケーリング)があります。ロードバランサーと組み合わせると何がうれしいか、という観点で調べてみると、今回の構成の発展形が見えてきます。
10 — Clean up

後片づけ

登場人物が多いぶん、消す順番に気をつけます。ロードバランサーは起動している間ずっと料金が発生するため、使い終わったら必ず片づけましょう。次の順で進めると、依存関係でつまずきにくくなります。

  1. ロードバランサーを削除する:「ロードバランサー」で対象を選び、「アクション」→「削除」。これで時間課金が止まります。
  2. ターゲットグループを削除する:「ターゲットグループ」で対象を選び削除します(ロードバランサーを消したあとに行います)。
  3. EC2 インスタンスを終了する:「インスタンス」で web-1web-2 を選び、「インスタンスを終了(Terminate)」。状態が「終了済み」になれば料金が止まります。
  4. セキュリティグループを削除する(任意):今回作った 2 つのセキュリティグループは、ロードバランサーとインスタンスを消したあとに削除できます(他で使っていないことを確認してから)。
  5. (方式 B を選んだ場合)AMI とスナップショットを片づける:作成した web-ami を「AMI」で登録解除し、続けて「スナップショット」から対応するスナップショットを削除します。登録解除だけではスナップショットが残り、ストレージ料金がかかり続けます。web-base を残していれば、これも終了します。
Caution — ロードバランサーは消し忘れに注意

インスタンスを止めても、ロードバランサーは別途削除が必要

ロードバランサーは EC2 とは独立したリソースで、存在している間は時間あたりの料金が発生し続けます。インスタンスを終了しても自動では消えません。使い終わったら必ず削除しましょう。デフォルト VPC やデフォルトのサブネットは消さないようにしてください。

コストに関する注意: Application Load Balancer は、起動している間ずっと時間あたりの料金と、処理量に応じた料金(LCU)がかかります。新規アカウントの無料利用枠には Elastic Load Balancing の枠(一般的に月 750 時間・一定の処理量まで)がありますが、消し忘れると枠を超えて課金されます。あわせて、EC2 インスタンス 2 台も起動中は課金されますt2.micro / t3.micro などは無料利用枠の対象。ただし枠は時間の合計なので、2 台動かすと 1 台のときより早く枠を消費します)。各サーバーに付くディスク(EBS ボリューム)や、割り当てられる public IPv4 アドレスにも料金がかかります。VPC・サブネット・ルートテーブル・セキュリティグループ自体には料金はかかりません。使い終えたら、上の「後片づけ」でロードバランサーの削除とインスタンスの終了を必ず行いましょう。最新の料金は AWS の公式料金ページで確認してください。