1. はじめに
概要
多くの組織は、サービスやアプリケーションのネットワーク トラフィックを保護するために、境界制御を備えた Google Cloud 上で Virtual Private Cloud(VPC)ネットワークを使用して、データの引き出しを防止しています。VPC ネットワークは、Google の本番環境ネットワーク内に仮想的に実装された物理ネットワークです。VPC ネットワークは Compute Engine 仮想マシン(VM)インスタンスの接続を提供し、内部アプリケーション ロードバランサにネイティブの内部パススルー ネットワーク ロードバランサとプロキシ システムを提供します。また、Cloud VPN トンネルと Cloud Interconnect 用の VLAN アタッチメントを使用してオンプレミス ネットワークに接続し、Google Cloud の外部ロードバランサからバックエンドにトラフィックを分散します。
VM とは異なり、Cloud Run サービスは、デフォルトでは特定の VPC ネットワークに関連付けられていません。この Codelab では、VPC からのトラフィックのみが Cloud Run サービス(バックエンド サービスなど)にアクセスできるように、上り(内向き)接続の設定を変更する方法を示します。さらに、この Codelab では、2 つ目のサービス(フロントエンド サービスなど)が VPC を介してバックエンドの Cloud Run サービスにアクセスする方法を説明します。
この例では、バックエンドの Cloud Run サービスは Hello World を返します。フロントエンドの Cloud Run サービスには、URL を収集するための入力フィールドが UI に用意されています。次に、フロントエンド サービスがその URL(バックエンド サービスなど)に対して GET リクエストを行うため、これが(ブラウザ間リクエストではなく)サービス間リクエストになります。フロントエンド サービスがバックエンドに到達できると、ブラウザに「hello world」というメッセージが表示されます。
学習内容
- VPC から Cloud Run サービスへのトラフィックのみを許可する方法
- 内部上り(内向き)トラフィックのみの Cloud Run サービスと通信するように Cloud Run サービスで下り(外向き)を構成する方法
2. 設定と要件
前提条件
- Cloud コンソールにログインしています。
- 以前に Cloud Run サービスをデプロイしました。たとえば、「ソースコードからウェブサービスをデプロイする」クイックスタートの手順に沿って開始できます。
Cloud Shell をアクティブにする
- Cloud Console で、[Cloud Shell をアクティブにする]
をクリックします。
Cloud Shell を初めて起動する場合は、内容を説明する中間画面が表示されます。中間画面が表示されたら、[続行] をクリックします。
Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。
この仮想マシンには、必要なすべての開発ツールが読み込まれます。5 GB の永続的なホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワークのパフォーマンスと認証が大幅に向上しています。この Codelab での作業のほとんどはブラウザを使って行うことができます。
Cloud Shell に接続すると、認証が完了し、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。
- 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`
- Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。
gcloud config list project
コマンド出力
[core] project = <PROJECT_ID>
上記のようになっていない場合は、次のコマンドで設定できます。
gcloud config set project <PROJECT_ID>
コマンド出力
Updated property [core/project].
3. Cloud Run サービスを作成する
環境変数を設定する
この Codelab 全体で使用する環境変数を設定できます。
REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend BACKEND=backend
バックエンドの Cloud Run サービスを作成する
まず、ソースコード用のディレクトリを作成し、そのディレクトリに移動します。
mkdir -p internal-codelab/frontend internal-codelab/backend && cd internal-codelab/backend
次に、次の内容の package.json
ファイルを作成します。
{ "name": "backend-service", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.18.1" } }
次に、以下の内容で index.js
ソースファイルを作成します。このファイルには、サービスのエントリ ポイントと、アプリのメインロジックが含まれています。
const express = require('express'); const app = express(); app.use(express.urlencoded({ extended: true })); app.get('/', function (req, res) { res.send("hello world"); }); const port = parseInt(process.env.PORT) || 8080; app.listen(port, () => { console.log(`helloworld: listening on port ${port}`); });
最後に、次のコマンドを実行して Cloud Run サービスをデプロイします。
gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION
フロントエンドの Cloud Run サービスを作成する
フロントエンド ディレクトリに移動します。
cd ../frontend
次に、次の内容の package.json
ファイルを作成します。
{ "name": "frontend", "version": "1.0.0", "description": "", "scripts": { "start": "node index.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "axios": "^1.6.6", "express": "^4.18.2" } }
次に、以下の内容で index.js
ソースファイルを作成します。このファイルには、サービスのエントリ ポイントと、アプリのメインロジックが含まれています。
const express = require("express"); const app = express(); const port = 8080; const path = require('path'); const axios = require('axios'); // serve static content (index.html) using // built-in middleware function in Express app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); // this endpoint receives a URL in the post body // and then makes a get request to that URL // results are sent back to the caller app.post('/callService', async (req, res) => { const url = req.body.url; let message = ""; try { console.log("url: ", url); const response = await axios.get(url); message = response.data; } catch (error) { message = error.message; console.error(error.message); } res.send(` ${message} <p> </p> `); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
index.html ファイル用のパブリック ディレクトリを作成する
mkdir public touch public/index.html
そして index.html を更新して以下を含めます。
<html> <script src="https://unpkg.com/htmx.org@1.9.10" integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC" crossorigin="anonymous" ></script> <body> <div style="margin-top: 100px; margin-left: 100px"> <h1>I'm the Frontend service on the Internet</h1> <form hx-trigger="submit" hx-post="/callService" hx-target="#message"> <label for="url"> URL:</label> <input style="width: 308px" type="text" id="url" name="url" placeholder="The backend service URL" required /> <button hx-indicator="#loading" type="submit">Submit</button> <p></p> <span class="htmx-indicator" id="loading"> Loading... </span> <div id="message" style="white-space: pre-wrap"></div> <p></p> </form> </div> </body> </html>
最後に、次のコマンドを実行して Cloud Run サービスをデプロイします。
gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION
バックエンド サービスを呼び出す
2 つの Cloud Run サービスが正常にデプロイされたことを確認します。
ウェブブラウザでフロントエンド サービスの URL を開きます。
テキスト ボックスにバックエンド サービスの URL を入力します。このリクエストは、ブラウザからルーティングされるのではなく、フロントエンドの Cloud Run インスタンスからバックエンドの Cloud Run サービスにルーティングされることに注意してください。
「hello world」と表示されます。
4. 内部 Ingress 専用にバックエンド サービスを設定する
次の gcloud コマンドを実行して、VPC ネットワーク内からのトラフィックのみにバックエンド サービスへのアクセスを許可します。
gcloud run services update $BACKEND --ingress internal --region $REGION
バックエンド サービスが VPC からのトラフィックのみを受信できることを確認するには、フロントエンド サービスからバックエンド サービスを呼び出してみます。
今回は、「Request failed with status code 404(リクエストが失敗しました。ステータス コード 404)」と表示されます。
このエラーは、フロントエンドの Cloud Run サービスのアウトバウンド リクエスト(下り、外向き)が最初にインターネットに送信されるため、Google Cloud がリクエストの送信元を認識できないために発生しました。
次のセクションでは、VPC にアクセスするようにフロントエンド サービスを構成し、内部ソースとして認識されている VPC からリクエストが送信されたことを Google Cloud が認識できるようにします。
5. VPC にアクセスするようにフロントエンド サービスを構成する
このセクションでは、VPC 経由でバックエンド サービスと通信するようにフロントエンドの Cloud Run サービスを構成します。
そのためには、フロントエンドの Cloud Run インスタンスに直接 VPC 下り(外向き)を追加して、VPC 内で使用する内部 IP をサービスに付与する必要があります。次に、フロントエンド サービスからのすべてのアウトバウンド接続が VPC に向かうように下り(外向き)を構成します。
まず、次のコマンドを実行してダイレクト VPC 下り(外向き)を有効にします。
gcloud beta run services update $FRONTEND \ --network=default \ --subnet=default \ --vpc-egress=all-traffic \ --region=$REGION
これで、フロントエンド サービスが VPC にアクセスできることを確認できます。
gcloud beta run services describe $FRONTEND \ --region=$REGION
次のような出力が表示されます。
VPC access: Network: default Subnet: default Egress: all-traffic
次に、フロントエンド サービスからバックエンド サービスの呼び出しを再度試します。
今回は「hello world」と表示されます。
注: すべての下り(外向き)トラフィックが VPC にルーティングされているため、フロントエンド サービスはインターネットにアクセスできません。たとえば、フロントエンド サービスが https://curlmyip.org/ にアクセスしようとすると、タイムアウトします。
6. 完了
これでこの Codelab は完了です。
Cloud Run のドキュメントと Cloud Run サービスのプライベート ネットワークを構成する方法を確認することをおすすめします。
学習した内容
- VPC から Cloud Run サービスへのトラフィックのみを許可する方法
- Cloud Run サービスで下り(外向き)を構成して、内部上り(内向き)のみの Cloud Run サービスと通信する方法
7. クリーンアップ
不注意による料金の発生(たとえば、Cloud Run サービスが誤って無料枠の毎月の Cloud Run 呼び出し割り当てよりも多く呼び出された場合)を回避するには、Cloud Run を削除するか、手順 2 で作成したプロジェクトを削除します。
Cloud Run サービスを削除するには、Cloud Run Cloud コンソール(https://console.cloud.google.com/run)に移動し、$FRONTEND サービスと $BACKEND サービスを削除します。
プロジェクト全体を削除する場合は、https://console.cloud.google.com/cloud-resource-manager に移動し、手順 2 で作成したプロジェクトを選択して [削除] を選択します。プロジェクトを削除する場合は、Cloud SDK でプロジェクトを変更する必要があります。使用可能なすべてのプロジェクトのリストを表示するには、gcloud projects list
を実行します。