【GCP】Cloud Pub/SubとCloud Runを連携してみる
今回は Cloud Pub / Sub と Cloud Run を連携する方法 を解説していきたいと思います!
以下の公式チュートリアルを参考に、Cloud Pub / Sub と Cloud Run の連携を試していきたいと思います。
目次
- 目次
- 簡単な流れ
- 使用する変数を解説
- デフォルト設定
- Pub/Sub トピックを作成する
- サンプルコードを取得
- コードの内容
- デプロイ
- Pub / Sub と Cloud Run の連携設定
- Pub / Sub サブスクリプション作成
- 動作確認
- 後始末
- まとめ
簡単な流れ
本記事では、以下のような流れで解説を進めていきます。
- 使用する変数を解説
- Pub / Sub トピックを作成
- 使用するコードを解説
- Cloud Run へコンテナをデプロイ
- Pub / Sub サブスクリプションを作成
- 動作確認
- 後始末
- まとめ
それでは、早速、Cloud Pub / Sub と Cloud Run を連携する方法を解説していきたいと思います!
使用する変数を解説
以下は解説中で利用する変数リストです。本記事をトレースする場合に活用してください。
PROJECT_ID=[プロジェクトID] PROJECT_NUMBER=[プロジェクト番号] REGION=[リージョン] CLUSTER_NAME=[クラスター名] SERVICE_NAME=pubsub-tutorial TOPIC_NAME=test-run-topic SUBSCRIPTION_NAME=test-run-subscription
※ コマンド実行時に適宜設定でも問題ありません。
以下、各変数の簡単な内容の解説です。
PROJECT_ID
: 本記事のトレースする場合に使用するプロジェクトのIDPROJECT_NUMBER
: 本記事のトレースする場合に使用するプロジェクトのプロジェクト番号REGION
: 本記事のトレースする場合に使用するプロジェクトのリージョン。既にデフォルト設定済みの場合は設定不要。CLUSTER_NAME
: 本記事のトレースする場合に使用するクラスタの名前。既にデフォルト設定済みの場合は設定不要。SERVICE_NAME
: Cloud Run にデプロイするサービスの名前TOPIC_NAME
: 作成・使用する Cloud Pub / Sub のトピック名SUBSCRIPTION_NAME
: 作成・使用する Cloud Pub / Sub サブスクリプション名
SERVICE_NAME
、TOPIC_NAME
、SUBSCRIPTION_NAME
については、仮の文字列を記載していますが、変更しても問題ありません。
本記事での解説では、上記の文字列の名称を使用して、解説を進めていきます。
デフォルト設定
デフォルトのプロジェクトやリージョンを設定していない場合は、以下のコマンドで設定してください。
gcloud config set project $PROJECT_ID gcloud config set run/region $REGION gcloud config set run/cluster $CLUSTER_NAME gcloud config set run/cluster_location $REGION
Pub/Sub トピックを作成する
起動トリガーとなる Pub / Sub トピック を作成します。
gcloud pubsub topics create $TOPIC_NAME
ここで作成したトピックにメッセージが送られると、Cloud Run に設置するサンプルサービスが起動します。
Cloud Run へのサンプルサービスのデプロイについては、この後、解説していきます。
サンプルコードを取得
Cloud Run のサンプルコードは、以下のリポジトリに含まれるコードを利用します。
以下のコマンドでサンプルリポジトリをクローンしてください。
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
コードの内容
nodejs-docs-samples/run/pubsub
にあるコードを使用します。
Cloud Run にデプロイされる主なコードは以下の3つです。
nodejs-docs-samples/run/pubsub/Dockerfile
nodejs-docs-samples/run/pubsub/index.js
nodejs-docs-samples/run/pubsub/app.js
以下、簡単にファイルの中身を見ていきます。
Dockerfile
nodejs-docs-samples/run/pubsub/Dockerfile
の中身は以下の通りです。
FROM node:10-slim WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --production COPY . . CMD [ "npm", "start" ]
Cloud Run にデプロイされるNodeコンテナです。
主なコードの3つには含めていませんが、コピーされるpackage.json
のscripts.start
フィールドはnode index.js
となっています。
コンテナの起動時に、このあと解説するnodejs-docs-samples/run/pubsub/index.js
ファイルが実行されます。
index.js
nodejs-docs-samples/run/pubsub/index.js
の中身は以下の通りです。
const app = require('./app.js'); const PORT = process.env.PORT || 8080; app.listen(PORT, () => console.log(`nodejs-pubsub-tutorial listening on port ${PORT}`) );
ウェブサーバのスタート部分。
ルーティングや Pub / Sub メッセージの処理部分は、app.js
の方に分割されています。
app.js
については、次の項目で解説します。
app.js
nodejs-docs-samples/run/pubsub/app.js
の中身は以下の通り。
const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.post('/', (req, res) => { if (!req.body) { const msg = 'no Pub/Sub message received'; console.error(`error: ${msg}`); res.status(400).send(`Bad Request: ${msg}`); return; } if (!req.body.message) { const msg = 'invalid Pub/Sub message format'; console.error(`error: ${msg}`); res.status(400).send(`Bad Request: ${msg}`); return; } const pubSubMessage = req.body.message; const name = pubSubMessage.data ? Buffer.from(pubSubMessage.data, 'base64').toString().trim() : 'World'; console.log(`Hello ${name}!`); res.status(204).send(); }); module.exports = app;
app.js
では主に ルーティングと Pub / Sub メッセージの処理 が記述されています。
req.body.message
が設定されていない場合は、不正なリクエストとみなしてエラーメッセージが返されます。
req.body.message
が設定されている場合は、メッセージの内容を使って、コンソールにHello ○○!
と出力されます。
デプロイ
続いて、紹介したコードを元に、コンテナイメージをビルド・デプロイします。
cd nodejs-docs-samples/run/pubsub/ gcloud builds submit --tag gcr.io/$PROJECT_ID/pubsub gcloud run deploy $SERVICE_NAME --image gcr.io/$PROJECT_ID/pubsub
gcloud builds submit ...
コマンドでは、コードの内容で解説したDockerfile
を元にコンテナイメージがビルドされ、Container Resistry へアップロードされます。
ビルドは Cloud Build を使用して行われます。
gcloud run deploy ...
コマンドでは、アップロードされたコンテナイメージを Cloud Run にデプロイしています。
Cloud Run にデプロイする際の、未承認を許可するかどうかの質問には n(いいえ)と答えてください。
Pub / Sub と Cloud Run の連携設定
Cloud Pub / Sub と Cloud Run を連携するための権限設定をしていきます。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member=serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountTokenCreator gcloud iam service-accounts create cloud-run-pubsub-invoker \ --display-name "Cloud Run Pub/Sub Invoker" gcloud run services add-iam-policy-binding $SERVICE_NAME \ --member=serviceAccount:cloud-run-pubsub-invoker@${PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/run.invoker
まず、gcloud projects add-iam-policy-binding ...
コマンドで、プロジェクトで Pub / Sub 認証トークンを作成できるようにしています。
続いて、gcloud iam service-accounts create ...
コマンドの部分で、_Cloud Run に作成したサービス(ここではpubsub-tutorial
)を起動するためのサービスアカウントを作成 しています。
最後のgcloud run services add-iam-policy-binding ...
コマンドでは、作成したサービスアカウントにpubsub-tutorial
サービスを起動する権限を付与 しています。
参考ページ
Pub / Sub サブスクリプション作成
Pub/Sub トピックを作成するで作成したトピックを購読するサブスクリプションを作成します。
END_POINT=[Cloud Run サービスの URL ] gcloud pubsub subscriptions create $SUBSCRIPTION_NAME --topic $TOPIC_NAME \ --push-endpoint=${END_POINT} \ --push-auth-service-account=cloud-run-pubsub-invoker@${PROJECT_ID}.iam.gserviceaccount.com
ここで、--push-endpoint
オプションでプッシュ先を指定 しています。
END_POINT
変数には作成した Cloud Run サービス pubsub-tutorial
のURLを設定してください。
URLはpubsub-tutorial
のページで確認できます。
pubsub-tutorial
のページの上部に表示される https://xxxx.run.app
のような形式のURLを設定してください。
また、--push-auth-service-account
オプションの部分で、先ほど作成した pubsub-tutorial
サービスの起動権限持ったサービスアカウントが Pub / Sub サブスクリプションを紐づけられています。
これにより、作成した Pub/Sub サブスクリプションに pubsub-tutorial
サービスの起動権限が間接的に付与されています。
動作確認
実際に、作成した Pub / Sub トピックにメッセージを公開して、pubsub-tutorial
サービスがちゃんと起動するか確認します。
gcloud pubsub topics publish $TOPIC_NAME --message "Runner"
Google Cloud Consoleを開いて、pubsub-tutorial
サービスのページを開いてください。
サービスページに「ログ」タブがあると思うので、クリックしてログを表示させてください。
「Hello Runner!」と表示されていれば、成功です!
※ ログが表示されるまでに時間がかかる事があります。 すぐに表視されない場合は、少し開けてから再度確認してみてください。
後始末
使用した Cloud Run サービスや Pub / Sub トピックス、サブスクリプションを削除します。
gcloud run services delete $SERVICE_NAME gcloud pubsub subscriptions delete $SUBSCRIPTION_NAME gcloud pubsub topics delete $TOPIC_NAME
プロジェクトを削除する場合や、gcloudのデフォルト設定を削除する場合は、以下のページを参考にしてください。
Cloud Run チュートリアルで Pub/Sub を使用する #クリーンアップ
まとめ
以上、「 Cloud Pub / Sub と Cloud Run を連携する方法」について簡単にまとめてみました!
サービスアカウントの設定が少し面倒ですが、その辺に慣れてしまえば、それほど手間もかからなそうです。
今後、メッセージングサービスが必要になる事があったら、使ってみたいと思います。