Cloud Run を使用してウェブサイトをデプロイする

1. 始める前に

仮想マシン(VM)インスタンス、クラスタ、Pod、Service などを作成、管理するためのオーバーヘッドが発生するため、ウェブサイトの運用は困難になりがちです。これは大規模な多層アプリには適していますが、ウェブサイトをデプロイして公開するだけの場合、多くのオーバーヘッドが発生します。

Knative の Google Cloud 実装である Cloud Run を使用すると、VM ベースまたは Kubernetes ベースのデプロイに必要なオーバーヘッドなしにウェブサイトを管理、デプロイできます。管理が簡素化されるだけでなく、ウェブサイトでリクエストを受信していないときは「ゼロにスケール」できます。

Cloud Run は、コンテナにサーバーレス開発をもたらすだけでなく、独自の Google Kubernetes Engine(GKE)クラスタ上や、Cloud Run が提供するフルマネージドの Platform as a Service(PaaS)ソリューション上で実行することもできます。この Codelab では、後者のシナリオをテストします。

次の図は、デプロイと Cloud Run ホスティングのフローを示しています。まず、Cloud Build を介して Docker イメージを作成し、Cloud Shell でトリガーします。次に、Cloud Shell でコマンドを使用してそのイメージを Cloud Run にデプロイします。

db5f05c090d5ebcb.png

前提条件

学習内容

  • Cloud Build で Docker イメージをビルドして gcr.io にアップロードする方法
  • Docker イメージを Cloud Run にデプロイする方法
  • Cloud Run デプロイメントを管理する方法
  • Cloud Run でアプリのエンドポイントを設定する方法

作成するアプリの概要

  • Docker コンテナ内で実行される静的ウェブサイト
  • Container Registry に存在するこのコンテナのバージョン
  • 静的ウェブサイト用の Cloud Run デプロイメント

必要なもの

  • プロジェクトを作成するための管理者権限を持つ Google アカウント、またはプロジェクト オーナーのロールを持つプロジェクト

2. 環境のセットアップ

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

Google アカウントをまだお持ちでない場合は、アカウントを作成してください。次に、Google Cloud コンソールにログインし、[プロジェクト] >プロジェクトを作成します。

53dad2cefdae71da.png

faab21976aabeb4c.png

プロジェクト ID を覚えておいてください。この ID はプロジェクト名の下に自動的に入力されます。プロジェクト ID はすべての Google Cloud プロジェクトで一意の名前であるため、スクリーンショット内の名前はすでに使用されているため、使用できません。これ以降は PROJECT_ID と呼びます。

次に、Google Cloud リソースを使用して Cloud Run API を有効にするために、Cloud コンソールで課金を有効にする必要があります。

Cloud Run API を有効にする

ナビゲーション メニュー 📍? >API とサービス >ダッシュボード >API とサービスを有効にします。.

5dbb2e6e27a55fcf.png

“Cloud Run API”を検索します次に、[Cloud Run API] >有効にする

f1fd486174a744cf.png

この Codelab をすべて実行しても費用はかかりませんが、より多くのリソースを使用する場合や、実行したままにする場合は、コストが高くなる可能性があります(最後のクリーンアップをご覧ください)。詳細については、料金をご覧ください。

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

Cloud Shell

Google Cloud と Cloud Run はノートパソコンからリモートで操作できますが、ここでは Cloud Shell(Google Cloud 上で動作するコマンドライン環境)を使用します。この環境には、必要なすべてのクライアント ライブラリとフレームワークがあらかじめ構成されています。

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

  1. Cloud Console から Cloud Shell を有効にするには、[Cloud Shell をアクティブにする] fEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q をクリックします(環境のプロビジョニングと接続に若干時間を要します)。

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

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>

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

gcloud config set project <PROJECT_ID>

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

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

Cloud Shell では、デフォルトで環境変数もいくつか設定されます。これらの変数は、以降のコマンドを実行する際に有用なものです。

echo $GOOGLE_CLOUD_PROJECT

コマンド出力

<PROJECT_ID>
  1. 最後に、デフォルトのゾーンとプロジェクト構成を設定します。
gcloud config set compute/zone us-central1-f

さまざまなゾーンを選択できます。詳しくは、リージョンとゾーン

3. ソース リポジトリのクローンを作成する

既存のウェブサイトをデプロイする場合は、リポジトリからソースのクローンを作成するだけでよいため、Docker イメージの作成と Cloud Run へのデプロイに集中できます。

次のコマンドを実行して、Cloud Shell インスタンスにリポジトリのクローンを作成し、適切なディレクトリに移動します。デプロイ前にアプリをテストできるように、Node.js の依存関係もインストールします。

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh

