Cloud Run による 3 つの簡単なステップで開発から本番環境へ

1. はじめに

アプリケーションの管理が難しいのはなぜですか?

大きな理由の 1 つは、デベロッパーがシステム管理者を兼任することが多いことです。最新のプロダクション グレードのウェブ アプリケーションを開発、デプロイ、管理するには、次の(一部)の懸念事項を考慮する必要があります。

4d018476b4a73b47.png

これらのことは、私にとっては心配したくないことばかりです。私が本当に考えたいのは、アプリケーション ロジックです。

6dfd143d20e5548b.png

これが Cloud Run のすべてです。アプリに集中し、管理とメンテナンスは Google に任せることができます。Google は、この分野のスキルを洗練し、完成させるために何百万時間も投資しています。

上記の管理上の課題に加えて、次の課題にも対処する必要があります。

  • 依存関係 - アプリが実行される環境は、可能な限り、テストが行われた環境と正確に一致している必要があります。これには、オペレーティング システム、サポート ライブラリ、言語インタープリタまたはコンパイラ、ハードウェア構成など、さまざまな要素が含まれます。
  • 配布 - アプリのローカル バージョンからインターネットで広く共有されるバージョンに移行するには、多くの場合、ランタイム環境の変更、複雑さの飛躍的な増大、急な学習曲線が必要になります。

Cloud Run は、これらの問題やその他の多くの問題に対応します。しかし、私の言葉を鵜呑みにするのではなく、一緒にアプリを作成して、ローカル開発環境から本番環境グレードのクラウドアプリに移行するのが、簡単な手順でどれほど簡単かを見てみましょう。

演習内容

  • シンプルなウェブアプリを構築し、開発環境で想定どおりに動作することを確認します。
  • 次に、同じアプリのコンテナ化されたバージョンに移行します。その過程で、コンテナ化の意味と、コンテナ化が非常に有用な理由について説明します。
  • 最後に、アプリをクラウドにデプロイし、コマンドラインと Google Cloud コンソールを使用して Cloud Run サービスを簡単に管理する方法を確認します。

学習内容

  • Python でシンプルなウェブサーバー アプリを作成する方法
  • どこでも実行できる Docker コンテナにアプリをパッケージ化する方法
  • アプリをクラウドにデプロイして、誰でも新しい作品を試せるようにする方法
  • Buildpack を使用して上記の手順をさらに簡素化する方法
  • Google Cloud コマンドライン ツールと Cloud コンソール ウェブ UI の使用方法

必要なもの

  • ウェブブラウザ
  • Google アカウント

このラボは、初心者を含むあらゆるレベルのデベロッパーを対象としています。Python を使用しますが、使用するすべてのコードを説明するため、内容を理解するために Python プログラミングに精通している必要はありません。

2. 準備

5110b5081a1e1c49.png

このセクションでは、このラボを始めるために必要なすべての手順について説明します。

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

  1. Cloud コンソールにログインして、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください)。

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

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

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

このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell を起動する

このラボでは、Cloud Shell セッションで作業します。Cloud Shell は、Google のクラウド内で実行されている仮想マシンによってホストされたコマンド インタープリタです。このセクションは、パソコンでもローカルで簡単に実行できますが、Cloud Shell を使用することで、誰もが一貫した環境での再現可能な操作性を利用できるようになります。本ラボの後、このセクションをパソコン上で再度実行してみてください。

704a7b7491bd157.png

Cloud Shell をアクティブにする

  1. Cloud Console で、[Cloud Shell をアクティブにする] 4292cbf4971c9786.png をクリックします。

bce75f34b2c53987.png

Cloud Shell を初めて起動した場合は、その内容を説明する画面が(スクロールしなければ見えない位置に)表示されます。その場合は、[続行] をクリックしてください(以後表示されなくなります)。この中間画面は次のようになります。

70f315d7b402b476.png

すぐにプロビジョニングが実行され、Cloud Shell に接続されます。

fbe3a0674c982259.png

この仮想マシンには、必要な開発ツールがすべて用意されています。仮想マシンは Google Cloud で稼働し、永続的なホーム ディレクトリが 5 GB 用意されているため、ネットワークのパフォーマンスと認証が大幅に向上しています。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。

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

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

ターミナルでいくつかの環境変数を設定します。これにより、以降の手順が簡単になります。

