Compute Engine での Python Bookshelf の実行

このチュートリアルでは、Compute Engine 上で Python Bookshelf アプリを実行する方法について説明します。このチュートリアルに沿って、既存の Python ウェブアプリを Compute Engine にデプロイします。App Engine スタンダード環境のチュートリアルの一部として、Bookshelf アプリのドキュメントを参照することを強くおすすめします。

目標

  • 単一の Compute Engine インスタンスに Bookshelf サンプルアプリをデプロイします。
  • マネージド インスタンス グループを使用して、アプリの水平スケーリングを行います。
  • HTTP 負荷分散を使用して、トラフィックを処理します。
  • 自動スケーリングを使用して、トラフィックの変化に対応します。

料金

このチュートリアルでは、以下を含む Google Cloud Platform(GCP)の課金対象コンポーネントを使用します。

  • Compute Engine
  • Cloud Storage
  • Cloud Datastore
  • Stackdriver Logging
  • Cloud Pub/Sub

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。 GCP を初めて使用される方は、無料トライアルをご利用いただけます。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。 詳しくは、課金を有効にする方法をご覧ください。

  4. Cloud Datastore、Cloud Storage、Cloud Pub/Sub API を有効にします。

    APIを有効にする

  5. Cloud SDK をインストールして初期化します。
  6. Python、pip、virtualenv をシステムにインストールします。手順については、Google Cloud Platform 用の Python 開発環境のセットアップをご覧ください。

Cloud Datastore の初期化

Bookshelf アプリは Cloud Datastore を使用して書籍情報を格納します。プロジェクトの Cloud Datastore を初めて初期化する場合には、次の操作を行います。

  1. GCP Console で Cloud Datastore を開きます。

  2. データストアのリージョンを選択して、[続行] をクリックします。[エンティティの作成] ページが表示されたらウィンドウを閉じます。これで、Bookshelf アプリから Cloud Datastore にエンティティを作成する準備ができました。

Cloud Storage バケットの作成

Cloud Storage バケットを作成する手順は次のとおりです。バケットは、Cloud Storage でデータを格納する基本的なコンテナです。

  1. ターミナル ウィンドウで次のコマンドを入力します。

    gsutil mb gs://[YOUR-BUCKET-NAME]

    [YOUR-BUCKET-NAME] は、Cloud Storage バケットの名前を表します。

  2. Bookshelf アプリでアップロードした画像を表示するには、バケットのデフォルトのアクセス制御リスト(ACL)を public-read に設定します。

    gsutil defacl set public-read gs://[YOUR-BUCKET-NAME]

サンプルアプリのクローンを作成する

サンプルアプリは、GitHub の GoogleCloudPlatform/getting-started-python から入手できます。

  1. リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/getting-started-python.git
    
  2. サンプル ディレクトリに移動します。

    cd getting-started-python/7-gce
    

アプリを構成する

  1. config.py を編集用に開きます。

  2. PROJECT_ID の値をプロジェクト ID に設定します。

  3. CLOUD_STORAGE_BUCKET の値を、お使いの Cloud Storage バケット名に設定します。

  4. config.py を保存して閉じます。

ローカル パソコン上でのアプリの実行

  1. 隔離された Python 環境を作成し、依存関係をインストールします。

    Linux / MacOS

    virtualenv -p python3 env
    source env/bin/activate
    pip install -r requirements.txt
    

    Windows

    virtualenv -p python3 env
    env\scripts\activate
    pip install -r requirements.txt
    

  2. ローカルで Honcho を使用して、アプリケーションとタスクワーカーの両方を実行します。Honocho の詳しい使用方法は、本チュートリアルの Cloud Pub/Sub に関するパートをご覧ください。

    honcho start -f ./procfile worker bookshelf

  3. ウェブブラウザに次のアドレスを入力します。

    http://localhost:8080

両方のローカルタスクを停止するには、Control+C キーを押します。

単一インスタンスにデプロイする

単一インスタンスのデプロイメント

このセクションでは、Compute Engine 上でアプリの単一インスタンスを実行する手順について説明します。

コードをリポジトリに push する

