GCE を使用して Google Cloud でウェブアプリをホストする

Google Cloud 内にウェブサイトをデプロイする方法は多数あり、各ソリューションで提供される機能や制御レベルはそれぞれ異なります。Google Compute Engine(GCE とも呼ばれます)は、ウェブサイトを実行するために使用されるインフラストラクチャをより詳細に制御しますが、Google Kubernetes Engine(GKE)、Google App Engine(GAE)などのソリューションと比べて、運用管理は少し必要になります。Compute Engine では、仮想マシンやロードバランサなど、インフラストラクチャの要素をきめ細かく制御できます。ここでは、サンプルのアプリケーションとして Fancy Store e コマース ウェブサイトをデプロイし、Compute Engine でウェブサイトを簡単にデプロイし、スケーリングする方法を示します。

学習内容

この Codelab の最後に、マネージド インスタンス グループ内にインスタンスを作成し、ウェブサイトの自動修復、負荷分散、自動スケーリング、ローリング アップデートを提供します。

Prerequisites

セルフペース型の環境設定

Google アカウント(Gmail または Google Apps)をまだお持ちでない場合は、アカウントを作成する必要があります。Google Cloud Platform Console(console.cloud.google.com)にログインして、新しいプロジェクトを作成します。

2016-02-10 12:45:26.png のスクリーンショット

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

この Codelab を実施した場合、費用は数ドルを超えることはありませんが、より多くのリソースを使用する場合や、実行したままにしておくとさらにコストがかかる場合があります(このドキュメントの最後にある「クリーンアップ」セクションをご覧ください)。

Google Cloud Platform の新規ユーザーは 300 ドル分の無料トライアルをご利用いただけます。

Compute Engine API を有効にする

次に、Compute Engine API を有効にする必要があります。API を有効にするには、API の利用規約と請求責任に同意する必要があります。

Google Cloud Shell

Google Cloud と Kubernetes はノートパソコンからリモートで操作できますが、この Codelab では Cloud で実行されるコマンドライン環境である Google Cloud Shell を使用します。

この Debian ベースの仮想マシンには、必要な開発ツールがすべて読み込まれています。5 GB の永続的なホーム ディレクトリが Google Cloud 上で動作することで、ネットワーク パフォーマンスと認証が大幅に強化されます。この Codelab に必要なのはブラウザだけです(はい、Chromebook で動作します)。

Google Cloud Shell を有効にするには、デベロッパー コンソールで右上のボタンをクリックします(プロビジョニングと環境への接続にはそれほど時間はかかりません)。

activateCloudShell.png

[Cloud Shell の起動] ボタンをクリックします。

Screen Shot 2017-06-14 at 10.13.43 PM.png

Cloud Shell に接続すると、認証が完了していて、プロジェクトが PROJECT_ID に設定されていることがわかります。

gcloud auth list

コマンド出力

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

Cloud Shell では、いくつかの環境変数もデフォルトで設定します。これは、今後コマンドを実行するときに役立ちます。

echo $GOOGLE_CLOUD_PROJECT

コマンド出力

<PROJECT_ID>

なんらかの理由でプロジェクトが設定されていない場合は、単に次のコマンドを実行します。

gcloud config set project <PROJECT_ID>

PROJECT_ID が見つからない場合は、設定手順で使用した ID を確認するか、コンソール ダッシュボードで確認します。

プロジェクト ID.png

重要: 最後に、デフォルトのゾーンとプロジェクトの構成を設定します。

gcloud config set compute/zone us-central1-f

さまざまなゾーンを選択できます。詳しくは、リージョンとゾーンのドキュメントをご覧ください。

GCS バケットの作成

ここでは、Google Cloud Storage バケットを使用して、ビルドしたコードと起動スクリプトを格納します。Cloud Shell で次のコマンドを実行し、新しい GCS バケットを作成します。

gsutil mb gs://fancy-store-$DEVSHELL_PROJECT_ID