export PROJ=$GOOGLE_CLOUD_PROJECT 
export APP=hello 
export PORT=8080
export REGION="us-central1"
export TAG="gcr.io/$PROJ/$APP"

API を有効にする

これらのサービスがどんな場面で(なぜ)必要になるのかは、後の手順でわかります。とりあえず、次のコマンドを実行して Cloud Build、Container Registry、Cloud Run の各サービスへのアクセス権を取得します。

gcloud services enable cloudbuild.googleapis.com         \
                       containerregistry.googleapis.com  \
                       run.googleapis.com          

成功すると次のようなメッセージが表示されます。

Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.

3. シンプルなウェブアプリを構築する

eef530b56b8e93a3.png

まず、Cloud Shell パネルの上部にある Open Editor ボタンをクリックします。たとえば、次のようになります。

9b81c8a37a6bcdd8.png

Visual Studio Code に似た IDE 環境が表示され、プロジェクトの作成、ソースコードの編集、プログラムの実行などを行うことができます。画面が狭すぎる場合は、コンソールと編集/ターミナル ウィンドウの間の分割線を拡大または縮小できます。これを行うには、次の図でハイライト表示されている 2 つの領域の間の水平バーをドラッグします。

8dea35450851af53.png

[Open Editor] ボタンと [Open Terminal] ボタンをそれぞれクリックすると、エディタとターミナルを切り替えることができます。それでは、この 2 つの環境を切り替えてみましょう。

次に、[File] -> [New Folder] を選択して、このラボの作業を保存するフォルダを作成し、hello と入力して OK をクリックします。このラボで作成するすべてのファイルと、Cloud Shell で行うすべての作業は、このフォルダで行われます。

次に、requirements.txt ファイルを作成します。これにより、アプリが依存するライブラリが Python に通知されます。このシンプルなウェブアプリでは、Flask というウェブサーバーを構築するための一般的な Python モジュールと、gunicorn というウェブサーバー フレームワークを使用します。Cloud エディタ ウィンドウで、[File] > [New File] メニューをクリックして新しいファイルを作成します。新しいファイルの名前を求めるプロンプトが表示されたら、「requirements.txt」と入力して OK ボタンを押します。新しいファイルが hello プロジェクト フォルダに保存されていることを確認します。

新しいファイルに次の行を入力して、アプリが Python の Flask パッケージと gunicorn ウェブサーバーに依存することを指定します。

Flask
gunicorn

Cloud エディタは変更を自動的に保存するため、このファイルを明示的に保存する必要はありません。

バージョン 1: Hello world!

同じ手法を使用して、main.py という名前の新しいファイルを作成します。これがアプリのメイン(かつ唯一)の Python ソースファイルになります。新しいファイルが hello プロジェクト フォルダに保存されていることを確認してください。

次のコードをこのファイルに挿入します。

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
    html = "<h1>Hello world!</h1>"
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

ターミナルに戻り、次のコマンドでプロジェクト フォルダに移動します。

cd hello

次のコマンドを実行して、プロジェクトの依存関係をインストールします。

pip3 install -r requirements.txt

ターミナルで次のコマンドを実行して、アプリを起動します。

python3 main.py

この時点で、アプリは Cloud Shell セッション専用の仮想マシンで実行されています。Cloud Shell には、仮想マシンで実行されているウェブサーバー(起動したばかりのサーバーなど)にグローバル インターネットのどこからでもアクセスできるようにするプロキシ メカニズムが含まれています。

web preview ボタンをクリックし、次のように Preview on Port 8080 メニュー項目をクリックします。

fe45e0192080efd6.png

実行中のアプリのウェブブラウザタブが開きます。次のような画面が表示されます。

b1f06501509aefb9.png

バージョン 2: URL パスをエコーする

Cloud エディタ(Open Editor ボタン)に戻り、次のように main.py ファイルを更新して、オプションの URL 接尾辞のエコーをサポートします。

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from environment.

# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])     # ← NEW
def say_hello(name="world"):               # ← MODIFIED
    html = f"<h1>Hello {name}!</h1>"       # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

ターミナル(Open Terminal ボタン)に戻り、control-C(Ctrl キーを押しながら「C」を押す)を入力して実行中のアプリを停止し、次のコマンドを入力して再起動します。

