高可用性アプリケーションでのロード バランシングの使用

このチュートリアルでは、リージョン マネージド インスタンス グループとロード バランシングを使用して、ビジーまたは使用不能でない VM インスタンスにトラフィックをリダイレクトし、ゾーンが停止しても高可用性を確保する方法を説明します。

リージョン マネージド インスタンス グループは、複数のゾーンにまたがる複数のインスタンスにアプリケーションを分散します。グローバル ロードバランサは、単一の IP アドレスを介して複数のリージョンにトラフィックを配信します。これらのサービスの両方を使用してアプリケーションを複数のゾーンに分散することにより、ゾーンの障害のような極端なケースでも、アプリケーションの可用性を確保できます。

ロードバランサは、さまざまな種類のトラフィックの配信に使用できます。このチュートリアルでは、外部 HTTP トラフィックを配信するグローバル ロードバランサの作成方法について説明しますが、このチュートリアルの内容の大部分は他の種類のロードバランサにも該当します。ロードバランサで配信できる他の種類のトラフィックについては、Cloud Load Balancing の種類をご覧ください。

このチュートリアルでは、リージョン マネージド インスタンス グループでウェブ アプリケーションを起動して、ネットワーク アクセスを構成します。つづいて、トラフィックをウェブ アプリケーションに配信するロードバランサを作成し、ゾーンの停止をシミュレートしてロードバランサを観察する詳細な手順を示します。これらの機能の使用経験にもよりますが、このチュートリアルを完了するには約 45 分かかります。

アプリケーション アーキテクチャ

アプリケーションには、次の Compute Engine コンポーネントが含まれています。

  • VPC ネットワーク: Google Cloud 内の仮想ネットワーク。独自のルートとファイアウォール ルールを使用してグローバル接続を提供します。
  • ファイアウォール ルール: Google Cloudファイアウォールにより、インスタンスへのトラフィックを許可または拒否できます。
  • インスタンス テンプレート: マネージド インスタンス グループに個々の VM インスタンスを作成するために使用されるテンプレート。
  • リージョン マネージド インスタンス グループ: 複数のゾーンで同じアプリケーションを実行する VM インスタンスのグループ。
  • グローバル静的外部 IP アドレス: 外部ネットワークでアクセス可能な、グローバル リソースに接続できる静的 IP アドレス。
  • グローバル ロードバランサ: バックエンド インスタンスを複数のリージョンに分配できるようにするロードバランサ。ユーザーが同じアプリケーションやコンテンツにアクセスする必要がある状況で、1 つのエニーキャスト IP アドレスでアクセス権を付与する場合は、グローバル ロードバランサを使用します。
  • ヘルスチェック: 個々の VM インスタンス上のアプリケーションの応答性を評価するためにロードバランサが使用するポリシー。

ウェブ アプリケーションを起動する

このチュートリアルでは、GitHub に保存されているウェブ アプリケーションを使用します。アプリケーションの実装方法の詳細については、GoogleCloudPlatform/python-docs-samples GitHub リポジトリをご覧ください。

インスタンス テンプレートに起動スクリプトを含めることで、インスタンス グループ内のすべての VM でウェブ アプリケーションを起動します。さらに、このチュートリアルのファイアウォール ルールがプロジェクトで実行されている既存のリソースに影響するのを避けるため、専用の VPC ネットワークでインスタンス グループを実行します。

VPC ネットワークの作成

VPC ネットワークを使用すると、プロジェクト内の既存のリソースが、このチュートリアル用に作成するリソースの影響を受けないように保護されます。VPC ネットワークは、ロードバランサを経由するように着信トラフィックを制限するためにも必要です。

VPC ネットワークを作成して、デモウェブ アプリケーション用のファイアウォール ルールをカプセル化するには、次の操作を行います。

  1. Google Cloud コンソールで、[VPC ネットワーク] ページに移動します。

    [VPC ネットワーク] に移動

  2. [VPC ネットワークを作成] をクリックします。

  3. [名前] に「web-app-vpc」と入力します。

  4. [サブネット作成モード] を [カスタム] に設定します。

  5. 次の手順で新しいサブネットを作成します。

    1. [サブネット] セクションで、[名前] フィールドに「web-app-vpc-subnet」と入力します。
    2. [リージョン] プルダウンで、[us-central1] を選択します。
    3. [IP スタックタイプ] オプションが [IPv4] に設定されていることを確認します。
    4. [プライマリ IPv4 範囲] セクションに、IPv4 範囲「10.2.0.0/24」を入力します。
  6. ページの下部にある [作成] をクリックします。

VPC ネットワークが作成されるまで待ってから続行します。