ここでは、モノリスからマイクロサービスへのリポジトリに基づいて、既存の Fancy Store e コマース ウェブサイトをベースとして使用します。Git リポジトリからソースコードのクローンを作成します。これにより、GCE へのデプロイに集中できるようになります。後ほど、この Codelab ではコードを簡単に更新し、GCE での更新が簡単であることを実証します。

下のボタンをクリックして、プロジェクトにコード リポジトリのクローンを作成し、Cloud Shell と組み込みのコードエディタを開きます。

Cloud Shell コマンド プロンプトでコードの初期ビルドを実行し、アプリケーションがローカルで実行されるようにします。このスクリプトの実行には数分かかる場合があります。

./setup.sh

デュー デリジェンスを行い、アプリケーションをテストします。次のコマンドを実行してウェブサーバーを起動します。

cd microservices
npm start

出力:

Products microservice listening on port 8092!
Frontend microservice listening on port 8090!
Orders microservice listening on port 8091!

アプリケーションをプレビューするには、ウェブ プレビュー アイコンをクリックして、[ポートの変更] を選択し、フロントエンド マイクロサービスのポート「8090」を入力します。[変更してプレビュー] を選択します。

新しいウィンドウが開き、Fancy Store のフロントエンドの動作が表示されます。

ウェブサイトを表示した後にこのウィンドウを閉じて、ウェブサーバー プロセスを停止するには、ターミナル ウィンドウで CTRL+C を押します。

作業環境が完成したので、Compute Engine インスタンスのデプロイを開始しましょう。手順は次のとおりです。

  1. 起動スクリプトを作成してインスタンスを構成する
  2. ソースコードのクローンを作成して Google Cloud Storage にアップロードする
  3. Compute Engine インスタンスをデプロイしてバックエンド マイクロサービスをホストする
  4. バックエンド マイクロサービス インスタンスを使用するようにフロントエンド コードを再構成する
  5. フロントエンド マイクロサービスをホストするために Compute Engine インスタンスをデプロイする
  6. 通信できるようにネットワークを構成する

起動スクリプトを作成する

インスタンスを希望どおりに構成できるようにするため、起動スクリプトを使用して、インスタンスを起動するたびにインスタンスの動作を実行するよう設定します。Cloud Shell 内のコードエディタ内で monolith-to-microservices フォルダに移動し、startup-script.sh というファイルを作成します。

この新しいファイルに次のコードを貼り付けます。貼り付け後にコードの一部を編集します。

#!/bin/bash

# Install logging monitor. The monitor will automatically pick up 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 ca-certificates git build-essential supervisor psmisc

# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm

# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-[DEVSHELL_PROJECT_ID]/monolith-to-microservices/microservices/* /fancy-store/

# Install app dependencies.
cd /fancy-store/
npm install

# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /opt/app

# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update

エディタで [DEVSHELL_PROJECT_ID] というテキストを探し、次のコマンドの出力に置き換えます。

echo $DEVSHELL_PROJECT_ID

出力例:

my-gce-codelab-253520

startup-script.sh 内のコードの行は、次のようになります。

gs://fancy-store-my-gce-codelab-253520/monolith-to-microservices/microservices/* /fancy-store/

起動スクリプトは次のタスクを実行します。

  • Logging エージェントをインストールします。このエージェントは syslog から自動的にログを収集します。
  • Node.js および Supervisor をインストールします。Supervisor はアプリをデーモンとして実行します。
  • GCS バケットからアプリのソースコードのクローンを作成し、依存関係をインストールします。
  • アプリを実行するように Supervisor を設定します。アプリが予期せずに終了した場合や、管理者や他のプロセスにより強制終了された場合、Supervisor はアプリを確実に再起動します。また、アプリの stdout と stderr を syslog に送信し、Logging エージェントが収集できるようにします。

作成した startup-script.sh ファイルを先ほど作成した GCS バケットにコピーします。

gsutil cp startup-script.sh gs://fancy-store-$DEVSHELL_PROJECT_ID

