Google Cloud Runの実践ガイド|コンテナをサーバーレスで動かす方法と活用術

kento_morota 18分で読めます

「コンテナを使いたいけれど、Kubernetesは複雑すぎる」「サーバーレスでWebアプリを動かしたいが、制約が多すぎる」――こうした悩みを持つエンジニアやIT担当者は少なくありません。

Google Cloud Runは、コンテナイメージをそのままサーバーレスで実行できるGCPのマネージドサービスです。インフラ管理の手間を最小限に抑えながら、コンテナの柔軟性を最大限活かせる点が大きな特徴です。

この記事では、Cloud Runの基本概念から実際のデプロイ手順、運用のベストプラクティスまで、実務で使える知識を体系的に解説します。GCPの基礎的なデータ分析基盤に興味がある方は、BigQueryの使い方ガイドもあわせてご覧ください。

Cloud Runとは?サーバーレスコンテナの基本概念

Cloud Runは、Googleが提供するフルマネージドのサーバーレスコンテナ実行環境です。Dockerコンテナイメージをデプロイするだけで、自動的にスケーリングされるHTTPSエンドポイントが提供されます。

Cloud Runの仕組みと特徴

Cloud Runの最大の特徴は、コンテナとサーバーレスの長所を両立している点です。従来のサーバーレス(Cloud Functionsなど)では言語やランタイムに制約がありましたが、Cloud Runではコンテナイメージとして動作するものであれば、あらゆる言語・フレームワークを利用できます。

主な特徴は以下の通りです。

  • ゼロスケール対応:リクエストがない時はインスタンス数がゼロになり、課金も発生しません
  • 自動スケーリング:リクエスト数に応じて自動的にインスタンスが増減します
  • 任意のコンテナ:Dockerfileで定義したイメージをそのまま実行できます
  • HTTPSの自動プロビジョニング:SSL証明書の管理が不要です
  • カスタムドメイン:独自ドメインのマッピングも容易です

Cloud RunとCloud Functionsの使い分け

GCPにはCloud Functionsというサーバーレスサービスもあります。どちらを選ぶべきかは用途によって異なります。

Cloud Runが適しているケース

  • Webアプリケーションやマイクロサービスの運用
  • 特定の言語・フレームワーク(Rails、Djangoなど)を使いたい場合
  • 長時間実行が必要な処理(最大60分)
  • 複数のエンドポイントを1つのサービスで提供したい場合

Cloud Functionsが適しているケース

  • 単一のイベントに対する軽量な処理
  • GCPサービス間の連携(Cloud Storageへのアップロードトリガーなど)
  • コンテナの知識なしにすぐ始めたい場合

Cloud Runの料金体系と無料枠

Cloud Runの料金は完全な従量課金制で、リクエスト処理に使ったリソースに対してのみ課金されます。無料枠も用意されており、小規模なサービスであれば無料で運用できるケースも少なくありません。

課金の仕組み

Cloud Runの課金は以下の3要素で構成されます。

1. CPU使用料
インスタンスがリクエストを処理している間のCPU時間に対して課金されます。vCPUあたり$0.00002400/秒です。

2. メモリ使用料
割り当てたメモリ量と使用時間に対して課金されます。GiBあたり$0.00000250/秒です。

3. リクエスト料
100万リクエストあたり$0.40が課金されます。

無料枠の詳細

毎月の無料枠は以下の通りです。

  • CPU:180,000 vCPU秒/月
  • メモリ:360,000 GiB秒/月
  • リクエスト:200万リクエスト/月
  • ネットワーキング:北米内1GiB/月

実際の目安として、256MBメモリ・1vCPUの構成で、1リクエストあたり200ミリ秒の処理時間であれば、月間約50万リクエストまで無料枠内で収まります。コスト管理の全体的な戦略については、クラウドコスト削減の方法も参考にしてください。

Cloud Runへのデプロイ手順|ソースコードからサービス公開まで