ファイアウォール ルールを作成する

VPC ネットワークの作成が完了したら、VPC ネットワークへの HTTP トラフィックを許可するファイアウォール ルールを設定します。

  1. Google Cloud コンソールで、[ファイアウォール] ページに移動します。

    [ファイアウォール] に移動

  2. [ファイアウォール ルールを作成] をクリックします。

  3. [名前] フィールドに「allow-web-app-http」と入力します。

  4. [ネットワーク] を web-app-vpc に設定します。

  5. 次のオプションが以下のように設定されていることを確認します。

    • [トラフィックの方向] オプションが [上り(内向き)] に設定されている。
    • [一致したときのアクション] オプションが [許可] に設定されている。
  6. [ターゲット] プルダウンで、[ネットワーク上のすべてのインスタンス] を選択します。

  7. [送信元フィルタ] を IPv4 ranges に設定します。

  8. [送信元 IP 範囲] フィールドに「130.211.0.0/22, 35.191.0.0/16」と入力して、ロードバランサのヘルスチェックを許可します。

  9. [プロトコルとポート] で、次の操作を行います。

    1. 指定したプロトコルとポートを選択します。
    2. [TCP] を選択します。
    3. [ポート] フィールドに「80」と入力して、HTTP トラフィックのアクセスを許可します。
  10. [作成] をクリックします。

インスタンス テンプレートを作成する

VM インスタンスのグループの作成に使用するテンプレートを作成します。テンプレートから作成された各インスタンスは、起動スクリプトを使用してデモ用ウェブ アプリケーションを起動します。

  1. Google Cloud コンソールで、[インスタンス テンプレート] ページに移動します。

    [インスタンス テンプレート] に移動

  2. [インスタンス テンプレートを作成] をクリックします。

  3. [名前] に「load-balancing-web-app-template」と入力します。

  4. [マシンの構成] で、[マシンタイプ] を e2-medium に設定します。

  5. [詳細オプション] セクションをクリックして開きます。

  6. [ネットワーキング] セクションをクリックして、次の操作を行います。

    1. [ネットワーク インターフェース] セクションで、既存のネットワーク インターフェースの横にある アイコンをクリックして、既存のネットワーク インターフェースを削除します。
    2. [ネットワーク インターフェースを追加] をクリックしてから、web-app-vpc ネットワークを選択します。これで、このテンプレートで作成された各インスタンスが、前のステップで作成したネットワークで必ず実行されるようになります。
    3. [サブネットワーク] プルダウンで、web-app-vpc-subnet を選択します。
    4. [完了] をクリックします。
  7. [管理] セクションをクリックして、次の操作を行います。

    1. [自動化] セクションで、次の起動スクリプトを入力します。

      apt-get update
      apt-get -y install git python3-pip python3-venv
      git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
      python3 -m venv venv
      ./venv/bin/pip3 install -Ur ./python-docs-samples/compute/managed-instances/demo/requirements.txt
      ./venv/bin/pip3 install gunicorn
      ./venv/bin/gunicorn --bind 0.0.0.0:80 app:app --daemon --chdir ./python-docs-samples/compute/managed-instances/demo
      

      このスクリプトは、VM インスタンスの起動時にウェブ アプリケーションを取得し、インストールして起動します。

  8. 他のオプションはデフォルト値をそのまま使用します。

  9. [作成] をクリックします。

テンプレートが作成されるまで待ってから続行します。

リージョン マネージド インスタンス グループを作成する

インスタンス テンプレートを使用してリージョン マネージド インスタンス グループを作成し、ウェブ アプリケーションを実行します。

  1. Google Cloud コンソールで、[インスタンス グループ] ページに移動します。

    [インスタンス グループ] に移動

  2. [インスタンス グループを作成] をクリックします。

  3. [名前] に「load-balancing-web-app-group」と入力します。

  4. [インスタンス テンプレート] で [load-balancing-web-app-template] を選択します。

  5. [インスタンス数] を「6」に設定します。このフィールドが無効になっている場合は、まず自動スケーリングをオフにします。

    自動スケーリングをオフにするには、[自動スケーリング] セクションに移動します。[自動スケーリング モード] プルダウンで、[オフ: 自動スケーリングを行いません] を選択します。

  6. [ロケーション] で [マルチゾーン] を選択します。

  7. [リージョン] で、[us-central1] を選択します。

  8. [ゾーン] で、プルダウン リストから次のゾーンを選択します。

    • us-central1-b
    • us-central1-c
    • us-central1-f
  9. 他のオプションはデフォルト値をそのまま使用します。

  10. [作成] をクリックします。[インスタンス グループ] ページにリダイレクトされます。

    グループ内のすべてのインスタンスが実行されるまで、数分かかることがあります。