Cloud Source Repositories を使用してプロジェクトに Git リポジトリを作成し、そこにアプリコードをアップロードできます。そうすると、起動時にリポジトリから最新バージョンのアプリのコードを pull できます。これにより、アプリの更新時に新しいイメージやインスタンスを構成する必要がないため便利です。必要な操作は、既存のインスタンスの再起動または新しいインスタンスの作成のみです。

Git を初めて使用する場合は、git config --global を使用して自分の ID を設定します。

  1. Google Cloud Platform Console でリポジトリを作成します。

    リポジトリを作成

    gcloud を使用してリポジトリを作成することもできます。

    gcloud source repos create [YOUR_REPO]
    

    ここで:

    • [YOUR_PROJECT_ID] は実際のプロジェクト ID です。
    • [YOUR_REPO] は、作成するリポジトリの名前です。
  2. アプリのコードをプロジェクトのリポジトリに push します。

    git commit -am "Updating configuration"
    git config credential.helper gcloud.sh
    git remote add cloud https://source.developers.google.com/p/[YOUR_PROJECT_ID]/r/[YOUR_REPO]
    git push cloud master
    

起動スクリプトを使用してインスタンスを初期化する

Compute Engine インスタンスからアクセスできる場所にコードを配置したので、次は、コードのダウンロードと実行をインスタンスに指示します。インスタンスには起動スクリプトを設定できます。起動スクリプトはインスタンスが起動するときや再起動するときに必ず実行されます。

Bookshelf サンプルアプリに含まれる起動スクリプトは次のとおりです。

set -v

# Talk to the metadata server to get the project id
PROJECTID=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")

# Install logging monitor. The monitor will automatically pickup logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

# Install dependencies from apt
apt-get update
apt-get install -yq \
    git build-essential supervisor python python-dev python-pip libffi-dev \
    libssl-dev

# Create a pythonapp user. The application will run as this user.
useradd -m -d /home/pythonapp pythonapp

# pip from apt is out of date, so make it update itself and install virtualenv.
pip install --upgrade pip virtualenv

# Get the source code from the Google Cloud Repository
# git requires $HOME and it's not set during the startup script.
export HOME=/root
git config --global credential.helper gcloud.sh
git clone https://source.developers.google.com/p/$PROJECTID/r/[YOUR_REPO_NAME] /opt/app

# Install app dependencies
virtualenv -p python3 /opt/app/7-gce/env
source /opt/app/7-gce/env/bin/activate
/opt/app/7-gce/env/bin/pip install -r /opt/app/7-gce/requirements.txt

# Make sure the pythonapp user owns the application code
chown -R pythonapp:pythonapp /opt/app

# Configure supervisor to start gunicorn inside of our virtualenv and run the
# application.
cat >/etc/supervisor/conf.d/python-app.conf << EOF
[program:pythonapp]
directory=/opt/app/7-gce
command=/opt/app/7-gce/env/bin/honcho start -f ./procfile worker bookshelf
autostart=true
autorestart=true
user=pythonapp
# Environment variables ensure that the application runs inside of the
# configured virtualenv.
environment=VIRTUAL_ENV="/opt/app/7-gce/env",PATH="/opt/app/7-gce/env/bin",\
    HOME="/home/pythonapp",USER="pythonapp"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

# Application should now be running under supervisor

このスクリプトを使用するには、[YOUR_REPO_NAME] を実際のリポジトリ名で置き換えます。

起動スクリプトによって次のアクションが実行されます。

  • Stackdriver Logging エージェントをインストールします。このエージェントは syslog から自動的にログを収集します。

  • Python と Supervisor をインストールします。 Supervisor はアプリをデーモンとして実行します。

  • Cloud Source Repositories 内にあるアプリのソースコードのクローンを作成し、依存関係をインストールします。

  • アプリを実行するように Supervisor を構成します。アプリが予期せずに終了した場合や、管理者や他のプロセスにより強制終了された場合、Supervisor によりアプリを確実に再起動できます。また、Supervisor によりアプリの stdoutstderr が syslog に送信され、Logging エージェントによって収集されます。