ここからは、実際にCloud Runにアプリケーションをデプロイする手順を解説します。Node.jsのWebアプリケーションを例に進めます。

Step 1:アプリケーションの準備

まず、HTTPリクエストを受け付けるシンプルなアプリケーションを用意します。Cloud RunではPORT環境変数で指定されたポートでリクエストを待ち受ける必要があります。

// index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;

app.get('/', (req, res) => {
  res.send('Hello from Cloud Run!');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Step 2:Dockerfileの作成

コンテナイメージをビルドするためのDockerfileを作成します。

FROM node:20-slim

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

CMD ["node", "index.js"]

ポイントは以下の通りです。

  • 軽量ベースイメージnode:20-slimを使ってイメージサイズを小さくします
  • レイヤーキャッシュの活用package*.jsonを先にコピーし、依存関係のインストール結果をキャッシュします
  • 本番依存のみ--only=productionで開発用パッケージを除外します

Step 3:gcloudコマンドでデプロイ

Google Cloud CLIを使って、ビルドとデプロイを一度に実行できます。

# ソースコードから直接デプロイ(Cloud Buildが自動的にビルド)
gcloud run deploy my-service \
  --source . \
  --region asia-northeast1 \
  --allow-unauthenticated

# コンテナイメージを先にビルドしてデプロイする場合
gcloud builds submit --tag gcr.io/PROJECT_ID/my-service
gcloud run deploy my-service \
  --image gcr.io/PROJECT_ID/my-service \
  --region asia-northeast1 \
  --allow-unauthenticated

--source .オプションを使うと、ソースコードを直接Cloud Buildに送信し、コンテナイメージのビルドからデプロイまでを自動的に行います。Dockerfileが不要な場合は、Buildpacksが自動的に適切なイメージを生成します。

Step 4:デプロイの確認

# サービスの一覧を確認
gcloud run services list

# 特定サービスの詳細確認
gcloud run services describe my-service --region asia-northeast1

# ログの確認
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=my-service" --limit 50

デプロイが成功すると、https://my-service-xxxxx-an.a.run.appのような形式のURLが自動的に発行されます。

環境変数・シークレット管理の実践

本番環境では、データベースの接続情報やAPIキーなどの機密情報を安全に管理する必要があります。Cloud Runでは環境変数とSecret Managerの2つの方法でこれを実現します。

環境変数の設定

一般的な設定値は環境変数として渡します。

# デプロイ時に環境変数を設定
gcloud run deploy my-service \
  --set-env-vars "NODE_ENV=production,LOG_LEVEL=info" \
  --region asia-northeast1

# 既存サービスの環境変数を更新
gcloud run services update my-service \
  --update-env-vars "LOG_LEVEL=debug" \
  --region asia-northeast1

Secret Managerとの連携

APIキーやパスワードなどの機密情報は、Secret Managerに保存してCloud Runから参照する方法が推奨されます。

# シークレットを作成
echo -n "my-secret-value" | gcloud secrets create db-password --data-file=-

# Cloud Runサービスにシークレットをマウント
gcloud run deploy my-service \
  --set-secrets "DB_PASSWORD=db-password:latest" \
  --region asia-northeast1

この方法なら、シークレットのローテーションもサービスの再デプロイなしで実行可能です。IAMとセキュリティ設計の記事で、アクセス制御の詳細を確認できます。

オートスケーリングとパフォーマンス最適化

Cloud Runの強力な特徴であるオートスケーリングを効果的に活用するための設定と最適化手法を解説します。

スケーリング設定の基本

# 最小・最大インスタンス数の設定
gcloud run deploy my-service \
  --min-instances 1 \
  --max-instances 100 \
  --concurrency 80 \
  --cpu 1 \
  --memory 512Mi \
  --region asia-northeast1

各パラメータの意味と推奨値は以下の通りです。

--min-instances(最小インスタンス数)
0に設定するとコールドスタートが発生しますが、コストは最小になります。レイテンシが重要なサービスでは1以上を設定してウォームインスタンスを維持しましょう。

--max-instances(最大インスタンス数)
予期しないトラフィック急増時に、コストが想定外に膨らむのを防ぐ安全弁として設定します。

--concurrency(同時リクエスト数)
1インスタンスあたりが同時に処理するリクエスト数です。デフォルトは80です。CPUを多く消費する処理の場合は値を下げ、I/O待ちが多い処理では上げると効率的です。

コールドスタートの最小化

コールドスタート(新しいインスタンスの起動時間)はユーザー体験に直結します。以下の対策が有効です。

  • コンテナイメージの軽量化:マルチステージビルドを使い、不要なファイルを除外します
  • 最小インスタンスの設定--min-instances 1で常にウォームなインスタンスを維持します
  • 起動時の初期化処理を最小化:重い処理はリクエスト時まで遅延させます(Lazy Initialization)
  • CPU Boostの有効化:起動時にCPUをブーストし、初期化を高速化できます
# CPU Boostを有効化
gcloud run deploy my-service \
  --cpu-boost \
  --region asia-northeast1

CI/CDパイプラインとの連携

本番運用では、コードの変更を自動的にテスト・デプロイする仕組みが不可欠です。Cloud RunはCloud Buildとの組み合わせで、強力なCI/CDパイプラインを構築できます。

Cloud Buildを使った自動デプロイ

リポジトリにコードをプッシュすると自動デプロイされるパイプラインを構築しましょう。

# cloudbuild.yaml
steps:
  # テストの実行
  - name: 'node:20'
    entrypoint: 'npm'
    args: ['test']

  # コンテナイメージのビルド
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA', '.']

  # Artifact Registryへプッシュ
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA']

  # Cloud Runへデプロイ
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: 'gcloud'
    args:
      - 'run'
      - 'deploy'
      - 'my-service'
      - '--image=gcr.io/$PROJECT_ID/my-service:$COMMIT_SHA'
      - '--region=asia-northeast1'
      - '--platform=managed'

IaCでインフラ全体を管理したい場合は、TerraformによるIaC入門もぜひご覧ください。

トラフィック分割によるカナリアデプロイ

Cloud Runでは、新旧リビジョンにトラフィックを分割する機能を使ってカナリアデプロイを実現できます。

# 新しいリビジョンをデプロイ(トラフィックを流さない)
gcloud run deploy my-service \
  --image gcr.io/PROJECT_ID/my-service:v2 \
  --no-traffic \
  --region asia-northeast1

# 新リビジョンに10%のトラフィックを流す
gcloud run services update-traffic my-service \
  --to-revisions my-service-v2=10 \
  --region asia-northeast1

# 問題なければ100%に切り替え
gcloud run services update-traffic my-service \
  --to-latest \
  --region asia-northeast1

段階的にトラフィックを移行することで、万が一の障害時も影響範囲を限定できます。

Cloud Runと他GCPサービスの連携パターン

Cloud Runは単体でも強力ですが、他のGCPサービスと組み合わせることで、より実用的なシステムを構築できます。

Cloud SQLとの接続

Cloud RunからCloud SQLに接続する場合、Cloud SQL Auth Proxyを使ったセキュアな接続が推奨されます。

# Cloud SQL接続を設定してデプロイ
gcloud run deploy my-service \
  --add-cloudsql-instances PROJECT_ID:asia-northeast1:my-db \
  --set-env-vars "DB_HOST=/cloudsql/PROJECT_ID:asia-northeast1:my-db" \
  --region asia-northeast1

この設定により、Cloud RunインスタンスからCloud SQLインスタンスへの接続がUnixドメインソケット経由で確立されます。

Cloud Storageとの連携

Cloud Storageと連携することで、ファイルのアップロード処理やレポート生成などを効率的に実装できます。

const { Storage } = require('@google-cloud/storage');
const storage = new Storage();

async function uploadFile(bucketName, filePath, destFileName) {
  await storage.bucket(bucketName).upload(filePath, {
    destination: destFileName,
  });
  console.log(`${filePath} uploaded to ${bucketName}/${destFileName}`);
}

Pub/Subによる非同期処理

Cloud RunをPub/Subのサブスクライバーとして設定し、非同期にメッセージを処理するパターンも広く使われています。

# Pub/SubトピックのPushサブスクリプションでCloud Runをトリガー
gcloud pubsub subscriptions create my-sub \
  --topic my-topic \
  --push-endpoint https://my-service-xxxxx-an.a.run.app/pubsub \
  --push-auth-service-account my-invoker@PROJECT_ID.iam.gserviceaccount.com

Cloud Run運用のベストプラクティスとトラブルシューティング

最後に、Cloud Runを本番運用する際のベストプラクティスと、よくあるトラブルの対処法をまとめます。

運用のベストプラクティス

1. ヘルスチェックの実装
Cloud Runはスタートアッププローブとライブネスプローブをサポートしています。アプリケーションの起動完了を確認するエンドポイントを実装しましょう。

app.get('/health', (req, res) => {
  // DBへの接続確認など
  res.status(200).send('OK');
});

2. 構造化ログの出力
JSON形式でログを出力すると、Cloud Loggingで自動的に構造化されて検索性が向上します。

console.log(JSON.stringify({
  severity: 'INFO',
  message: 'Request processed',
  requestId: req.headers['x-cloud-trace-context'],
  duration: elapsed
}));

3. グレースフルシャットダウンの実装
Cloud RunはSIGTERMシグナルでインスタンスを停止します。処理中のリクエストを安全に完了させるため、シグナルハンドラを実装しましょう。

process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  server.close(() => {
    process.exit(0);
  });
});