python3 main.py

もう一度 web preview ボタンをクリックし、Preview on Port 8080 メニュー項目をクリックして、実行中のアプリのウェブブラウザ タブを開きます。もう一度「Hello world!」というメッセージが表示されます。スラッシュ文字の後の URL テキストを任意の文字列(/your-name など)に置き換え、次のような表示になることを確認します。

93b87996f88fa370.png

バージョン 3: ランダムな色

次に、Cloud エディタ(Open Editor ボタン)に戻り、main.py ファイルを次のように更新して、ランダムな背景色のサポートを追加します。

from flask import Flask
import os
import random

app = Flask(__name__)  # Create a Flask object.
PORT = os.environ.get("PORT")  # Get PORT setting from the environment.

# This function decides whether foreground text should be
# displayed in black or white, to maximize fg/bg contrast.
def set_text_color(rgb):                      # ← NEW
    sum = round(                              # ← NEW
        (int(rgb[0]) * 0.299)                 # ← NEW
        + (int(rgb[1]) * 0.587)               # ← NEW
        + (int(rgb[2]) * 0.114)               # ← NEW
    )                                         # ← NEW
    return "black" if sum > 186 else "white"  # ← NEW


# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
# If something is specified as the URL path (after the '/'), say_hello()
# responds with "Hello X", where X is the string at the end of the URL.
# To verify each new invocation of these requests, the HTML document
# includes CSS styling to produce a randomly colored background.
@app.route("/", methods=["GET"])
@app.route("/<name>", methods=["GET"])
def say_hello(name="world"):
    bg = random.sample(range(1, 255), 3)                       # ← NEW
    hex = (int(bg[0]) * 256) + (int(bg[1]) * 16) + int(bg[2])  # ← NEW
    fg_color = set_text_color(bg)                              # ← NEW
    bg_color = f"#{hex:06x}"                                   # ← NEW
    style = f"color:{fg_color}; background-color:{bg_color}"   # ← NEW
    html = f'<h1 style="{style}">Hello {name}!</h1>'           # ← MODIFIED
    return html


# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=PORT)

ターミナル(Open Terminal ボタン)に戻り、control-C(Ctrl キーを押しながら「C」を押す)を入力して実行中のアプリを停止し、次のコマンドを入力して再起動します。

python3 main.py

もう一度 web preview ボタンをクリックし、Preview on Port 8080 メニュー項目をクリックして、実行中のアプリのウェブブラウザ タブを開きます。生成されたテキストが表示されます。指定した接尾辞またはデフォルトの「Hello world!」という文字列が、次のようにランダムな色の背景の前に表示されます。

baf8d028f15ea7f4.png

ページを数回再読み込みすると、アプリにアクセスするたびに背景色がランダムに変化することがわかります。

これでアプリは完成です。おめでとうございます。次のステップでは、アプリをコンテナにパッケージ化する方法と、そのメリットについて説明します。

4. アプリをコンテナ化する

17cc234ec3325a8a.png

コンテナとは

コンテナ(特に Docker)を使用すると、すべての依存関係をバンドルしてアプリケーションを実行するモジュラー ボックスを作成できます。この結果をコンテナ イメージと呼びます。このセクションでは、アプリケーションとそのすべての依存関係をカプセル化するために使用するコンテナ イメージを作成します。

依存関係についてですが、前の手順で、デベロッパー環境でアプリを実行したときに、pip3 install -r requirements.txt を実行し、requirements.txt ファイルにすべての依存ライブラリと対応するバージョンが含まれていることを確認する必要がありました。コンテナを使用すると、コンテナ イメージの生成時にこれらの要件がインストールされるため、コンテナの利用者はインストールについて心配する必要がありません

このコンテナ イメージは、Cloud Run にアプリケーションをデプロイするための基本的なビルディング ブロックとなります。コンテナはほぼすべての仮想サーバーまたは実サーバーで使用できるため、アプリケーションを任意の場所にデプロイしたり、アプリケーションをあるサービス プロバイダから別のサービス プロバイダに、またはオンプレミスからクラウドに移行したりできます。

コンテナは、アプリケーションの次の点を改善します。

  • 再現可能 - コンテナは自己完結型で完全
  • ポータブル - コンテナは業界横断的なビルディング ブロックであり、クラウド プロバイダや環境をまたいだアプリケーションの移植性を実現します。