現在は、https://storage.googleapis.com/[BUCKET_NAME]/startup-script.sh からアクセスできます。[BUCKET_NAME] は Cloud Storage バケットの名前を表します。デフォルトでは、承認済みのユーザーとサービス アカウントでのみ表示可能で、ウェブブラウザでアクセスすることはできません。Google Compute Engine インスタンスには、サービス アカウントから自動的にアクセスできます。

GCS バケットへのコードのコピー

インスタンスは起動時に GCS バケットからコードを pull するため、コードの「.env'」ファイルにいくつかの構成変数を格納できます。

クローン作成したコードを GCS バケットにコピーします。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

バックエンド インスタンスのデプロイ

最初にデプロイするインスタンスは、注文とプロダクトのマイクロサービスを格納するバックエンド インスタンスです。

Cloud Shell で次のコマンドを実行して、先ほど作成した起動スクリプトを使用するように構成され、後で特定のファイアウォール ルールを適用できるように「backend」インスタンスとしてタグ付けされた f1-micro インスタンスを作成します。

gcloud compute instances create backend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=backend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh

バックエンドへの接続を構成する

アプリケーションのフロントエンドをデプロイする前に、デプロイしたばかりのバックエンドを指すように構成を更新する必要があります。

バックエンドの外部 IP アドレスを取得します。これは、バックエンド インスタンスの [EXTERNAL_IP] タブにある次のコマンドで確認できます。

gcloud compute instances list

出力例:

NAME     ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
backend  us-central1-a  f1-micro                   10.128.0.2   34.68.223.88  RUNNING

Cloud Shell のコードエディタに戻り、[monolith-to-microservices] -> [react-app] フォルダに移動します。コードエディタ メニューで、[View] → [Toggle Hidden Files] を選択して、「.env'」ファイルを表示します。

バックエンドの外部 IP アドレスを指定する「.env'」ファイルを編集します。以下の [BACKEND_ADDRESS] は、上記の gcloud コマンドで決定したバックエンド インスタンスの外部 IP アドレスを表します。

REACT_APP_ORDERS_URL=http://[BACKEND_ADDRESS]:8091/api/orders
REACT_APP_PRODUCTS_URL=http://[BACKEND_ADDRESS]:8092/api/products

react-app を再ビルドします。これにより、フロントエンド コードが更新されます。

npm install && npm run-script build

アプリケーション コードを GCS バケットにコピーします。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

フロントエンド インスタンスをデプロイする

コードが構成されたので、フロントエンド インスタンスをデプロイできます。次のコマンドを実行して、前と同様のコマンドでフロントエンド インスタンスをデプロイします。ただし、このインスタンスはファイアウォールの目的で「フロントエンド」タグが付けられています。

gcloud compute instances create frontend \
    --machine-type=f1-micro \
    --image=debian-9-stretch-v20190905 \
    --image-project=debian-cloud \
    --tags=frontend \
    --metadata=startup-script-url=https://storage.googleapis.com/fancy-store-$DEVSHELL_PROJECT_ID/startup-script.sh 

ネットワークを構成する

フロントエンドのポート 8090 とバックエンドのポート 8091 ~ 8092 へのアクセスを許可するファイアウォール ルールを作成します。これらのファイアウォール コマンドは、アプリケーションのインスタンス作成時に割り当てられたタグを使用します。

gcloud compute firewall-rules create fw-fe \
    --allow tcp:8090 \
    --target-tags=frontend
gcloud compute firewall-rules create fw-be \
    --allow tcp:8091-8092 \
    --target-tags=backend

ウェブサイトが機能するようになりました。フロントエンドの外部 IP に移動します。このアドレスは、フロントエンド インスタンスの EXTERNAL_IP を調べることで判断できます。

gcloud compute instances list

出力例:

NAME      ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP      STATUS
backend   us-central1-a  f1-micro                   10.128.0.2   104.198.235.171  RUNNING
frontend  us-central1-a  f1-micro                   10.128.0.3   34.69.141.9      RUNNING

