はじめてみよう Google Cloud ハンズオン Cloud Run編を試す(gcloud設定、Cloud Runデプロイ)
はじめに
この記事では、以下の、「はじめてみよう Google Cloud ハンズオン Cloud Run 編」のgcloud設定やCloud Runへのデプロイを試します。
環境
実行したMacbook Proのスペックは以下のとおりです。
メモリ:64GB
プロセッサ:Intel Core i9 8コア
OS:Ventura 13.4.1(c)
リポジトリのクローン
はじめに該当のリポジトリをクローンしておきます。
git clone git@github.com:google-cloud-japan/gcp-getting-started-cloudrun.git
gcloudコマンドのインストール
はじめにgcloudコマンドを利用可能にするため、以下のコマンドを実行します。
brew install --cask google-cloud-sdk
~/.zshrc
に以下を追記します。
source "/usr/local/share/google-cloud-sdk/completion.zsh.inc"
source "/usr/local/share/google-cloud-sdk/path.zsh.inc"
~/.zshrc
を再読み込みします。
source ~/.zshrc
gcloudのバージョンを確認します。
gcloud --version
Google Cloud SDK 439.0.0
beta 2023.07.14
bq 2.0.94
core 2023.07.14
gcloud-crc32c 1.0.0
gsutil 5.25
Google Cloud プロジェクトの設定
対象の Google Cloud プロジェクトを設定
Google Cloudプロジェクトを作成し、プロジェクトIDを環境変数に設定します。
export PROJECT_ID=[PROJECT_ID]
プロジェクトIDは、ダッシュボードに進み、左上のプロジェクト情報から確認します。
プロジェクトの課金が有効化されていることを確認する
gcloud beta billing projects describe ${PROJECT_ID} | grep billingEnabled
有効化できていれば、以下の表示になりました。
billingEnabled: true
gcloudの設定
gcloud から利用する Google Cloud のデフォルトプロジェクトを設定
gcloud config set project ${PROJECT_ID}
gcloud からの Cloud Run のデフォルト設定
gcloud config set run/region asia-northeast1
gcloud config set run/platform managed
利用する機能の有効化
gcloud services enable artifactregistry.googleapis.com run.googleapis.com cloudbuild.googleapis.com sourcerepo.googleapis.com container.googleapis.com
サンプルアプリケーション
ハンズオンで利用するアプリケーションはsumservice
と呼び、REST APIで公開します。
固定文字列を返すHello Challenger API
と数値の合計を返す数値合計 API
があります。
フォルダ、ファイル構成は以下となっています。
.
└─ src
└─ sumservice
├─ .dockerignore # コンテナに含めないファイル群を指定するファイル
├─ Dockerfile # Docker コンテナ作成定義ファイル
├─ Procfile # 起動方法が記載されているファイル、Buildpacks でビルドするときに利用
├─ main.py # メイン関数ソースファイル
└─ requirements.txt # 利用ライブラリ一覧
Dockerfile
Use the official lightweight Python image.
# https://hub.docker.com/_/python
FROM python:3.9-slim
# Allow statements and log messages to immediately appear in the Knative logs
ENV PYTHONUNBUFFERED True
# Copy local code to the container image.
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
# Install dependencies.
RUN pip install -r requirements.txt
# Run the web service on container startup. Here we use the gunicorn
# webserver, with one worker process and 8 threads.
# For environments with multiple CPU cores, increase the number of workers
# to be equal to the cores available.
# Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
main.py
main.pyはFlaskを用いてAPIサーバとして実装されています。
import os
import json
import requests
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/")
def hello_world():
name = os.environ.get("NAME", "Challenger01")
return "Hello {}!".format(name)
@app.route("/sum", methods=["POST"])
def sum_numbers():
try:
json_data = request.get_json()
except:
return jsonify({'error': 'Bad Request', 'message': 'Invalid request: {}'.format(request.get_data(as_text=True))}), 400
if not 'numbers' in json_data:
return jsonify({'error': 'Bad Request', 'message': 'Request format error: {}'.format(request.get_data(as_text=True))}), 400
try:
ans = sum(json_data['numbers'])
except TypeError:
return jsonify({'error': 'Bad Request', 'message': 'Request format error: {}'.format(request.get_data(as_text=True))}), 400
return jsonify({'sum': ans}), 200
def retrieve_token(target_url):
# Set up metadata server request
metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='
token_request_url = metadata_server_token_url + target_url
token_request_headers = {'Metadata-Flavor': 'Google'}
# Fetch the token
token_response = requests.get(
token_request_url, headers=token_request_headers)
return token_response.content.decode("utf-8")
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
詳細は、サンプルアプリケーションの章をご確認ください。
Cloud Runへのデプロイ
Cloud Runへのデプロイは2種類あります。
- Dockerfileを使い、ローカルでコンテナを作成、レジストリにプッシュしてからデプロイ
- Buildpacks、Cloud Build を使い、Dockerfile 無し、かつリポジトリの指定無しにデプロイ
今回は前者を試します。
Dockerfileを使い、ローカルでコンテナを作成、レジストリにプッシュしてからデプロイ
アーキテクチャ図は、以下です。
まず、Artifact Registryを作成します。
次に、ソースファイルとDockerfileを元にイメージを作成し、そのイメージを元にしたコンテナをArtifact Registryへpushします。その後、そのコンテナを元にCloud Runへデプロイされます。
Artifact Registryにリポジトリを作成
gcloud artifacts repositories create cloudrun-handson --repository-format=docker --location=asia-northeast1 --description="Docker repository for Cloud Run hands-on"
Create request issued for: [cloudrun-handson]
Waiting for operation [projects/${PROJECT_ID}/locations/asia-northeast1/operations/18c4a96d-296e-4c11-8e5c-cf3164fff021] to complete...done.
Created repository [cloudrun-handson].
Artifact Registryにリポジトリが作成できたことを確認します。
docker コマンドの認証設定
gcloud auth configure-docker asia-northeast1-docker.pkg.dev --quiet
...
Adding credentials for: asia-northeast1-docker.pkg.dev
ローカルにコンテナを作成
(cd src/sumservice && docker build -t asia-northeast1-docker.pkg.dev/${PROJECT_ID}/cloudrun-handson/sumservice:v1 .)
docker images
コマンドでイメージが作成できたかを確認します。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
asia-northeast1-docker.pkg.dev/${PROJECT_ID}/cloudrun-handson/sumservice v1 b500b7ef15cc 6 seconds ago 161MB
作成したコンテナをArtifact Registryへpushします
docker push asia-northeast1-docker.pkg.dev/${PROJECT_ID}/cloudrun-handson/sumservice:v1
The push refers to repository [asia-northeast1-docker.pkg.dev/noted-ability-320105/cloudrun-handson/sumservice]
ba457e788bff: Pushed
a5e3673b9369: Pushed
8cc7b56b32c3: Pushed
9bfcb9ca631e: Pushed
ba4397078275: Pushed
91c4ec8027b7: Pushed
5f77f286226c: Pushed
c6e34807c2d5: Pushed
v1: digest: sha256:d6c2f5ced0e41fbdb5506e7dd6654d64a3cc2e1cc6d0b8156833fa0a5651f831 size: 1995
リポジトリにpushできたことを確認します。
Cloud Runへデプロイします
Artifact Registryへ登録されたイメージからCloud Runを認証なしで起動します。
gcloud run deploy sumservice --image=asia-northeast1-docker.pkg.dev/${PROJECT_ID}/cloudrun-handson/sumservice:v1 --allow-unauthenticated
Enabling service [run.googleapis.com] on project [xxxxxxxxxxxxxx]...
Operation "operations/acf.p2-xxxxxxxxxxxxxx-f116d24a-e537-4139-8dac-0419b160a73f" finished successfully.
Deploying container to Cloud Run service [sumservice] in project [${PROJECT_ID}] region [asia-northeast1]
✓ Deploying new service... Done.
✓ Creating Revision...
✓ Routing traffic...
✓ Setting IAM Policy...
Done.
Service [sumservice] revision [sumservice-00001-qaq] has been deployed and is serving 100 percent of traffic.
Service URL: https://xxxxxxxxxx.a.run.app
動作確認
SUM_URL=$(gcloud run services describe sumservice --format json | jq -r '.status.address.url')
curl -s -H "Content-Type: application/json" -d '{"numbers": [10, 20, 30, 300, 100]}' ${SUM_URL}/sum | jq
以下が返ってくれば、成功です。
{
"sum": 460
}
サービスの削除
デプロイしたサービスを削除します。
gcloud run services delete sumservice --quiet
おわりに
この記事では、「はじめてみよう Google Cloud ハンズオン Cloud Run 編」のgcloudコマンドのインストールからCloud Runへのデプロイまでを試しました。
Discussion