つまり、コンテナは「一度書けば、どこでも動く」という機能を最終的に提供します。このルールの例外として、生成されたコンテナは、作成したプロセッサ タイプでの実行に制限されますが、他のハードウェア構成用のコンテナ バージョンを生成する方法もあります。

それでは、コンテナを作成してみましょう。Docker というコンテナを作成するための特定のテクノロジーを使用します。

Cloud エディタで、Dockerfile という名前の新しいファイルを作成します。このファイルは、イメージを構築するための設計図です。オペレーティング環境とソースコード、依存関係のインストール方法、アプリのビルド方法、コードの実行方法を Docker に伝えます。

# Use an official lightweight Python image.
FROM python:3.9-slim

# Copy local code to the container image.
WORKDIR /app
COPY main.py .
COPY requirements.txt .

# Install dependencies into this container so there's no need to 
# install anything at container run time.
RUN pip install -r requirements.txt

# Service must listen to $PORT environment variable.
# This default value facilitates local development.
ENV PORT 8080

# Run the web service on container startup. Here you use the gunicorn
# server, with one worker process and 8 threads. For environments 
# with multiple CPU cores, increase the number of workers to match 
# the number of cores available.
CMD exec gunicorn --bind 0.0.0.0:$PORT --workers 1 --threads 8 --timeout 0 main:app

Cloud ターミナルで次のコマンドを実行し、Cloud Build を使用してコンテナ イメージをビルドします。

gcloud builds submit --tag $TAG

レジストリに push されると、イメージ名を含む SUCCESS メッセージが表示されます。これは gcr.io/<project-id>/hello のようになります。これでイメージが Google Container Registry に保存され、いつでもどこでも再利用できるようになりました。

現在のプロジェクトに関連付けられているすべてのコンテナ イメージを一覧表示するには、次のコマンドを使用します。

gcloud container images list

次に、次の docker コマンドを使用して、Cloud Shell からローカルでアプリケーションを実行してテストします。

docker run -p $PORT:$PORT -e PORT=$PORT $TAG

-p $PORT:$PORT オプションは、ホスト環境の外部ポート $PORT(上記では 8080 に設定)を実行中のコンテナ内の同じポート番号にマッピングするように Docker に指示します。これにより、作成するサーバーコードとアプリのテスト時に接続する外部ポート番号が同じ(8080)になるため、作業が簡単になります。ただし、-p オプションを使用して、ホスト上の任意の外部ポートをコンテナ内の任意の内部ポートにマッピングすることも簡単にできます。

-e PORT=$PORT オプションは、コンテナ内で実行されているアプリで $PORT 環境変数(上記では 8080 に設定)を使用できるように Docker に指示します。

これで、コンテナ内で実行されている Python コードにウェブブラウザをポイントして、アプリをテストする準備が整いました。Cloud Shell ウィンドウで、前の手順と同様に、[ウェブでプレビュー] アイコンをクリックし、[ポート 8080 でプレビュー] を選択します。

結果は、Cloud Shell ターミナルでアプリを直接実行したときと同じように、ランダムな色の背景の前に生成されたテキストが表示されます。ページを数回再読み込みすると、アプリにアクセスするたびに背景色がランダムに変化することがわかります。

おめでとうございます!これで、アプリのコンテナ化されたバージョンが実行されました。次のセクションでは、コードを 1 行も変更せずに、コンテナ イメージを本番環境品質のウェブアプリに変換します

5. クラウドへ...

1b0665d94750ded6.gif

アプリをコンテナ化したので、この素晴らしいアプリを世界中のユーザーと共有しましょう。次は、アプリをクラウドにデプロイします。しかし、単に共有するだけでなく、もっと活用したいと考えているかもしれません。以下の点を確認してください。

  • 信頼性の高い実行 - アプリを実行しているコンピュータがクラッシュした場合に、自動的にフォールト トレランスが適用されます。
  • 自動的にスケーリング - アプリは大量のトラフィックに対応し、使用されていないときはフットプリントを自動的に削減します。
  • 使用していないリソースに対して課金されないため、費用を最小限に抑えることができます。課金されるのは、トラフィックへの応答中に消費されたリソースのみです。
  • カスタム ドメイン名でアクセス可能 - サービスにカスタム ドメイン名を割り当てるワンクリック ソリューションにアクセスできます。
  • 優れたレスポンス時間を提供します。コールド スタートのレスポンスは妥当ですが、最小インスタンス構成を指定することで微調整できます。
  • 標準の SSL/TLS ウェブ セキュリティを使用したエンドツーエンドの暗号化をサポートします。サービスをデプロイすると、標準のウェブ暗号化と、対応する必要な証明書が無料で自動的に取得されます。