よくあるトラブルと対処法

デプロイが失敗する場合

  • DockerfileのCMDでPORT環境変数を正しく参照しているか確認します
  • コンテナイメージがx86_64アーキテクチャでビルドされているか確認します(M1/M2 Macユーザーは要注意)
  • ヘルスチェックのタイムアウト内にサービスが起動しているか確認します

レスポンスが遅い場合

  • --min-instances 1を設定してコールドスタートを回避します
  • --cpu-boostを有効にして起動時のCPU割り当てを増やします
  • コンテナイメージのサイズを確認し、不要なレイヤーを削除します

メモリ不足エラーが発生する場合

  • --memoryパラメータを増やします(最大32GiB)
  • メモリリークがないかプロファイリングを行います
  • 同時リクエスト数(--concurrency)を下げてインスタンスあたりの負荷を軽減します

まとめ:Cloud Runで実現するモダンなアプリケーション運用

Cloud Runは、コンテナの柔軟性とサーバーレスの手軽さを両立する、実務に最適なサービスです。本記事で紹介した内容を振り返ります。

  • 基本概念:コンテナをサーバーレスで実行するマネージドサービス
  • 料金:従量課金制で、無料枠内なら月額0円での運用も可能
  • デプロイ:gcloudコマンド一つでソースコードからサービスを公開
  • セキュリティ:Secret ManagerとIAMで機密情報を安全に管理
  • スケーリング:トラフィックに応じた自動スケーリングとパフォーマンス最適化
  • CI/CD:Cloud Buildとの連携でカナリアデプロイを実現
  • 連携Cloud SQLCloud Storageとの統合パターン

まずは無料枠を活用して、小さなWebアプリケーションをCloud Runにデプロイしてみましょう。コンテナベースの開発に慣れることで、将来的なマイクロサービス化やマルチクラウド対応への道も開けます。

#GCP#Cloud Run#サーバーレス
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

AI活用のヒントをお探しですか?お気軽にご相談ください。

まずは話だけ聞いてもらう