Compute Engine インスタンスの作成と構成

  1. Compute Engine インスタンスを作成します。次のコマンドで、新しいインスタンスを作成し、GCP サービスへのアクセスを許可し、起動スクリプトを実行します。インスタンス名は my-app-instance です。

    Linux / MacOS

    gcloud compute instances create my-app-instance \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --machine-type=g1-small \
        --scopes userinfo-email,cloud-platform \
    
        --metadata-from-file startup-script=gce/startup-script.sh \
        --zone us-central1-f \
        --tags http-server
    

    Windows

    gcloud compute instances create my-app-instance ^
        --image-family=debian-9 ^
        --image-project=debian-cloud ^
        --machine-type=g1-small ^
        --scopes userinfo-email,cloud-platform ^
        --metadata-from-file startup-script=gce/startup-script.sh ^
        --zone us-central1-f ^
        --tags http-server
    

  2. インスタンス作成の進行状況を確認します。

    gcloud compute instances get-serial-port-output my-app-instance --zone us-central1-f
    

    起動スクリプトが完了すると、コマンド出力の最後の近くに「Finished running startup script」と表示されます。

  3. インスタンスへのトラフィックを許可するファイアウォール ルールを作成します。

    Linux / MacOS

    gcloud compute firewall-rules create default-allow-http-8080 \
        --allow tcp:8080 \
        --source-ranges 0.0.0.0/0 \
        --target-tags http-server \
        --description "Allow port 8080 access to http-server"
    

    Windows

    gcloud compute firewall-rules create default-allow-http-8080 ^
        --allow tcp:8080 ^
        --source-ranges 0.0.0.0/0 ^
        --target-tags http-server ^
        --description "Allow port 8080 access to http-server"
    

  4. インスタンスの外部 IP アドレスを取得します。

    gcloud compute instances list
    
  5. 実行中のアプリを確認するために、http://[YOUR_INSTANCE_IP]:8080 に移動します。

    [YOUR_INSTANCE_IP] は、実際のインスタンスの外部 IP アドレスで置き換えてください。

インスタンスの管理とモニタリング

Google Cloud Platform Console を使用して、インスタンスのモニタリングと管理ができます。

実行中のインスタンスを表示し、ssh を使用してそのインスタンスに接続するには、[コンピューティング] > [Compute Engine] に移動します。

Compute Engine リソースによって生成されたすべてのログを表示するには、[モニタリング] > [ログ] に移動します。 Stackdriver Logging は、syslog などの一般的な各種サービスからログを収集するように自動的に構成されます。

複数のインスタンスによる水平スケーリング

マネージド インスタンスによる複数インスタンスのデプロイメント

Compute Engine では、水平スケーリングを容易に行えます。マネージド インスタンス グループと Compute Engine Autoscaler を使用することにより、Compute Engine は、必要なときに自動的にアプリの新しいインスタンスを作成し、要求が少ない場合はインスタンスをシャットダウンできます。HTTP ロードバランサをセットアップすると、マネージド インスタンス グループ内の各インスタンスにトラフィックを分散できます。

デプロイメント スクリプト

サンプルアプリには、後続のデプロイメント手順を自動化するスクリプトが含まれています。deploy.sh という名前のスクリプトは、完全に自動スケーリングされた負荷分散アプリのリソースをデプロイします。詳細については、複数のインスタンスによる水平スケーリングをご覧ください。

次の各ステップを自分で実行することも、gce/deploy.shgce ディレクトリから実行することもできます。

$IMAGE_FAMILY、$IMAGE_PROJECT、$MACHINE_TYPE、$SCOPES などの環境変数のデフォルト値は、gce/deploy.sh の初期化セクションで確認できます。

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

