Google Compute Engine Autoscaler を使用した一括処理

このチュートリアルでは、Google Cloud Platform のいくつかの機能(マネージド インスタンス グループ自動スケーリングHTTP 負荷分散オブジェクト変更通知)を使用してアプリケーションを設定します。このアプリケーションは、イメージを入力として受け取って、そのイメージのサムネイルを作成します。このチュートリアルで学ぶ概念は、受信したアセットをワークロードの変化に基づいて動的に処理するあらゆるアプリケーションに幅広く応用できます。たとえば次のようなシナリオに応用できます。

  • 音声、動画、画像の処理
  • サーバー側一括操作のスケーリング

次の図は、サンプル アプリケーションのアーキテクチャを示しています。

サンプル アプリケーションのアーキテクチャ
図1: アプリケーション アーキテクチャ

アプリケーション フローの詳細は次のとおりです。

  1. 新しいファイルが追加されると、Google Cloud Storage の入力バケットから Google App Engine の通知処理アプリケーションに、オブジェクト変更通知を使用して通知が送られます。
  2. App Engine アプリケーションは、オブジェクト変更通知を処理し、対応するタスクを作成して、作成したタスクをタスクキューに配置します。
  3. タスクキューは、タスクを HTTP ロードバランサに HTTP POST リクエストとして送信します。
  4. HTTP ロードバランサは、タスクを受け入れて入力画像の処理を開始できる仮想マシン インスタンスを選択します。ロードバランサの受信負荷がその合計処理能力の一定の割合に達すると、Compute Engine Autoscaler がターゲット マネージド インスタンス グループに新しい Compute Engine 仮想マシン インスタンスを作成します。新しいインスタンスには画像処理アプリケーションのコピーが含まれます。
  5. 画像処理アプリケーションのコピーにより、入力バケットの各画像のサムネイルが作成されて、出力バケットに配置されます。

目標

  • Google Compute Engine 仮想マシン インスタンスのマネージド グループを作成する
  • Compute Engine の HTTP 負荷分散を設定する
  • 自動スケーリングのための Compute Engine Autoscaler を設定する
  • すべてを組み合わせて、インスタンスの負荷分散自動スケーリング グループを作成する
  • デモ アプリケーションをデプロイして実行する

新しい Cloud Platform Console プロジェクトの作成と設定

  1. Google Cloud Platform Console でプロジェクトを作成するか、既存のプロジェクトを使用します。

    デプロイされている他のアプリケーション(特に App Engine のアプリケーション)との競合を避けるために、新しいプロジェクトを使用することをおすすめします。

  2. {% dynamic if "no_credentials" in setvar.task_params %}{% dynamic setvar credential_type %}NO_AUTH{% dynamic endsetvar %}{% dynamic if not setvar.redirect_url %}{% dynamic setvar redirect_url %}https://console.cloud.google.com{% dynamic endsetvar %}{% dynamic endif %}{% dynamic endif %}{% dynamic if setvar.in_henhouse_no_auth_whitelist %}{% dynamic if not setvar.credential_type %}{% dynamic setvar credential_type %}NO_AUTH{% dynamic endsetvar %}{% dynamic endif %}{% dynamic elif setvar.in_henhouse_service_account_whitelist %}{% dynamic if not setvar.credential_type %}{% dynamic setvar credential_type %}SERVICE_ACCOUNT{% dynamic endsetvar %}{% dynamic endif %}{% dynamic endif %}{% dynamic if not setvar.service_account_roles and setvar.credential_type == "SERVICE_ACCOUNT" %}{% dynamic setvar service_account_roles %}{% dynamic endsetvar %}{% dynamic endif %}{% dynamic setvar console %}{% dynamic if "no_steps" not in setvar.task_params %}

  3. {% dynamic endif %}{% dynamic if setvar.api_list %}{% dynamic if setvar.in_henhouse_no_auth_whitelist or setvar.in_henhouse_service_account_whitelist %}GCP Console プロジェクトをセットアップします。

    プロジェクトをセットアップする

    クリックして、以下を行います。

    • プロジェクトを作成または選択します。
    • プロジェクトに{% dynamic if setvar.api_names %}{% dynamic print setvar.api_names %}{% dynamic else %}必要な{% dynamic endif %}{% dynamic if "," in setvar.api_list %} API{% dynamic elif "API" in setvar.api_names %}{% dynamic else %} API{% dynamic endif %} を有効にします。
    • {% dynamic if setvar.credential_type == 'SERVICE_ACCOUNT' %}
    • サービス アカウントを作成します。
    • JSON として秘密鍵をダウンロードします。
    • {% dynamic endif %}

    これらのリソースは、GCP Console でいつでも表示および管理できます。

    {% dynamic else %}{% dynamic if "no_text" not in setvar.task_params %}{% dynamic if setvar.api_names %}{% dynamic print setvar.api_names %}{% dynamic else %}必要な{% dynamic endif %}{% dynamic if "," in setvar.api_list %} API{% dynamic elif "API" in setvar.api_names %}{% dynamic else %} API{% dynamic endif %} を有効にします。 {% dynamic endif %}

    {% dynamic if "," in setvar.api_list %}API{% dynamic else %}API{% dynamic endif %}を有効にする

    {% dynamic endif %}{% dynamic endif %}{% dynamic if "no_steps" not in setvar.task_params %}
  4. {% dynamic endif %}{% dynamic endsetvar %}{% dynamic print setvar.console %}