ロードバランサを構成する

ロードバランサを使用してトラフィックをウェブ アプリケーションに配信するには、すべての着信トラフィックを受信するために外部 IP アドレスを予約する必要があります。次に、その IP アドレスからのトラフィックを受け入れてインスタンス グループにリダイレクトするロードバランサを作成します。

静的 IP アドレスを予約する

グローバル静的外部 IP アドレスを使用して、すべてのユーザー トラフィックを受信する単一のエントリ ポイントをロードバランサのために用意します。関連付けられた Google Cloud リソースを変更、削除しても、Compute Engine は静的 IP アドレスを保持します。したがって、ウェブ アプリケーションの他の部分が変更されても、ウェブ アプリケーションは常に同じエントリ ポイントを持つことができます。

  1. Google Cloud コンソールで、[IP アドレス] ページに移動します。

    [IP アドレス] に移動

  2. [静的外部 IP アドレスを予約] をクリックします。

  3. [名前] フィールドに「web-app-ipv4」と入力します。

  4. [IP バージョン] を IPv4 に設定します。

  5. [タイプ] を [グローバル] に設定します。

  6. [予約] をクリックします。

ロードバランサを作成する

このセクションでは、HTTP トラフィックを配信するグローバル ロードバランサを作成するために必要な手順について説明します。

このロードバランサは、フロントエンドを使用して着信トラフィックを受信し、バックエンドを使用してこのトラフィックを正常なインスタンスに分散します。ロードバランサは複数のコンポーネントで構成されるため、ロードバランサを作成するタスクは以下の 5 つのステップに分かれます。

  • ロードバランサの種類を選択する
  • ロードバランサの名前を付ける
  • フロントエンドを構成する
  • バックエンドを構成する
  • 確認して完了する

ロードバランサを作成するには、上記のステップをすべて完了します。

ロードバランサの種類を選択する

  1. Google Cloud コンソールで、[ロード バランシング] ページに移動します。

    [ロード バランシング] に移動

  2. [ロードバランサを作成] をクリックします。
  3. [ロードバランサの種類] で [アプリケーション ロードバランサ(HTTP / HTTPS)] を選択し、[次へ] をクリックします。
  4. [インターネット接続または内部] で [インターネット接続(外部)] を選択し、[次へ] をクリックします。
  5. [グローバルまたはシングル リージョンのデプロイ] で [グローバル ワークロードに最適] を選択し、[次へ] をクリックします。
  6. [ロードバランサの世代] で [グローバル外部アプリケーション ロードバランサ] を選択し、[次へ] をクリックします。
  7. [構成] をクリックします。

ロードバランサの名前を付ける

  1. 左側のパネルの [ロードバランサの名前] に「web-app-load-balancer」と入力します。

フロントエンドを構成する

  1. [フロントエンドの構成] ページで、[名前] に「web-app-ipv4-frontend」と入力します。
  2. [プロトコル] を HTTP に設定します。
  3. [IP バージョン] を IPv4 に設定します。
  4. [IP アドレス] を web-app-ipv4 に設定します。
  5. [ポート] を 80 に設定します。
  6. [完了] をクリックすると、フロントエンドが作成されます。

バックエンドを構成する

  1. 左側のパネルで、[バックエンドの構成] をクリックします。
  2. [バックエンド サービスとバックエンド バケット] プルダウンをクリックしてメニューを開いてから、[バックエンド サービスを作成] をクリックします。
  3. 新しいウィンドウで、バックエンド サービスの [名前] に「web-app-backend」と入力します。
  4. [バックエンド] セクションで、次の操作を行います。
    1. [インスタンス グループ] を load-balancing-web-app-group に設定します。
    2. [ポート番号] を 80 に設定します。これにより、ロードバランサとインスタンス グループ間の HTTP トラフィックを許可することができます。
    3. [分散モード] で、[使用率] を選択します。
    4. [完了] をクリックします。
  5. ロードバランサのバックエンドのヘルスチェックを次のように作成します。

    1. [ヘルスチェック] プルダウンをクリックしてから、[ヘルスチェックを作成] をクリックします。新しいウィンドウが開きます。
    2. 新しいウィンドウで、[名前] に「web-app-load-balancer-check」と入力します。
    3. [プロトコル] を HTTP に設定します。
    4. [ポート] に「80」と入力します。
    5. このチュートリアルでは、[リクエストパス] を /health に設定します。これは、デモウェブ アプリケーションが応答するように設定されているパスです。
    6. ヘルス条件を次のように設定します。

      1. [チェック間隔] を 3 秒に設定します。これは、プローブを開始してから次のブローブを開始するまでの時間です。
      2. [タイムアウト] を 3 秒に設定します。これは、 Google Cloud でプローブに対するレスポンスを待ち受ける時間です。この値は、チェック間隔で設定した数値以下にする必要があります。
      3. [正常しきい値] を [2 回連続して成功] に設定します。これは、プローブが連続で成功するとインスタンスが正常であると判断される回数です。
      4. [異常しきい値] を [2 回連続して失敗] に設定します。これは、プローブが連続で失敗するとインスタンスに異常があると判断される回数です。
    7. [作成] をクリックしてヘルスチェックを作成します。

  6. 他のオプションはデフォルト値をそのまま使用します。

  7. [作成] をクリックすると、バックエンド サービスが作成されます。