これにより、リポジトリのクローンが作成され、ディレクトリが変更され、アプリをローカルで実行するために必要な依存関係がインストールされます。スクリプトの実行には数分かかる場合があります。

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

cd ~/monolith-to-microservices/monolith
npm start

出力:

Monolith listening on port 8080!

アプリをプレビューするには、[ウェブでプレビュー] acc630712255c604.png をクリックし、[ポート 8080 でプレビュー] を選択します。

5869738f0e9ec386.png

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

9ed25c3f0cbe62fa.png

ウェブサイトを閲覧した後、このウィンドウは閉じることができます。web-server プロセスを停止するには、ターミナル ウィンドウで CONTROL+C(Macintosh では Command+C)を押します。

4. Cloud Build を使用して Docker コンテナを作成する

ソースファイルの準備が整ったので、アプリを Docker 化します。

通常は、2 段階のアプローチを取る必要があります。具体的には、Docker コンテナをビルドして、レジストリに push し、GKE がそこからイメージを pull できるようにします。ただし、Cloud Build を使用して 1 つのコマンドで Docker コンテナをビルドし、イメージを Container Registry に配置することで、作業を楽にすることができます。手動で Dockerfile を作成して push するプロセスを確認するには、Container Registry のクイックスタートをご覧ください。

Cloud Build は、ディレクトリにあるファイルを圧縮して Cloud Storage バケットに移動します。次に、ビルドプロセスでそのバケットからすべてのファイルを取得し、Dockerfile を使用します。Dockerfile は、Docker ビルドプロセスを実行するのと同じディレクトリにあります。Docker イメージの --tag フラグに gcr.io というホストを指定した場合、生成された Docker イメージは Container Registry に push されます。

まず、Cloud Build API が有効になっていることを確認する必要があります。次のコマンドを実行して有効にします。

gcloud services enable cloudbuild.googleapis.com

API が有効になったら、Cloud Shell で次のコマンドを実行してビルドプロセスを開始します。

gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 .

このプロセスには数分かかります。完了すると、ターミナルに次のような出力が表示されます。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/monolith:1.0.0  SUCCESS

ビルド履歴を表示したり、プロセスをリアルタイムで確認したりするには、Cloud コンソールに移動し、ナビゲーション メニュー 📍? >Cloud Build >履歴。以前のビルドがすべて一覧表示されますが、そこには作成したビルドのみが表示されるはずです。

4c753ede203255f6.png

[Build id] をクリックすると、そのビルドのすべての詳細が表示されます。詳細にはログ出力も含まれます。[イメージ] の横にあるリンクをクリックすると、作成されたコンテナ イメージを表示できます。

6e88ed1643dfe629.png

5. コンテナを Cloud Run にデプロイする

ウェブサイトをコンテナ化して Container Registry に push したので、次は Cloud Run にデプロイします。

Cloud Run にデプロイするには次の 2 つの方法があります。

  • Cloud Run(フルマネージド)は、コンテナのライフサイクル全体を管理する PaaS モデルです。この Codelab では、この方法を使用します。
  • Cloud Run for Anthos は制御が強化された Cloud Run であり、GKE からクラスタと Pod を導入できます。詳細については、Cloud Run for Anthos on Google Cloud の設定をご覧ください。

コマンドラインの例は、先ほど設定した環境変数を使用して Cloud Shell に表示されます。

コマンドライン

次のコマンドを実行して、アプリをデプロイします。

gcloud run deploy --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --platform managed 

使用するリージョンを指定するように求められます。最も近いリージョンを選択し、デフォルトの推奨サービス名(monolith)を受け入れます。

d52d9419c5166674.png

テスト目的で、アプリへの未認証リクエストを許可します。プロンプトで「y」と入力します。

3a57b32f133dad61.png

デプロイメントを確認する

Deployment が正常に作成されたことを確認するには、次のコマンドを実行します。Pod statusRunning になるまで少し時間がかかる場合があります。

gcloud run services list

[1] Cloud Run(フルマネージド)を選択します。

出力:

SERVICE   REGION    URL  LAST DEPLOYED BY          LAST DEPLOYED AT
✔  monolith  us-east1 <your url>  <your email>  2019-09-16T21:07:38.267Z

出力には、いくつかの情報が表示されます。デプロイメント、デプロイしたユーザー(メールアドレス)、アプリケーションへのアクセスに使用する URL を確認できます。すべて正常に作成されたようです。

サービスのリストに記載された URL をウェブブラウザで開きます。ローカルでプレビューしたものと同じウェブサイトが表示されます。

6. 同時実行の値を小さくした新しいリビジョンを作成する

ここでアプリを再度デプロイしますが、今回はパラメータのうちの 1 つを調整します。