Google Cloud SDK の設定

このチュートリアルでは、Google Cloud SDK を使用してプロジェクトとサンプル アプリケーションを設定します。Cloud SDK のクイック スタートの手順に沿って Cloud SDK をインストールし、自分のアカウントを使用できるように承認します。

次に、作成するリソースのゾーンを選択します。このチュートリアルでは us-central1-f ゾーンを使用します。このゾーンの変数を設定します。

$ ZONE="us-central1-f"

マネージド インスタンス グループの作成

マネージド インスタンス グループとは、共通のテンプレートを使用して設定された同一のインスタンスからなるマネージド グループです。このチュートリアルでは、オートスケーラーがマネージド インスタンス グループの仮想マシン インスタンスをプロビジョニングします。仮想マシン インスタンスは、ロードバランサの負荷に基づいて作成または削除されます。

マネージド インスタンス グループを作成するには、まず、新しいインスタンス テンプレート(imagemagick-go-template)を作成します。

gcloud compute instance-templates create imagemagick-go-template \
    --description "A pool of machines running our ImageMagick service." \
    --image debian-7 \
    --machine-type n1-standard-1 \
    --metadata goprog="http://storage.googleapis.com/imagemagick/compute/web-process-image.go" \
    startup-script-url="gs://imagemagick/compute/scripts/startup-test-go.sh" \
    --boot-disk-size 200GB \
    --scopes storage-full \
    --tags http-lb

このテンプレートでは、グループに含まれるインスタンスの基本設定を指定するために次のフラグが設定されています。

  • --description: テンプレートの説明。
  • --image: 使用するオペレーティング システム イメージ
  • --machine-type: 使用する Google Cloud Platform マシンタイプ
  • --boot-disk-size: ブートディスクのサイズ。
  • --scopes: インスタンスから Google Cloud Storage API を呼び出せるようにします。
  • --tags: インスタンスにラベルを割り当てて、グループとして操作できるようにします。このチュートリアルでは、http-lb というラベルが付いたインスタンスにファイアウォール ルールを適用します。
  • --metadata: 一連の Key-Value ペアを指定して、さまざまなメタデータ属性を定義できます。ここでは次の属性が定義されています。
    • goprog: 各インスタンスで実行されるアプリケーション スクリプトが置かれている Google Cloud Storage 内の場所。
    • startup-script-url: 各インスタンスのプロビジョニングに使用される起動スクリプトの URL。

次に、マネージド インスタンス グループ(imagemagick-go)を作成します。このグループに追加されたすべての新しい仮想マシン インスタンスのテンプレートとして、上で作成したインスタンス テンプレートを使用します。

gcloud compute instance-groups managed create imagemagick-go \
    --base-instance-name imagemagick-go \
    --size 1 \
    --template imagemagick-go-template \
    --zone $ZONE

上のコマンドでは、テンプレート名のほかに、インスタンス グループが実行されるゾーン、インスタンス名に使用するベース インスタンス名、最初に作成するインスタンスの数も指定しています。

HTTP ロードバランサの作成

このチュートリアルでは、HTTP ロードバランサを使用して、受信トラフィックをマネージド インスタンス グループに転送します。ロードバランサを設定した後、HTTP ロードバランサの合計処理能力の割合に基づいて自動スケーリングが行われるようにグループを設定します。ロードバランサの使用率がその割合を超えるとオートスケーラーが追加のインスタンスを起動し、その割合を下回ると不要なインスタンスをシャットダウンします。

ロードバランサは、次の図に示すように、受信リクエストを適切なバックエンドにルーティングする一連のリソースで構成されています。