アプリを Google Cloud Run にデプロイすると、上記のすべてのメリットが得られます。

アプリを Cloud Run にデプロイする

まず、新しいリビジョンと古いリビジョンを区別できるようにアプリを変更しましょう。これを行うには、デフォルトのメッセージが「Hello world!」から「Hello from Cloud Run!」に変更されるように main.py ファイルを変更します。つまり、main.py の次の行を次のように変更します。

def say_hello(name="world"):

の行を以下のように変更します。

def say_hello(name="from Cloud Run"):

Cloud Run はリージョナルです。つまり、Cloud Run サービスを実行するインフラストラクチャは特定のリージョンに配置され、そのリージョン内のすべてのゾーンで冗長的に利用できるよう Google によって管理されます。上記の「設定」セクションで、REGION 環境変数を使用してデフォルトのリージョンを定義しました。

次のコマンドを使用して、コンテナ イメージを再ビルドし、コンテナ化されたアプリケーションを Cloud Run にデプロイします。

gcloud builds submit --tag $TAG
gcloud run deploy "$APP"   \
  --image "$TAG"           \
  --platform "managed"     \
  --region "$REGION"       \
  --allow-unauthenticated
  • gcloud config set run/region $REGION を使用してデフォルトのリージョンを定義することもできます。
  • --allow-unauthenticated オプションを使用すると、サービスが一般公開されます。未認証のリクエストを回避するには、代わりに --no-allow-unauthenticated を使用します。

ここで指定するイメージは、前の手順でビルドした Docker イメージです。Cloud Build サービスのおかげで、結果のイメージが Google Container Registry に保存され、Cloud Run サービスがそれを見つけてデプロイできます。

デプロイが完了するまで少しお待ちください。成功すると、コマンドラインにサービス URL が表示されます。