ウェブサイトにアクセスするには http://[FRONTEND_ADDRESS]:8090 に移動します。ここで、[FRONTEND_ADDRESS] は上記で取得した EXTERNAL_IP です。インスタンスが起動して構成されるまでに数分かかることがあります。

[商品] ページと [注文] ページに移動してみます。これらは同じように機能します。

アプリケーションをスケーリングできるようにするために、マネージド インスタンス グループが作成され、フロントエンド インスタンスとバックエンド インスタンスがインスタンス テンプレートとして使用されます。

マネージド インスタンス グループ(MIG)には、単一のゾーンで単一のエンティティとして管理可能な同一のインスタンスが複数含まれます。マネージド インスタンス グループは、インスタンスの可用性を積極的に維持する(ステータスを RUNNING(実行中)の状態に保つ)ことで、アプリの高可用性を維持します。自動修復、負荷分散、自動スケーリング、ローリング アップデートを実現するために、フロントエンドとバックエンドのインスタンスでマネージド インスタンス グループを使用します。

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

マネージド インスタンス グループを作成するには、まず、グループの基礎となるインスタンス テンプレートを作成する必要があります。インスタンス テンプレートを使用することで、新しい VM インスタンスを作成する際に使用するマシンタイプ、ブートディスク イメージまたはコンテナ イメージ、ネットワーク、その他のインスタンス プロパティを定義できます。インスタンス テンプレートを使用すると、マネージド インスタンス グループにインスタンスを作成できます。また、インスタンスを個別に作成することもできます。

インスタンス テンプレートを作成するために、以前に作成した既存のインスタンスを使用します。まず、両方のインスタンスを停止する必要があります。

gcloud compute instances stop frontend
gcloud compute instances stop backend

次に、ソース インスタンスからインスタンス テンプレートを作成します。

gcloud compute instance-templates create fancy-fe \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a
gcloud compute instance-templates create fancy-be \
    --source-instance=backend \
    --source-instance-zone=us-central1-a

インスタンス テンプレートが作成されたことを確認します。

gcloud compute instance-templates list

出力例:

NAME      MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
fancy-be  f1-micro                   2019-09-12T07:52:57.544-07:00
fancy-fe  f1-micro                   2019-09-12T07:52:48.238-07:00

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

フロントエンド用とバックエンド用の 2 つのマネージド インスタンス グループを作成します。これらのマネージド インスタンス グループは、以前作成されたインスタンス テンプレートを使用し、各グループ内のそれぞれの 2 つのインスタンス用に構成されます。インスタンスには、「ベース インスタンス名」に基づいて自動的に命名され、ランダムな文字が追加されます。

gcloud compute instance-groups managed create fancy-fe-mig \
    --base-instance-name fancy-fe \
    --size 2 \
    --template fancy-fe
gcloud compute instance-groups managed create fancy-be-mig \
    --base-instance-name fancy-be \
    --size 2 \
    --template fancy-be

このアプリケーションの場合、フロントエンド マイクロサービスはポート 8090 で実行され、バックエンド マイクロサービスは注文用のポート 8091 と製品用のポート 8092 で実行されます。これらは標準以外のポートであるため、名前付きポートを指定して指定します。名前付きポートは Key-Value ペアのメタデータで、サービス名とサービスを実行するポートを表します。名前付きポートをインスタンス グループに割り当てることで、そのインスタンス グループに含まれるすべてのインスタンスでサービスを利用することができます。この情報は、後で構成する HTTP 負荷分散サービスで使用されます。

gcloud compute instance-groups set-named-ports fancy-fe-mig \ 
    --named-ports frontend:8090
gcloud compute instance-groups set-named-ports fancy-be-mig \
    --named-ports orders:8091,products:8092

自動修復の構成

アプリケーション自体の可用性を高め、応答していることを確認するには、マネージド インスタンス グループの自動修復ポリシーを構成します。

自動修復ポリシーは、アプリケーション ベースのヘルスチェックを使用して、アプリのレスポンスが期待どおりであることを検証します。デフォルトの応答であるインスタンスが RUNNING 状態かどうかを検証するより、アプリが応答していることを確認できます。