確認して完了する

ロードバランサを作成する前に、負荷分散設定を確認します。

  1. [グローバル外部アプリケーション ロードバランサを作成] ページの左パネルで、[確認と完了] をクリックします。
  2. [確認と完了] ページで、[フロントエンド] が使用する IP アドレスの [プロトコル] が HTTP になっていることを確認します。

  3. 同じページで、[バックエンド] が次のように設定されていることを確認します。

    • [バックエンド サービス] が web-app-backend
    • [エンドポイント プロトコル] が HTTP
    • [ヘルスチェック] が web-app-load-balancer-check
    • [インスタンス グループ] が load-balancing-web-app-group
  4. [作成] をクリックして、ロードバランサの作成を完了します。

ロードバランサの作成が完了するまで数分かかることがあります。

ロードバランサをテストする

次の手順で、ロードバランサを使用してウェブ アプリケーションに接続できることを確認します。

  1. Google Cloud コンソールで、[ロード バランシング] ページに移動します。

    [ロード バランシング] に移動

  2. [名前] 列で web-app-load-balancer をクリックし、作成したロードバランサを開きます。

  3. 外部静的 IP アドレスを使用してウェブアプリに接続するには、次の操作を行います。

    1. [フロントエンド] セクションで、[IP:ポート] 列に表示されている IP アドレスをコピーします。
    2. 新しいブラウザタブを開き、IP アドレスをアドレスバーに貼り付けます。次のように、デモ用ウェブ アプリケーションが表示されます。

      デモウェブ アプリケーション。

    ページを更新するたびに、ロードバランサが異なるゾーンの異なるインスタンスに接続することに注意してください。これは、インスタンスに直接接続していないためです。接続しているのはロードバランサであり、ロードバランサによってリダイレクト先のインスタンスが選択されます。

    確認が終わったら、デモ用ウェブ アプリケーションのブラウザタブを閉じます。

ゾーンの停止をシミュレートする