HTTP ロードバランサの概要
HTTP ロードバランサの概要(クリックで拡大)

受信トラフィックは、グローバル転送ルールを使用してターゲット HTTP プロキシにルーティングされます。このプロキシは、URL マップを使用して、トラフィックのルーティング先となるバックエンド サービスを特定します。バックエンド サービスは、接続済みの各バックエンドのリージョン、CPU 負荷、リクエスト レートの制約に基づいて、トラフィックをそれらのバックエンドに分散します。

ヘルスチェックの作成

ロードバランサには、バックエンド サービスがバックエンドの状態を確認するために使用できる HTTP ヘルスチェック リソースが必要です。これにより、起動していて接続を受け付けることができるインスタンスにのみ新しい接続が転送されるようになります。

ヘルスチェックを作成して、リクエストパスを "/healthcheck" と定義します。

gcloud compute http-health-checks create imagemagick-check \
    --request-path "/healthcheck"

バックエンド サービスの作成と設定

HTTP ヘルスチェックを作成したら、バックエンド サービスを作成して、作成したリソースを必須の HTTP ヘルスチェックとして設定します。

gcloud compute backend-services create imagemagick-backend-service \
    --http-health-check imagemagick-check

新しいバックエンド サービスのバックエンドとして imagemagick-go インスタンス グループを追加します。これにより、バックエンド サービスがこのインスタンス グループにトラフィックを転送できるようになります。

gcloud compute backend-services add-backend imagemagick-backend-service \
    --instance-group imagemagick-go \
    --balancing-mode UTILIZATION \
    --max-utilization 0.8 \
    --zone $ZONE

上のコマンドでは、この新しいバックエンドの分散モードが UTILIZATION に、最大 CPU 使用率が 0.8(80%)に設定されています。このロードバランサにはバックエンドが 1 つしかないため、ロードバランサの最大処理能力はバックエンドの最大 CPU 使用率に等しくなります。そのため、オートスケーラーを追加するときには、バックエンドの最大 CPU 使用率に基づいてスケールされるように設定します。

ロードバランサの完成

HTTP ロードバランサが正常に機能するためにはあと 4 つのコンポーネントが必要です。

  • URL マップ: ホストルールと URL パターン マッチングに基づいてリクエストをバックエンド サービスにルーティングします。
  • ターゲット HTTP プロキシ: グローバル転送ルールから受信した HTTP トラフィックを URL マップにルーティングします。
  • グローバル転送ルール: 受信トラフィックを指定のターゲット(この場合は HTTP プロキシ)にルーティングします。
  • ファイアウォール ルール: 指定のポートまたはポート範囲で受信トラフィックを許可します。

まず、すべての受信リクエストをバックエンド サービスに転送する新しい URL マップを作成します。

gcloud compute url-maps create imagemagick-map \
    --default-service imagemagick-backend-service

次に、リクエストを URL マップにルーティングするターゲット HTTP プロキシを作成します。

gcloud compute target-http-proxies create imagemagick-proxy \
    --url-map imagemagick-map

受信リクエストを処理してルーティングするグローバル転送ルールを作成します。

gcloud compute forwarding-rules create imagemagick-rule --global \
    --target-http-proxy imagemagick-proxy --port-range 80

最後に、http-lb というラベルが付いたインスタンスのポート 80 へのアクセスを許可するファイアウォール ルールを作成します。

gcloud compute firewall-rules create http-lb-rule \
    --target-tags http-lb --allow tcp:80

以上で、完全に機能する HTTP ロードバランサが完成しました。このロードバランサは、それぞれがアプリケーションのコピーを実行する仮想マシン インスタンスのマネージド グループの手前に置かれます。

オートスケーラーの作成と接続

次のコマンドを実行してオートスケーラーを作成します。

gcloud compute instance-groups managed set-autoscaling imagemagick-go \
    --max-num-replicas 23 \
    --min-num-replicas 2 \
    --target-load-balancing-utilization 0.5 \
    --zone $ZONE

このコマンドでは、いくつかの重要なパラメータが定義されています。これらのパラメータは、オートスケーラーが正常に機能するために必要です。

  • --target: インスタンスの最大数および最小数と連動して自動的にスケーリングされるマネージド インスタンス グループ。
  • --min-num-replicas: オートスケーラーが維持する必要があるレプリカの最小数。
  • --max-num-replicas: オートスケーラーが維持できるレプリカの最大数。
  • --target-load-balancing-utilization: オートスケーラーが維持する必要がある HTTP ロードバランサの使用率。この例では、ロードバランサのバックエンド サービスの使用率が最大使用率の半分(imagemagick-go)に達するとオートスケーラーが 0.5 に新しいインスタンスを追加します。