Deploying container to Cloud Run service [hello] in project [PROJECT_ID...
✓ Deploying new service... Done.                                   
  ✓ Creating Revision... Revision deployment finished. Waiting for health check...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [hello] revision [hello-...] has been deployed and is serving 100 percent of traffic.
Service URL: https://hello-....a.run.app

次のコマンドを使用して、サービス URL を取得することもできます。

gcloud run services describe hello  \
  --platform managed                \
  --region $REGION                  \
  --format "value(status.url)"

次のような内容が表示されます。

https://hello-....a.run.app

このリンクは、Cloud Run サービスの専用 URL で、TLS セキュリティが適用されています。このリンクは永続的で(サービスを無効にしない限り)、インターネット上のどこでも使用できます。これは、前述の一時的な仮想マシンに依存する Cloud Shell のプロキシ メカニズムを使用しません。

ハイライト表示された Service URL をクリックして、実行中のアプリのウェブブラウザ タブを開きます。ランダムな色の背景の前に「Hello from Cloud Run!」というメッセージが表示されます。

おめでとうございます!アプリが Google Cloud で実行されるようになりました。アプリは、TLS(HTTPS)暗号化と、驚くほどのトラフィック レベルへの自動スケーリングにより、公開されます。

でも、このプロセスはもっと簡単にできると思います。

6. コンテナを自動的に作成する

これはすべて非常に便利ですが、Dockerfile やコンテナについて考えたくない場合はどうすればよいでしょうか。ほとんどの開発者と同様に、アプリケーション コードの記述に集中して、コンテナ化は他の人に任せたい場合はどうすればよいですか?Cloud Run は、まさにこの目的のために存在する Buildpacks というオープンソース標準をサポートしています。これは、ソースファイルのコレクションからコンテナを製造するプロセスを自動化するためのものです。

たとえば、コンテナのビルド方法を高度にカスタマイズしたい場合など、明示的な Dockerfile の使用を希望するデベロッパーもいます。ただし、この演習のような一般的なケースでは、ビルドパックが適切に機能し、Dockerfile を手動で作成する必要がありません。Buildpack を使用するようにコードを変更しましょう。

まず、新しいリビジョンと古いリビジョンを区別できるようにアプリを変更しましょう。これを行うには、デフォルトのメッセージが「Hello from Cloud Run!」から「Hello from Cloud Run with Buildpacks!」に変更されるように main.py ファイルを変更します。つまり、main.py の次の行を次のように変更します。

def say_hello(name="from Cloud Run"):

の行を以下のように変更します。

def say_hello(name="from Cloud Run with Buildpacks"):

次に、Procfile という名前の新しいファイルを作成して、ビルドパックを活用します。Cloud エディタでファイルを作成し、次の 1 行のテキストを挿入します。

web: python3 main.py

これにより、ビルドバック システムは自動生成されたコンテナでアプリを実行する方法を認識します。この指示があれば、Dockerfile は不要になります。これを確認するには、Dockerfile を削除して、Cloud Shell ターミナルで次のコマンドを実行します。

gcloud beta run deploy "$APP"  \
    --source .                 \
    --platform "managed"       \
    --region "$REGION"         \
    --allow-unauthenticated

これは、前の手順でアプリをデプロイするために実行したコマンドと似ていますが、今回は --image オプションを --source . オプションに置き換えています。これにより、gcloud コマンドは、現在のディレクトリにあるソースファイルに基づいて(--source .dot は現在のディレクトリの短縮形)、Buildpack を使用してコンテナ イメージを作成するように指示されます。サービスがコンテナ イメージを暗黙的に処理するため、この gcloud コマンドでイメージを指定する必要はありません。

もう一度、ハイライト表示された Service URL をクリックして、実行中のアプリのウェブブラウザ タブを開き、サービスがランダムな色の背景の前に「Hello from Cloud Run with Buildpacks!」と表示していることを確認して、このデプロイが機能していることを確認します。

ビルドパックを使用して Dockerfile を作成することで、3 つの簡単な手順が 2 つに減っていることに注目してください。

  1. 開発環境でアプリを作成します。
  2. 1 つのコマンドでまったく同じコードをクラウドにデプロイします。

7. コマンドラインを使用する必要がありますか?

いいえ。ほぼすべての Google Cloud サービスと同様に、Cloud Run を操作する方法は 3 つあります。

  • gcloud コマンドライン ツール(先ほど説明しました)。
  • 直感的なポイント アンド クリック操作をサポートする Cloud Console を介したリッチなウェブ ユーザー インターフェース。
  • プログラムで、Java、C#、Python、Go、Javascript、Ruby、C/C++ など、多くの一般的な言語で使用できる Google クライアント ライブラリを使用します。

コンソール UI を使用して、Cloud Run アプリの追加インスタンスをデプロイしましょう。左上のメニューから Cloud Run サービスのランディング ページに移動します。

e2b4983b38c81796.png

次のように、Cloud Run サービスの概要が表示されます。

b335e7bf0a3af845.png

[サービスの作成] リンクをクリックして、デプロイ プロセスを開始します。

51f61a8ddc7a4c0b.png

サービス名として「hello-again」と入力し、デフォルトのデプロイ プラットフォームとリージョンを使用して、[次へ] をクリックします。

8a17baa45336c4c9.png

コンテナ イメージの URL(gcr.io/cloudrun/hello)を入力します。これは、テスト用に Google が作成したコンテナです。[詳細設定] プルダウンをクリックすると、使用可能な多くの構成設定の一部が表示されます。カスタマイズできる項目をいくつかご紹介します。

  • ポート番号とコンテナのエントリ ポイント(コンテナのビルド時に指定されたエントリ ポイントをオーバーライドします)
  • ハードウェア: メモリと CPU の数
  • スケーリング: 最小インスタンス数と最大インスタンス数
  • 環境変数
  • その他: リクエスト タイムアウト設定、コンテナあたりの最大リクエスト数、HTTP/2

[次へ] ボタンをクリックしてダイアログを進めます。次のダイアログでは、サービスのトリガー方法を指定できます。[上り(内向き)] で [すべてのトラフィックを許可する] を選択し、[認証] で [未認証のトラフィックを許可する] を選択します。

e78281d1cff3418.png

これは最も自由な設定です。認証情報を指定しなくても、公共のインターネット上のどこからでも Cloud Run アプリにアクセスできます。アプリにさらに制限の厳しい設定が必要になることもありますが、この学習演習ではシンプルな設定のままにします。

[Create] ボタンをクリックして、Cloud Run サービスを作成します。数秒後、Cloud Run サービスの概要リストに新しいサービスが表示されます。概要行には、最新のデプロイ(日時とデプロイしたユーザー)と、いくつかの重要な構成設定が表示されます。サービス名のリンクをクリックして、新しいサービスの詳細を確認します。

サービスを確認するには、概要ページの上部に表示されている URL をクリックします。次の例では、URL がハイライト表示されています。

6c35cf0636dddc51.png

次のように表示されます。

3ba6ab4fe0da1f84.png

新しい Cloud Run サービスをデプロイしたので、REVISIONS タブを選択して、複数のデプロイを管理する方法を確認します。

2351ee7ec4a356f0.png

コンソールから新しいリビジョンを直接デプロイするには、次のスクリーンショットの例でハイライト表示されている EDIT & DEPLOY NEW REVISION ボタンをクリックします。

a599fa88d00d6776.png

今すぐボタンをクリックして、新しいリビジョンを作成します。コンテナ URL の横にある SELECT ボタンをクリックします(下図を参照)。

5fd1b1f8e1f11d40.png

ポップアップ表示されたダイアログで、Buildpacks を使用して Cloud Build からデプロイしたシンプルなウェブアプリを見つけて選択します。コンテナ イメージを必ず選択してください

gcr.io/<project>/cloud-run-source-deploy

folder のようにします。

8a756c6157face3a.png

選択したら、一番下までスクロールして DEPLOY ボタンをクリックします。これで、アプリの新しいリビジョンがデプロイされました。確認するには、サービス URL に再度アクセスし、カラフルな「Hello from Cloud Run with Buildpacks!」ウェブアプリが表示されていることを確認します。

ご覧のとおり、[リビジョン] タブにはデプロイしたすべてのリビジョンの概要が表示されます。このサービスには 2 つのリビジョンが表示されます。リビジョンの名前の左にあるラジオボタンをクリックしてリビジョンを選択すると、画面の右側にリビジョンの詳細の概要が表示されます。これらのボタンを選択すると、2 つのリビジョンが 2 つの異なるコンテナ イメージから派生していることがわかります。

MANAGE TRAFFIC ボタンを使用すると、特定のリビジョンに送信される受信リクエストの分散を変更できます。特定のリビジョンに送信されるトラフィック量を微調整できるため、次のような有用なユースケースが実現します。

  • 受信トラフィックのごく一部でアプリの新しいバージョンをカナリア テストする
  • 問題のあるリリースから以前のリビジョンにトラフィックを戻す
  • A/B テスト

MANAGE TRAFFIC ボタンは次の場所にあります。

519d3c22ae028287.png

次のように 50/50 のトラフィック分割を指定して、2 つのリビジョン間でトラフィックを 50/50 に分割するように構成します。

8c37d4f115d9ded4.png

[保存] ボタンをクリックし、サービスの URL に繰り返しアクセスして 50/50 の分割を確認します。リクエストの平均半分が現在のリビジョン(「Hello from Cloud Run with Buildpacks!」)で処理され、半分が以前のリビジョン(「It's running!」)で処理されていることを確認します。

[サービスの詳細] ページの他のタブでは、パフォーマンス、トラフィック、ログをモニタリングできます。これにより、サービスの稼働状況とパフォーマンスに関する貴重な分析情報を得ることができます。[権限] タブで、サービスへのアクセスを微調整することもできます。このページのタブを少し時間をかけて確認し、利用可能な機能を確認してください。

プログラム インターフェース

前述のように、Cloud Run サービスをプログラムで作成、デプロイ、管理することもできます。手動タスクの場合、このオプションはコマンドラインやウェブ コンソールよりも高度ですが、Cloud Run サービスを自動化するには、この方法が最適です。Google クライアント ライブラリは、複数の一般的なプログラミング言語で使用できます。

8. アプリをテストする

198ada162d1f0bf1.png

この最後のステップでは、人工的な負荷テストを実行してアプリのストレステストを行い、需要の増加に応じてアプリがどのようにスケーリングされるかを確認します。ここでは、Cloud Shell にプリインストールされている hey というツールを使用します。このツールを使用すると、ロードテストを実行して結果を表示できます。

テストを実行する

Cloud Shell ターミナルで次のコマンドを実行して、ロードテストを実行します。

hey -q 1000 -c 200 -z 30s https://hello-...run.app

コマンド引数は次のように解釈されます。

  • -q 1000 - 1 秒あたり約 1,000 件のリクエストで負荷をかける
  • -c 200 - 200 個の並列ワーカーを割り当てます
  • -z 30s - 負荷テストを 30 秒間実行します。
  • このコマンドラインの最後の引数としてサービス URL を必ず使用してください

テストの結果は次のようになります。

 Summary:
 Total:        30.2767 secs
 Slowest:      3.3633 secs
 Fastest:      0.1071 secs
 Average:      0.1828 secs
 Requests/sec: 1087.2387
 Total data:   3028456 bytes
 Size/request: 92 bytes

Response time histogram:
 0.107 [1]     |
 0.433 [31346] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 0.758 [1472]  |■■
 1.084 [82]    |
 1.410 [4]     |
...

Latency distribution:
...
 50% in 0.1528 secs
 75% in 0.1949 secs
 90% in 0.2442 secs
 95% in 0.4052 secs
 99% in 0.7062 secs

Details (average, fastest, slowest):
...
 req write:    0.0000 secs, 0.0000 secs, 0.0232 secs
 resp wait:    0.1824 secs, 0.1070 secs, 3.2953 secs
 resp read:    0.0000 secs, 0.0000 secs, 0.0010 secs
Status code distribution:
 [200] 32918 responses

この概要から、次のことがわかります。

  • 30 秒間に約 1,000 件/秒の割合で 32,918 件のリクエストが送信されました。
  • エラーは発生しませんでした(HTTP 200 レスポンスのみ)。
  • 平均レイテンシは 180 ミリ秒でした。
  • 最小レイテンシは 107 ミリ秒、最悪のケースは 3.3 秒でした
  • 90 パーセンタイルのレイテンシは 244 ミリ秒でした。

Cloud Run コンソールの METRICS タブを確認すると、サーバー側のパフォーマンスを確認できます。

e635c6831c468dd3.png

9. クリーンアップ

サービスが使用されていない場合、Cloud Run の料金は発生しませんが、ビルドしたコンテナ イメージが保存されていると課金される場合があります。

課金されないようにするには、GCP プロジェクトを削除してプロジェクト内のすべてのリソースへの課金を停止するか、次のコマンドを使用してコンテナ イメージを単純に削除します。

gcloud container images delete $TAG

Cloud Run サービスを削除するには、次のコマンドを使用します。

gcloud run services delete hello --platform managed --region $REGION --quiet
gcloud run services delete hello-again --platform managed --region $REGION --quiet

10. お疲れさまでした。

9a31f4fdbbf1ddcb.png

おめでとうございます。本番環境の Cloud Run アプリを正常にビルドしてデプロイできました。この過程で、コンテナと独自のコンテナをビルドする方法について学習しました。また、gcloud コマンドライン ツールと Cloud Console の両方を使用して、Cloud Run でアプリを簡単にデプロイする方法も学びました。これで、あなたの素晴らしい作品を世界中に公開する方法がわかりました。

最後に、重要な質問を 1 つご紹介します。

開発環境でアプリが動作するようになったら、Cloud Run が提供するすべての本番環境グレードの属性を使用して、アプリをクラウドにデプロイするために何行のコードを変更する必要がありましたか?

答えは 0 です。

おすすめの Codelab...

その他の便利な機能

リファレンス ドキュメント

11. 行動を促すフレーズ

Google Cloud ロゴ

この Codelab をお楽しみいただけたなら、Google Cloud を実際に使用する時間を増やして、ぜひ Google Cloud Innovators にご参加ください

Innovators 一般メンバーバッジのロゴ

Google Cloud Innovators は無料で、次の特典があります。

  • ライブ ディスカッション、AMA、ロードマップ セッションに参加して、Google 社員から直接最新情報を入手できます
  • Google Cloud の最新ニュースをメールでお届けします
  • デジタルバッジとビデオ会議の背景
  • Skills Boost でラボと学習に利用できる 500 クレジット

登録するには、こちらをクリックしてください。