デフォルトでは、Cloud Run アプリの同時実行の値は 80 に設定されます。つまり、各コンテナ インスタンスは一度に最大 80 件のリクエストを処理します。これは、1 つのインスタンスが一度に 1 つのリクエストを処理する Functions as a Service(FaaS)モデルとは大きく異なります。

同時実行の値を 1(テスト目的のみ)に設定して同じコンテナ イメージを再デプロイし、どうなるかを確認します。

gcloud run deploy --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --platform managed --concurrency 1

初回と同様に、以降の質問に回答します。コマンドが成功したら、Cloud コンソールで結果を確認します。

Cloud Run ダッシュボードで monolith サービスをクリックして詳細を表示します。

7d1eed2e4728a4f2.png

[変更内容] タブをクリックします。2 つのリビジョンが作成されているはずです。monolith-00002 をクリックし、詳細を確認します。同時実行の値が 1 に減っていることがわかります。

217185c0eccc87dd.png]

4ad481b8bcd0343d.png

テストにはこの構成で十分ですが、ほとんどの本番環境のシナリオでは、コンテナで複数の同時リクエストをサポートすることになります。

次に、再デプロイせずに元の同時実行を復元します。同時実行の値をデフォルトの 80 または 0 に設定すると、同時実行の制限がすべて解除され、デフォルトの最大値(この記事の作成時点では 80)に設定できます。

Cloud Shell で次のコマンドを実行して、現在のリビジョンを更新します。

gcloud run deploy --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --platform managed --concurrency 80

別のリビジョンが作成されたこと、トラフィックがリダイレクトされていること、同時実行数が 80 に戻ったことを確認します。

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

マーケティング チームから、会社のウェブサイトのホームページを変更するよう依頼されました。その会社が何をし、何を販売しているかについて、もっと多くの情報を提供するべきだと考えています。このセクションでは、マーケティング チームの満足度を高めるために、ホームページにテキストを追加します。

デベロッパーの 1 人が 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 アプリをビルドし、monolith の公開ディレクトリにコピーします。

cd ~/monolith-to-microservices/react-app
npm run build:monolith

コードが更新されたので、次は Docker コンテナを再ビルドして Container Registry に公開する必要があります。前と同じコマンドを使用できますが、今回はバージョン ラベルを更新します。

次のコマンドを実行し、更新後のイメージ バージョン 2.0.0 を指定して新しい Cloud Build をトリガーします。

cd ~/monolith-to-microservices/monolith

#Feel free to test your application
npm start

gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

次のセクションでは、そのイメージを使用して、ダウンタイムなしでアプリを更新します。

8. ダウンタイムなしでウェブサイトを更新する

変更が完了し、マーケティング チームも更新内容に満足してくれました。次は、ユーザーへのサービスを中断させずにウェブサイトを更新します。

Cloud Run は各デプロイを新しいリビジョンとして扱います。リビジョンはオンラインになり、トラフィックがリダイレクトされます。

以下の手順に沿ってウェブサイトを更新します。

コマンドライン

コマンドラインから次のコマンドを使用すると、サービスを再デプロイしてイメージを新しいバージョンに更新できます。

gcloud run deploy --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --platform managed

デプロイメントを確認する

次のコマンドを実行して、デプロイの更新を検証します。

gcloud run services describe monolith --platform managed 

出力は次のようになります。

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
  annotations:
    client.knative.dev/user-image: gcr.io/my-cloudrun-codelab/monolith:2.0.0
...

サービスが、新しいリビジョンにデプロイされた最新バージョンのイメージを使用していることがわかります。

変更を確認するには、Cloud Run サービスの外部 URL に再度アクセスし、アプリのタイトルが更新されていることを確認します。

次のコマンドを実行してサービスを一覧表示し、IP アドレスを忘れた場合は確認します。

gcloud run services list

ウェブサイトのホームページ コンポーネントに追加したテキストが表示されるようになりました。

451ca252acae6928.png

9. クリーンアップ

Container Registry イメージを削除する

# Delete the container image for version 1.0.0 of our monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:1.0.0 --quiet

# Delete the container image for version 2.0.0 of our monolith
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 --quiet

Cloud Storage から Cloud Build アーティファクトを削除する

# The following command will take all source archives from all builds and delete them from cloud storage

# Run this command to print all sources:
# gcloud builds list | awk 'NR > 1 {print $4}' 

gcloud builds list | awk 'NR > 1 {print $4}' | while read line; do gsutil rm $line; done

Cloud Run サービスの削除

gcloud run services delete monolith --platform managed

10.完了

ここでは、Cloud Run を使用してウェブサイトのデプロイ、スケーリング、更新を行いました。

その他の情報