マネージド インスタンス グループは、同じインスタンス テンプレートに基づく同種のインスタンスのグループです。インスタンス テンプレートは、ソースイメージやディスクサイズ、スコープ、メタデータ(例: 起動スクリプト)など、インスタンスの構成を定義します。

  1. まず、テンプレートを作成します。

    gcloud compute instance-templates create $TEMPLATE \
      --image-family $IMAGE_FAMILY \
      --image-project $IMAGE_PROJECT \
      --machine-type $MACHINE_TYPE \
      --scopes $SCOPES \
      --metadata-from-file startup-script=$STARTUP_SCRIPT \
      --tags $TAGS
  2. インスタンス グループを作成します。

    gcloud compute instance-groups managed \
      create $GROUP \
      --base-instance-name $GROUP \
      --size $MIN_INSTANCES \
      --template $TEMPLATE \
      --zone $ZONE

    --size パラメータは、グループ内のインスタンス数を指定します。すべてのインスタンスが起動スクリプトの実行を完了した後、各インスタンスの外部 IP アドレスとポート 8080 を使用して各インスタンスに個別にアクセスできます。インスタンスの外部 IP アドレスを調べるには、「gcloud compute instances list」と入力します。マネージド インスタンスには、同じプレフィックス my-app で始まる名前が付きます。これは --base-instance-name パラメータで指定したものです。

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

テストやデバッグであれば単独のインスタンスでも十分ですが、ウェブ トラフィックを処理するのであれば、ロードバランサを使用して、利用できる複数のインスタンスの間で自動的にトラフィックを分配することをおすすめします。ロードバランサを作成する手順は次のとおりです。

  1. ヘルスチェックを作成します。ロードバランサは、ヘルスチェックを使用して、トラフィックを処理できるインスタンスを判断します。

    gcloud compute http-health-checks create ah-health-check \
      --request-path /_ah/health \
      --port 8080
  2. 名前付きポートを作成します。HTTP ロードバランサが http サービスを検索して、トラフィックの送信先ポートを確認します。既存のインスタンス グループで、ポート 8080 に名前 http を指定します。

    gcloud compute instance-groups managed set-named-ports \
        $GROUP \
        --named-ports http:8080 \
        --zone $ZONE
  3. バックエンド サービスを作成します。バックエンド サービスは、負荷分散されたトラフィックのターゲットとして機能します。バックエンド サービスにより、トラフィックの送信先となるインスタンス グループおよび使用するヘルスチェックが定義されます。

    gcloud compute backend-services create $SERVICE \
      --http-health-checks ah-health-check \
      --global
  4. バックエンド サービスを追加します。

    gcloud compute backend-services add-backend $SERVICE \
      --instance-group $GROUP \
      --instance-group-zone $ZONE \
      --global
  5. URL マップとプロキシを作成します。URL マップは、どの URL がどのバックエンド サービスにつながるのかを定義します。今回のサンプルでは、1 つのバックエンド サービスですべてのトラフィックを処理しています。複数のリージョンやグループ間でリクエストを負荷分散する場合は、複数のバックエンド サービスを作成します。プロキシは、トラフィックを受信し、URL マップを使用してトラフィックをバックエンド サービスに転送します。

    1. URL マップを作成します。

      gcloud compute url-maps create $SERVICE-map \
        --default-service $SERVICE
    2. プロキシを作成します。

      gcloud compute target-http-proxies create $SERVICE-proxy \
        --url-map $SERVICE-map
  6. グローバル転送ルールを作成します。グローバル転送ルールは、公開 IP アドレスとポートをプロキシに関連付けます。

    gcloud compute forwarding-rules create $SERVICE-http-rule \
      --global \
      --target-http-proxy $SERVICE-proxy \
      --ports=80

オートスケーラーを構成する