フロントエンドとバックエンドでヘルスチェックに 3 回連続して失敗した場合にインスタンスを修復するヘルスチェックを作成します。

gcloud compute health-checks create http fancy-fe-hc \
    --port 8090 \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3
gcloud compute health-checks create http fancy-be-hc \
    --port 8091 \
    --request-path=/api/orders \
    --check-interval 30s \
    --healthy-threshold 1 \
    --timeout 10s \
    --unhealthy-threshold 3

ヘルスチェック プローブがポート 8090 ~ 8091 でマイクロサービスに接続できるようにファイアウォール ルールを作成します。

gcloud compute firewall-rules create allow-health-check \
    --allow tcp:8090-8091 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16 \
    --network default

ヘルスチェックを各サービスに適用します。

gcloud compute instance-groups managed update fancy-fe-mig \
    --health-check fancy-fe-hc \
    --initial-delay 300
gcloud compute instance-groups managed update fancy-be-mig \
    --health-check fancy-be-hc \
    --initial-delay 300

障害のシミュレーションを行う

ヘルスチェックが機能することを確認するために、インスタンスにログインしてサービスを停止します。インスタンス名を確認するには、次のコマンドを実行します。

gcloud compute instance-groups list-instances fancy-fe-mig

そこから、インスタンスの 1 つにセキュアシェルを実行します。ここで、INSTANCE_NAME はリストにあるインスタンスの 1 つです。

gcloud compute ssh [INSTANCE_NAME]

インスタンス内で、supervisorctl を使用してアプリケーションを停止します。

sudo supervisorctl stop nodeapp; sudo killall node

インスタンスからログアウトします。

exit

修復される様子をモニタリングします。

watch -n 5 gcloud compute operations list \
--filter='operationType~compute.instances.repair.*'

出力例:

NAME                                                  TYPE                                       TARGET                                 HTTP_STATUS  STATUS  TIMESTAMP
repair-1568314034627-5925f90ee238d-fe645bf0-7becce15  compute.instances.repair.recreateInstance  us-central1-a/instances/fancy-fe-1vqq  200          DONE    2019-09-12T11:47:14.627-07:00

修復が行われたら、Ctrl+C キーを押して、watch コマンドを終了します。この時点で、マネージド インスタンス グループは、インスタンスを再作成して修復します。

マネージド インスタンス グループを補完するために、HTTP(S) ロードバランサを使用してフロントエンドとバックエンドのマイクロサービスにトラフィックを提供し、マッピングを使用してパスルールに基づいて適切なバックエンド サービスにトラフィックを送信します。これにより、負荷が分散された IP をすべてのサービスに対して公開します。

https://cloud.google.com/load-balancing/docs/load-balancing-overview

HTTP(S) ロードバランサを作成する

Google Cloud Platform にはさまざまな種類のロードバランサが用意されていますが、トラフィックには HTTP(S) ロードバランサを使用します。HTTP ロードバランサは次のように構成されています。

  1. 転送ルールによって受信したリクエストをターゲットの HTTP プロキシに転送します。
  2. ターゲット HTTP プロキシは各リクエストを URL マップと照合し、各リクエストに適したバックエンド サービスを判断します。
  3. バックエンド サービスは、バックエンドの処理能力、ゾーン、インスタンスの健全性に基づき、適切なバックエンドに各リクエストを転送します。HTTP ヘルスチェックを使用して各バックエンド インスタンスの健全性が検証されます。バックエンド サービスが HTTPS または HTTP/2 のヘルスチェックを使用するように構成されている場合、リクエストは途中で暗号化されてからバックエンド インスタンスに送信されます。
  4. ロードバランサとインスタンス間のセッションでは、HTTP、HTTPS、HTTP/2 プロトコルを使用できます。HTTPS または HTTP/2 を使用する場合、バックエンド サービスの各インスタンスには SSL 証明書が必要です。

