1. はじめに
概要
多くの組織では、サービスやアプリケーションのネットワーク トラフィックを保護するために、境界制御が可能な Google Cloud で Virtual Private Cloud(VCP)ネットワークを使用して、データの引き出しを防止しています。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」というメッセージが表示されます。次に、https://curlmyip.org を呼び出してフロントエンド サービスの IP アドレスを取得する方法について説明します。
学習内容
- VPC から Cloud Run サービスへのトラフィックのみを許可する方法
- フロントエンド サービスの公共のインターネット アクセスを維持しながら、内部上り(内向き)専用の Cloud Run サービス(バックエンドなど)と通信するように Cloud Run サービス(フロントエンドなど)で下り(外向き)を構成する方法。
2. 設定と要件
前提条件
- Cloud コンソールにログインしていること。
- 以前に第 2 世代の関数をデプロイしている。たとえば、Cloud Functions 第 2 世代のクイックスタートに沿ってデプロイを開始できます。
Cloud Shell をアクティブにする
- Cloud Console で、[Cloud Shell をアクティブにする]
をクリックします。

Cloud Shell を初めて起動する場合は、その内容を説明する中間画面が表示されます。中間画面が表示された場合は、[続行] をクリックします。

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

この仮想マシンには、必要な開発ツールがすべて用意されています。仮想マシンは Google Cloud で稼働し、永続的なホーム ディレクトリが 5 GB 用意されているため、ネットワークのパフォーマンスと認証が大幅に向上しています。この 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 全体で使用する環境変数を設定できます。
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
バックエンドの Cloud Run サービスを作成する
まず、ソースコードのディレクトリを作成し、そのディレクトリに移動します。
mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-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-w-internet
次に、次の内容の 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",
"htmx.org": "^1.9.10"
}
}
次に、次の内容を含む 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 Request Tester service on the Internet</h1>
<form hx-trigger="submit" hx-post="/callService" hx-target="#zen">
<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="zen" 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(例: https://frontend-your-hash-uc.a.run.app/)を開きます。
テキスト ボックスに、バックエンド サービスの URL を入力します。このリクエストは、ブラウザからではなく、フロントエンドの Cloud Run インスタンスからバックエンドの Cloud Run サービスにルーティングされます。
「hello world」と表示されます。
4. 内部上り(内向き)専用のバックエンド サービスを設定する
次の gcloud コマンドを実行して、Cloud Run サービスをプライベート ネットワークに組み込むことができます。
gcloud run services update $BACKEND --ingress internal --region $REGION
フロントエンド サービスからバックエンド サービスを呼び出そうとすると、404 エラーが発生します。フロントエンドの Cloud Run サービスのアウトバウンド接続(下り(外向き))は最初にインターネットに接続するため、Google Cloud はリクエストの送信元を認識しません。
5. VPC にアクセスするようにフロントエンド サービスを構成する
このセクションでは、VPC を介してバックエンド サービスと通信するようにフロントエンド Cloud Run サービスを構成します。
これを行うには、フロントエンドの Cloud Run サービスにダイレクト VPC 下り(外向き)を追加して、VPC ネットワーク上の内部 IP アドレスに到達できるようにする必要があります。次に、プライベート IP へのリクエストのみが VPC にルーティングされるように下り(外向き)を構成します。この構成により、フロントエンドは引き続き公共のインターネットにアクセスできます。詳細については、他の Cloud Run サービスからリクエストを受信するのドキュメントをご覧ください。
ダイレクト VPC 下り(外向き)を構成する
まず、次のコマンドを実行して、フロントエンド サービスでダイレクト VPC 下り(外向き)を使用します。
gcloud beta run services update $FRONTEND \ --network=$SUBNET_NAME \ --subnet=$SUBNET_NAME \ --vpc-egress=private-ranges-only \ --region=$REGION
これで、フロントエンド サービスが VPC にアクセスできることを確認できます。
gcloud beta run services describe $FRONTEND \ --region=$REGION
次のような出力が表示されます。
VPC access:
Network: default
Subnet: default
Egress: private-ranges-only
限定公開の Google アクセスを有効にする
次に、次のコマンドを実行して、サブネットでプライベート Google アクセスを有効にします。
gcloud compute networks subnets update $SUBNET_NAME \ --region=$REGION \ --enable-private-ip-google-access
次のコマンドを実行して、プライベート Google アクセスが有効になっていることを確認できます。
gcloud compute networks subnets describe $SUBNET_NAME \ --region=$REGION \ --format="get(privateIpGoogleAccess)"
run.app URL の Cloud DNS ゾーンを作成する
最後に、Google Cloud が run.app URL を内部 IP アドレスとして扱えるように、run.app URL の Cloud DNS ゾーンを作成します。
前のステップで、プライベート範囲のみに直接 VPC 下り(外向き)を構成したとき。つまり、宛先が内部 IP の場合、フロントエンド サービスからのアウトバウンド接続は VPC ネットワークにのみ送信されます。ただし、バックエンド サービスはパブリック IP に解決される run.app URL を使用します。
このステップでは、run.app URL が内部 IP アドレスとして認識される private.googleapis.com IP アドレス範囲に解決されるように、Cloud DNS ゾーンを作成します。これで、これらの範囲へのリクエストは VPC ネットワーク経由で転送されます。
これを行うには、https://cloud.google.com/run/docs/securing/private-networking#from-other-services をご覧ください。
# do not include the https:// in your DNS Name # for example: backend-<hash>-uc.a.run.app DNS_NAME=<your backend service URL without the https://> gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \ --description="" \ --dns-name="a.run.app." \ --visibility="private" \ --networks=$SUBNET_NAME gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \ --zone="codelab-backend-service" \ --type="A" \ --ttl="60" \ --rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"
ウェブサイトのバックエンド サービスにアクセスしようとすると、「hello world」が返されます。
https://curlmyip.org/ を使用してインターネットにアクセスしようとすると、IP アドレスが表示されます。
6. トラブルシューティング
設定が正しく構成されていない場合に表示される可能性のあるエラー メッセージを次に示します。
- エラー
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.appが表示された場合は、DNS A レコードに「https://」を追加していないことを確認してください。 - ゾーンを構成した後でバックエンドにアクセスしようとしたときに 404 エラーが表示された場合は、グローバル run.app レコードのキャッシュが期限切れになるまで待つ(6 時間など)か、次のコマンドを実行して新しいリビジョンを作成(キャッシュをクリア)します。
gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION
7. 完了
以上で、この Codelab は完了です。
Cloud Run のプライベート ネットワーキングに関するドキュメントを確認することをおすすめします。
学習した内容
- VPC から Cloud Run サービスへのトラフィックのみを許可する方法
- フロントエンド サービスの公共のインターネット アクセスを維持しながら、内部上り(内向き)専用の Cloud Run サービス(バックエンドなど)と通信するように Cloud Run サービス(フロントエンドなど)で下り(外向き)を構成する方法。
8. クリーンアップ
誤って課金されないようにする(たとえば、この Cloud Run サービスが無料枠の Cloud Run 呼び出しの月間割り当てよりも多く呼び出された場合など)、Cloud Run サービスを削除するか、ステップ 2 で作成したプロジェクトを削除します。
Cloud Run サービスを削除するには、Cloud Run Cloud Console(https://console.cloud.google.com/functions/)に移動し、この Codelab で作成した $FRONTEND サービスと $BACKEND サービスを削除します。
プロジェクト全体を削除する場合は、https://console.cloud.google.com/cloud-resource-manager に移動し、ステップ 2 で作成したプロジェクトを選択して、[削除] を選択します。プロジェクトを削除した場合は、Cloud SDK でプロジェクトを変更する必要があります。gcloud projects list を実行すると、使用可能なすべてのプロジェクトのリストを表示できます。