ゾーンの停止による広範囲の使用不能状態をシミュレートすることにより、ロードバランサの機能を観察できます。このシミュレーションを実行するには、指定したゾーンに存在するすべてのインスタンスに、/health リクエストパスの異常ステータスを強制的に報告させます。これらのインスタンスが異常ステータスを報告すると、ロード バランシングのヘルスチェックが失敗し、ロードバランサはそれらのインスタンスへのトラフィックの配信を停止するよう促されます。

  1. ロードバランサがトラフィックを配信しているゾーンをモニタリングします。

    1. Google Cloud コンソールで [Cloud Shell] に移動します。

      Cloud Shell を開く

      Google Cloud コンソールのペインで Cloud Shell が開きます。セッションの初期化に数秒かかることがあります。

    2. ロードバランサの静的外部 IP アドレスを次の手順で保存します。

      1. ターミナルで次のコマンドを入力して、ロードバランサのフロントエンド転送ルールから外部 IP アドレスを取得します。

        gcloud compute forwarding-rules describe web-app-ipv4-frontend --global
        

        出力は次のようになります。出力から EXTERNAl_IP_ADDRESS をコピーします。

        IPAddress: EXTERNAl_IP_ADDRESS
        ...
        
      2. ローカル bash 変数を作成します。

        export LOAD_BALANCER_IP=EXTERNAl_IP_ADDRESS
        

        EXTERNAl_IP_ADDRESS は、コピーした外部 IP アドレスに置き換えます。

    3. ロードバランサがトラフィックを配信しているゾーンをモニタリングするには、次の bash スクリプトを実行します。

      while true
      do
          BODY=$(curl -s "$LOAD_BALANCER_IP")
          NAME=$(echo -n "$BODY" | grep "load-balancing-web-app-group" | perl -pe 's/.+?load-balancing-web-app-group-(.+?)<.+/\1/')
          ZONE=$(echo -n "$BODY" | grep "us-" | perl -pe 's/.+?(us-.+?)<.+/\1/')
          echo $ZONE
          sleep 2 # Wait for 2 seconds
      done
      

      このスクリプトは、ロードバランサのフロントエンドの IP アドレスを使用してウェブ アプリケーションへの接続を継続的に試行し、接続ごとにウェブ アプリケーションが実行されているゾーンを出力します。

      結果の出力には、us-central1-bus-central1-cus-central1-f のゾーンが含まれます。

      us-central1-f
      us-central1-b
      us-central1-c
      us-central1-f
      us-central1-f
      us-central1-c
      us-central1-f
      us-central1-c
      us-central1-c
      

      このターミナルは開いたままにしておきます。

  2. モニタリングの実行中に、ゾーン停止のシミュレーションを開始します。

    1. Cloud Shell で、 [追加] ボタンをクリックして、2 番目のターミナル セッションを開きます
    2. プロジェクト ID のローカル bash 変数を作成します。

      export PROJECT_ID=PROJECT_ID
      

      ここで、PROJECT_ID は、現在のプロジェクトのプロジェクト ID です。この値は Cloud Shell のすべての新しい行に表示されます。

      user@cloudshell:~ (PROJECT_ID)$
      
    3. 無効にするゾーンのローカル bash 変数を作成します。ゾーン us-central1-f の障害をシミュレートするには、次のコマンドを使用します。

      export DISABLE_ZONE=us-central1-f
      

      次に、以下の bash スクリプトを実行します。このスクリプトにより、使用不能になったゾーンのデモウェブ アプリケーション インスタンスは、ロードバランサのヘルスチェックに対して異常レスポンスを出力します。異常レスポンスにより、ロードバランサはこれらのインスタンスへのトラフィックの配信を停止します。

      export MACHINES=$(gcloud --project=$PROJECT_ID compute instances list --filter="zone:($DISABLE_ZONE)" --format="csv(name,networkInterfaces[0].accessConfigs[0].natIP)" | grep "load-balancing-web-app-group")
      for i in $MACHINES;
      do
        NAME=$(echo "$i" | cut -f1 -d,)
        IP=$(echo "$i" | cut -f2 -d,)
        echo "Simulating zonal failure for zone $DISABLE_ZONE, instance $NAME"
        curl -q -s "http://$IP/makeUnhealthy" >/dev/null --retry 2
      done
      

      その少し後で、ロードバランサは異常が発生したゾーンへのトラフィックの配信を停止します。そのため、最初のターミナル ウィンドウでは、ゾーン us-central1-f が出力リストに表示されなくなります。

      us-central1-c
      us-central1-c
      us-central1-c
      us-central1-b
      us-central1-b
      us-central1-c
      us-central1-b
      us-central1-c
      us-central1-c
      

      これは、ロードバランサが、正常でかつ応答しているインスタンスにのみトラフィックを配信していることを示します。

      両方のターミナルを開いたままにしておきます。

    4. 第 2 のターミナルで、復元するゾーンのローカル bash 変数を作成します。ゾーン us-central1-f へのトラフィックを復元するには、次のコマンドを使用します。

      export ENABLE_ZONE=us-central1-f
      

      次に、以下の bash スクリプトを実行します。このスクリプトにより、使用可能になったゾーンのデモウェブ アプリケーション インスタンスは、ロードバランサのヘルスチェックに対して正常レスポンスを出力します。正常レスポンスにより、ロードバランサはこれらのインスタンスへのトラフィックの配信を再開します。

      export MACHINES=$(gcloud --project=$PROJECT_ID compute instances list --filter="zone:($ENABLE_ZONE)" --format="csv(name,networkInterfaces[0].accessConfigs[0].natIP)" | grep "load-balancing-web-app-group")
      for i in $MACHINES;
      do
        NAME=$(echo "$i" | cut -f1 -d,)
        IP=$(echo "$i" | cut -f2 -d,)
        echo "Simulating zonal restoration for zone $ENABLE_ZONE, instance $NAME"
        curl -q -s "http://$IP/makeHealthy" >/dev/null --retry 2
      done
      

      数分で、1 つ目のターミナル ウィンドウの出力リストにゾーン us-central1-f が表示される回数が徐々に増えていきます。

      us-central1-b
      us-central1-b
      us-central1-c
      us-central1-f
      us-central1-c
      us-central1-c
      us-central1-b
      us-central1-c
      us-central1-f
      

      これは、ロードバランサが、元のように、すべてのゾーンに着信トラフィックを配信していることを示します。

      確認が終わったら、両方のターミナルを閉じます。