ヘルスチェックを作成して、各サービスでトラフィックを処理できるインスタンスを特定します。

gcloud compute http-health-checks create fancy-fe-frontend-hc \
  --request-path / \
  --port 8090
gcloud compute http-health-checks create fancy-be-orders-hc \
  --request-path /api/orders \
  --port 8091
gcloud compute http-health-checks create fancy-be-products-hc \
  --request-path /api/products \
  --port 8092

負荷分散されたトラフィックの送信先となるバックエンド サービスを作成します。このバックエンド サービスは、作成したヘルスチェックと名前付きポートを使用します。

gcloud compute backend-services create fancy-fe-frontend \
  --http-health-checks fancy-fe-frontend-hc \
  --port-name frontend \
  --global
gcloud compute backend-services create fancy-be-orders \
  --http-health-checks fancy-be-orders-hc \
  --port-name orders \
  --global
gcloud compute backend-services create fancy-be-products \
  --http-health-checks fancy-be-products-hc \
  --port-name products \
  --global

バックエンド サービスを追加します。

gcloud compute backend-services add-backend fancy-fe-frontend \
  --instance-group fancy-fe-mig \
  --instance-group-zone us-central1-a \
  --global
gcloud compute backend-services add-backend fancy-be-orders \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-a \
  --global
gcloud compute backend-services add-backend fancy-be-products \
  --instance-group fancy-be-mig \
  --instance-group-zone us-central1-a \
  --global

URL マップを作成します。URL マップは、どの URL がどのバックエンド サービスにつながるのかを定義します。

gcloud compute url-maps create fancy-map \
  --default-service fancy-fe-frontend

それぞれのサービスにルーティングするための「/api/orders'」パスと「/api/products'」パスを許可するパスマッチャーを作成します。

gcloud compute url-maps add-path-matcher fancy-map \
   --default-service fancy-fe-frontend \
   --path-matcher-name orders \
   --path-rules "/api/orders=fancy-be-orders,/api/products=fancy-be-products"

作成した URL マップに関連付けるプロキシを作成します。

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

パブリック IP アドレスとポートをプロキシに関連付けるグローバル転送ルールを作成します。

gcloud compute forwarding-rules create fancy-http-rule \
  --global \
  --target-http-proxy fancy-proxy \
  --ports 80

構成を更新する

新しい静的 IP アドレスができたので、バックエンド インスタンスを指すエフェメラル アドレスではなく、この新しいアドレスを指すようにフロントエンドのコードを更新する必要があります。

Cloud Shell で、構成ファイルの .env' がある react-app フォルダに変更します。

cd ~/monolith-to-microservices/react-app/

ロードバランサの IP アドレスを確認します。

gcloud compute forwarding-rules list --global

出力例:

NAME                    REGION  IP_ADDRESS     IP_PROTOCOL  TARGET
fancy-http-rule          34.102.237.51  TCP          fancy-proxy

任意のテキスト エディタ(例: nano)で .env を編集し、ロードバランサのパブリック IP を指定します。[LB_IP] は上記で決定したバックエンド インスタンスの外部 IP アドレスです。

REACT_APP_ORDERS_URL=http://[LB_IP]/api/orders
REACT_APP_PRODUCTS_URL=http://[LB_IP]/api/products

react-app を再ビルドします。これにより、フロントエンド コードが更新されます。

npm install && npm run-script build

アプリケーション コードを GCS バケットにコピーします。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

フロントエンド インスタンスを更新する

新しいコードと構成ができたので、マネージド インスタンス グループ内のフロントエンド インスタンスでこの新しいコードを pull します。インスタンスは起動時にコードを pull するため、ローリング再起動コマンドを発行できます。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig \
    --max-unavailable 100%

ウェブサイトをテストする

リストにインスタンスが表示されるまで、マネージド インスタンス グループのステータスを確認します。

watch -n 5 gcloud compute instance-groups list-instances fancy-fe-mig

アイテムがリストに表示されたら、Ctrl+C キーを押して watch コマンドを終了します。