Google Cloud Storage バケットの作成と設定

この例では、Google Cloud Storage バケットを使用して、受信する画像と処理済みのサムネイルの両方を格納します。

アップロードされた画像を格納するための入力バケットと、処理済みのサムネイルを格納するための出力バケットの 2 つのバケットを作成する必要があります。バケット名は Google Cloud Storage 全体で一意でなければならないため、次の例のように、固有のプロジェクト ID を名前空間として使用することをおすすめします。

gsutil mb gs://${PROJECT_ID}-input-bucket gs://${PROJECT_ID}-output-bucket

Google App Engine アプリケーションのビルドとデプロイ

この例の App Engine アプリケーションは、新しい画像を処理できるようになると通知を受け取る単純なエンドポイントとして機能します。 ここからサンプルコードをダウンロードして、ローカル ディレクトリに解凍してください。代わりに GitHub プロジェクト レポジトリのクローンを作成することもできます。その場合は次のコマンドを実行します。

$ git clone https://github.com/GoogleCloudPlatform/httplb-autoscaling-go.git

ダウンロードしたレポジトリのローカル ルート ディレクトリを参照する新しい環境変数を作成します。

$ export EXAMPLE_DIR=local/path/to/httplb-autoscaling-go

次に、いくつかの設定を変更する必要があります。まず、ロードバランサの転送ルールの IP アドレスを取得します。

gcloud compute forwarding-rules list --global
NAME              REGION_IP_ADDRESS     IP_PROTOCOL   TARGET
imagemagick-rule  <ip_address>          TCP           imagemagick-proxy

$EXAMPLE_DIR/appengine に移動して、main.go を編集用に開きます。このファイルを次のように変更します。

  • processingPoolIp の値を、上で取得した IP アドレスに置き換えます。
  • saveToBucketName の値を、前に指定した出力バケットの名前(<project_id>-output-bucket)に置き換えます。

ファイルを保存して、次のようにアプリケーションをデプロイします。

gcloud preview app deploy $EXAMPLE_DIR/appengine/app.yaml $EXAMPLE_DIR/appengine/queue.yaml

オブジェクト変更通知の設定

この例では、入力バケットにアップロードされた新しい画像が自動的に処理されるようにするために、オブジェクト変更通知を使用します。オブジェクト変更通知では、バケットでオブジェクトの格納、更新、削除が行われるたびに、通知チャンネルに対するイベントが呼び出されます。

サービス アカウントの作成

オブジェクト変更通知を設定するにはサービス アカウントを作成する必要があります。 サービス アカウントを使用すると、Google サービスを別の Google サービスに対して認証することができます。新しいサービス アカウントを作成する手順は次のとおりです。

  1. Cloud Platform Console でサービス アカウント キーを作成します。

  2. [新しいサービス アカウント] をクリックして名前を入力します。後で使用するのでメールアドレスを書き留めておきます。

  3. [作成] をクリックして JSON サービス アカウント キーをダウンロードします。

  4. Cloud SDK でサービス アカウントを有効にします。

    gcloud auth activate-service-account --key-file <path_to_key_file> <service_account_email>
    

プッシュ通知の設定

オブジェクト変更通知を App Engine にプッシュできるように、プッシュ通知を登録する必要もあります。

  1. ブラウザで Google Search Console に移動します。
  2. [サイトを追加] をクリックします。
  3. プロジェクトの App Engine のアドレスを入力します。

    https://<project_id>.appspot.com
    
  4. [続行] をクリックします。

  5. メッセージが表示されたら確認ファイルをダウンロードします。
  6. ダウンロードしたファイルを $EXAMPLE_DIR/appengine にコピーします。

同じディレクトリで、app.yaml を編集用に開きます。次の行を見つけます。

- url: /.*
  script: _go_app

これらの行の前に次の行を追加して、ダウンロードした確認ファイルの場所を指定します。

handlers:
- url: /<your-downloaded-verification-file>
  static_files: <your-downloaded-verification-file>
  upload: <your-downloaded-verification-file>

アプリケーションを再デプロイします。

gcloud preview app deploy $EXAMPLE_DIR/appengine/app.yaml $EXAMPLE_DIR/appengine/queue.yaml