ロードバランサにより、すべての正常なインスタンス間でトラフィックが分散されます。しかし、すべてのインスタンスを合わせても処理できないほどのトラフィックが生じた場合にはどうなるでしょうか。インスタンスを手動で追加することもできます。しかしながら、それよりも良い方法として Compute Engine Autoscaler があります。Compute Engine Autoscaler を構成して、トラフィックの需要に応じてインスタンスが自動的に作成、削除されるようにします。

  1. オートスケーラーを作成します。

    gcloud compute instance-groups managed set-autoscaling \
      $GROUP \
      --max-num-replicas $MAX_INSTANCES \
      --target-load-balancing-utilization $TARGET_UTILIZATION \
      --zone $ZONE

    上記のコマンドにより、マネージド インスタンス グループにオートスケーラーが作成され、最大 10 個のインスタンスまで自動的にスケーリングされます。ロードバランサの使用率が 50% を超えると新しいインスタンスが追加され、使用率が 50% を下回るとインスタンスが削除されます。

  2. ファイアウォール ルールを作成します。

    # Check if the firewall rule has been created in previous steps of the documentation
    if gcloud compute firewall-rules list --filter="name~'default-allow-http-8080'" \
      --format="table(name)" | grep -q 'NAME'; then
      echo "Firewall rule default-allow-http-8080 already exists."
    else
      gcloud compute firewall-rules create default-allow-http-8080 \
        --allow tcp:8080 \
        --source-ranges 0.0.0.0/0 \
        --target-tags http-server \
        --description "Allow port 8080 access to http-server"
    fi
    

  3. 少なくとも 1 つのインスタンスが HEALTHY を報告するまで、進行状況を確認します。

    gcloud compute backend-services get-health frontend-web-service --global
    

アプリの表示

  1. ロードバランサの転送 IP アドレスを取得します。

    gcloud compute forwarding-rules list --global
    

    転送ルールの IP アドレスは IP_ADDRESS 列に表示されます。

  2. リストから取得した IP アドレスをブラウザに入力します。負荷分散型の自動スケーリング アプリが Compute Engine 上で動作していることを確認します。

デプロイの管理とモニタリング

複数のインスタンスであっても、単一のインスタンスと同じように簡単に管理できます。負荷分散、自動スケーリング、マネージド インスタンス グループをモニタリングするには、GCP Console を使用します。

インスタンス グループと自動スケーリングの構成を管理するには、[Compute Engine] > [インスタンス グループ] セクションを使用できます。

URL マップやバックエンド サービスなど、負荷分散の構成を管理するには、[ネットワーク サービス] > [負荷分散] セクションを使用できます。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

破棄スクリプトを実行する

deploy.sh スクリプトを実行した場合、teardown.sh スクリプトを実行すると、deploy.sh スクリプトによって作成されたリソースをすべて削除できます。これにより、プロジェクトが deploy.sh スクリプトの実行前の状態に戻るので、以降の課金を回避できます。チュートリアルの開始時に作成した単一インスタンスとストレージ バケットを削除するには、次のセクションの手順に従ってください。

手動でリソースを削除する

このチュートリアルの手順を手動で進めてきた場合、作成したクラウド リソースを手動で削除できます。

ロードバランサの削除

  1. GCP Console で [負荷分散] ページに移動します。

    [負荷分散] ページに移動

  2. 削除するロードバランサの横のチェックボックスをオンにします。

  3. ページの上部にある [削除] ボタンをクリックして、ロードバランサを削除します。

  4. [ロードバランサの削除] ダイアログで、関連付けられているバックエンド サービスとヘルスチェック リソースを選択します。

  5. [ロードバランサの削除] ボタンをクリックして、ロードバランサとそれに関連付けられているリソースを削除します。

Compute Engine マネージド インスタンス グループの削除

Compute Engine インスタンス グループを削除するには:

  1. GCP Console で、[インスタンス グループ] ページに移動します。

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

  2. 次のチェックボックスをオンにします。 削除するインスタンス グループ。
  3. インスタンス グループを削除するには、ページの上部にある [削除]()をクリックします。

1 つの Compute Engine インスタンスの削除

Compute Engine インスタンスを削除するには:

  1. GCP Console の [VM インスタンス] ページに移動します。

    [VM インスタンス] ページに移動

  2. 次のチェックボックスをオンにします。 削除するインスタンス。
  3. インスタンスを削除するには、[削除] () をクリックします。

Cloud Storage バケットの削除

Cloud Storage バケットを削除するには:

  1. GCP Console で、Cloud Storage ブラウザページに移動します。

    Cloud Storage ブラウザページに移動

  2. 削除するバケットのチェックボックスをクリックします。
  3. バケット削除するには、[削除]()をクリックします。

次のステップ

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

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