サービスが「正常」と表示されていることを確認します。

gcloud compute backend-services get-health fancy-fe-frontend --global

出力例:

---
backend: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instanceGroups/fancy-fe-mig
status:
  healthStatus:
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-x151
    ipAddress: 10.128.0.7
    port: 8090
  - healthState: HEALTHY
    instance: https://www.googleapis.com/compute/v1/projects/my-gce-codelab/zones/us-central1-a/instances/fancy-fe-cgrt
    ipAddress: 10.128.0.11
    port: 8090
  kind: compute#backendServiceGroupHealth

アプリケーションは http://[LB_IP] でアクセスできます。[LB_IP] はロードバランサに指定された IP_ADDRESS で、次のコマンドで確認できます。

gcloud compute forwarding-rules list --global

これまでに 2 つのマネージド インスタンス グループを作成して、それぞれ 2 つのインスタンスを作成しました。この構成は完全に機能しますが、負荷に関係なく静的構成です。次に、使用率に基づいて自動スケーリング ポリシーを作成し、各マネージド インスタンス グループを自動的にスケーリングします。

使用率に応じて自動的にサイズを変更する

自動スケーリング ポリシーを作成するには、Cloud Shell 内で次のコマンドを実行します。これらのコマンドにより、マネージド インスタンス グループにオートスケーラーが作成されます。オートスケーラーは、使用率が 60% を超えたときにインスタンスを自動的に追加します。また、ロードバランサの使用率が 60% を下回ると、インスタンスを削除します。

gcloud compute instance-groups managed set-autoscaling \
  fancy-fe-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60
gcloud compute instance-groups managed set-autoscaling \
  fancy-be-mig \
  --max-num-replicas 5 \
  --target-load-balancing-utilization 0.60

コンテンツ配信ネットワークを有効にする

スケーリングに役立つもう 1 つの機能は、コンテンツ配信ネットワーク サービスである Cloud CDN がフロントエンドにキャッシュを提供できるようにすることです。これを行うには、フロントエンド サービスで次のコマンドを実行します。

gcloud compute backend-services update fancy-fe-frontend \
    --enable-cdn --global

これで、ユーザーが HTTP(S) ロードバランサのコンテンツをリクエストすると、そのリクエストは Google Front End(GFE)に到着し、Google Cloud Front End(GFE)はまずユーザーのリクエストに対するレスポンスを探します。レスポンスがキャッシュされていた場合、GFE はそれをユーザーに送信します。これを「キャッシュ ヒット」と呼びます。

それ以外の場合、GFE がリクエストに対するキャッシュに保存されたレスポンスを見つけられない場合、GFE はバックエンドに直接リクエストを行います。このリクエストに対するレスポンスをキャッシュに保存できる場合、GFE はそのレスポンスを Cloud CDN キャッシュに保存して以降のリクエストで使用できるようにします。

インスタンス テンプレートを更新する

既存のインスタンス テンプレートは編集できません。ただし、インスタンスはステートレスであり、すべての構成は起動スクリプトによって行われるため、コアイメージ自体を変更する場合は、実際にインスタンス テンプレートを変更するだけで済みます。このプロセスを具体的に示すために、単純な変更を行って push します。

このセクションでは、インスタンス テンプレートのベースとなる frontend インスタンスを更新します。更新では、インスタンス テンプレートのイメージの更新バージョンにファイルを配置して、インスタンス テンプレートを更新し、新しいテンプレートを展開して、そのファイルがマネージド インスタンス グループ インスタンスに存在することを確認します。

frontend インスタンスをまだ起動していない場合は起動します。

gcloud compute instances start frontend

インスタンスへのシェルの実行:

gcloud compute ssh frontend

インスタンス内で、ファイルが更新済みであることを確認するためにファイルを作成します。

echo "Updated" > ~/updated_proof

インスタンスからログアウトします。

exit

インスタンスをシャットダウンします。

gcloud compute instances stop frontend

新しいインスタンス テンプレートを作成します。