Search Console に戻り、[確認] をクリックします。サイトが確認されたことを示すページが表示されます。

ホワイトリストへのドメインの登録

オブジェクト変更通知のリクエストが正常に処理されるように、Cloud Platform Console プロジェクトでドメインをホワイトリストに登録する必要があります。ドメインをホワイトリストに登録する手順は次のとおりです。

  1. Cloud Platform Console の [ドメインの確認] ページで、[ドメインを追加] をクリックします。
  2. 表示されるダイアログで、ホワイトリストに登録するドメインを入力します。

    https://<project_id>.appspot.com
    
  3. [ドメインを追加] をクリックしてホワイトリストを保存します。

最後に、ローカル端末で次のコマンドを実行して、前に作成した Cloud Storage 入力バケットのオブジェクト変更通知を登録します。

gsutil notification watchbucket https://${PROJECT_ID}.appspot.com \
    gs://${PROJECT_ID}-input-bucket

デモ アプリケーションのテストとモニタリング

以上ですべての準備が整ったので、このデモ構成をテストすることができます。この構成をテストするには、HTTP ロードバランサの CPU 使用率の合計が 50% を超えるくらいのスピードで入力バケットに多数の画像をコピーする必要があります。これにより、オートスケーラーがトリガーされます。

各インスタンスの起動スクリプトにより、指定したバケットに同じ画像を 10,000 個追加する Go スクリプト(generate_files.go)がインストールされています。このスクリプトを使用してアプリケーションをテストするには、まず、SDK アカウントをデフォルトのユーザー アカウントに戻します。

gcloud config set account <user_email>

次に、Cloud Storage の一時バケットを作成します。このバケットは、スクリプトによって生成された画像を保持するために使用します。

gsutil mb gs://${PROJECT_ID}-tmp-bucket

いずれかのインスタンスに SSH 接続します。

gcloud compute ssh <instance>

SSH 端末で環境変数の GOPATHPATH を設定して、スクリプトを実行できるようにします。

user@instance~:$ export GOPATH=/usr/local
user@instance~:$ export PATH=$PATH:/usr/local/go/bin

スクリプトを実行して、画像を新しい一時バケットにコピーします。

user@instance~:$ go run /tmp/generate_files.go <project_id>-tmp-bucket /tmp/eiffel.jpg

スクリプトの実行が終了したら、「exit」と入力して SSH 接続を閉じます。

一時バケットの準備が整ったので、ロードバランサとオートスケーラーに対する負荷を生成できます。次のコマンドを実行して、一時バケットの画像を入力バケットにコピーします。

gsutil -m cp -R gs://${PROJECT_ID}-tmp-bucket/* \
    gs://${PROJECT_ID}-input-bucket

コピープロセスを確認するには、Cloud Platform Console のインスタンス グループのページを表示します。このページには、マネージド インスタンス グループに関する情報(インスタンスの数など)が表示されます。インスタンス グループ名をクリックして実際のインスタンスを表示することもできます。

ロードバランサに関する情報を確認するには、コンソールの HTTP 負荷分散のページを表示します。このページには、設定したロードバランサの概要が表示されます。表の最初のリンク(imagemagick-map)をクリックすると、詳しい情報(バックエンド サービスに関連付けられているインスタンスの数など)が表示されます。

新しいインスタンスが作成されるたびに、インスタンス テンプレートに定義されているバイナリとスクリプトがダウンロードされてインストールされるため、新しいインスタンスが起動するまでに数分かかることがあります。その間は、オートスケーラーによって作成された新しいインスタンスの状態が PROVISIONING または STAGING になります。

まとめ

このチュートリアルでは、サーバー側一括処理フローの設計に使用できるいくつかの強力な概念について学びました。

  • Compute Engine Autoscaler を設定して、HTTP ロードバランサの受信ワークロードが指定のしきい値に達した場合にマネージド インスタンス グループのインスタンスをスケーリングする方法
  • HTTP ロードバランサを設定して、受信トラフィックをバックエンドに転送する方法
  • オブジェクト変更通知を使用して、Google Cloud Storage バケットに新しいコンテンツがアップロードされたらアプリケーションに通知する方法

このチュートリアルでは、一括処理フローで自動スケーリングを使用する方法について説明しましたが、ここで学んだ概念は、アプリケーションで自動スケーリングや負荷分散が重要となるあらゆる状況に応用できます。また、ここで作成したアプリケーションは、再利用したり、必要に応じて拡張したりできます。

サンプル アプリケーションのクリーンアップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Compute Engine ドキュメント