gcloud compute instance-templates create fancy-fe-new \
    --source-instance=frontend \
    --source-instance-zone=us-central1-a

新しいインスタンス テンプレートをマネージド インスタンス グループに展開します。

gcloud compute instance-groups managed rolling-action start-update fancy-fe-mig \
    --version template=fancy-fe-new

更新のステータスをモニタリングします。

gcloud compute instance-groups managed list-instances fancy-fe-mig

インスタンスのステータスが RUNNING に INSTANCE_TEMPLATE がfancy-fe-new になったら、新しく作成されたインスタンスにログインし、updated_proof' ファイルが存在するかどうかを確認します。新しく作成された [VM_NAME] ファイルが

gcloud compute ssh [VM_NAME]

「updated_proof'」ファイルがマネージドグループインスタンス上に存在する場合、更新は正常に push されています。

ウェブサイトに変更を加える

マーケティング チームから、サイトのホームページを変更するよう依頼されました。会社名と実際の販売商品について、より多くの情報を求めるべきです。このセクションでは、マーケティング チームの満足度を高めるために、ホームページにテキストを追加します。Google のデベロッパーがすでに index.js.new というファイル名で変更を作成しているようです。このファイルを index.js にコピーするだけで、変更を反映できます。以下の手順に沿って適切な変更を行います。

次のコマンドを実行して、更新したファイルを正しいファイル名にコピーし、ファイルの内容を出力して変更を確認します。

cd ~/monolith-to-microservices/react-app/src/pages/Home
mv index.js.new index.js
cat ~/monolith-to-microservices/react-app/src/pages/Home/index.js

変更後のコードは次のようになっています。

/*
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1
  },
  paper: {
    width: "800px",
    margin: "0 auto",
    padding: theme.spacing(3, 2)
  }
}));
export default function Home() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <Paper className={classes.paper}>
        <Typography variant="h5">
          Fancy Fashion &amp; Style Online
        </Typography>
        <br />
        <Typography variant="body1">
          Tired of mainstream fashion ideas, popular trends and societal norms?
          This line of lifestyle products will help you catch up with the Fancy trend and express your personal style.
          Start shopping Fancy items now!
        </Typography>
      </Paper>
    </div>
  );
}

React コンポーネントを更新しましたが、静的ファイルを生成するには React アプリを作成する必要があります。次のコマンドを実行して React アプリをビルドし、モノリスの公開ディレクトリにコピーします。

cd ~/monolith-to-microservices/react-app
npm install && npm run-script build

次に、このコードを GCS バケットに再度 push します。

cd ~
rm -rf monolith-to-microservices/*/node_modules
gsutil -m cp -r monolith-to-microservices gs://fancy-store-$DEVSHELL_PROJECT_ID/

ローリング アップデートを使用した変更のプッシュ

すべてのインスタンスを強制的に再起動して更新を pull できるようになりました。

gcloud compute instance-groups managed rolling-action restart fancy-fe-mig

このローリング再起動により、バッファに影響を与えずにインスタンスを再起動し、アクセスに影響しないようにしました。Console でインスタンスの循環を監視します。更新中は、ステータスが変換中です。完了すると、マネージド インスタンス グループは、[Compute Engine] > [インスタンス グループ] に準備完了と表示されます。

準備ができたら、実行するすべてのアクティビティをクリーンアップする最も簡単な方法はプロジェクトを削除することです。プロジェクトを削除すると、この Codelab で作成されたすべてのロードバランサ、インスタンス、テンプレートなどが削除され、予期しない定期請求の発生がなくなります。Cloud Shell で次のコマンドを実行します。PROJECT_ID はプロジェクト名ではなく、完全なプロジェクト ID です。

gcloud projects delete [PROJECT_ID]

プロンプトが表示されたら、「Y」と入力して削除を確定します。

GCE でのウェブサイトのデプロイ、スケーリング、更新が完了しました。また、Compute Engine でのマネージド インスタンス グループ、ロードバランサ、ヘルスチェックの操作についても確認しました。