08. Cloud Run / Functions
GCP のサーバーレスは Cloud Run が主役。コンテナをそのまま動かせて 0 にもスケールイン。Cloud Functions(旧称)は v2 で Cloud Run の派生サービスに統合されました。
この章の目次
3 つの選択肢
| Cloud Run service | Cloud Run jobs | Cloud Functions v2 | |
|---|---|---|---|
| 形態 | HTTP コンテナ | バッチコンテナ | 関数(コード or コンテナ) |
| スケール | 0 → 1000 | 並列実行 | 0 → 1000 |
| 料金 | vCPU・メモリ秒 | 実行時間 | 呼び出し従量 |
| 用途 | Web/API | 定期バッチ・ETL | イベント駆動 |
| AWS 対応 | Lambda + Fargate | Batch + ECS Task | Lambda |
Cloud Run service
resource "google_cloud_run_v2_service" "api" {
name = "myapp-api"
location = "asia-northeast1"
ingress = "INGRESS_TRAFFIC_ALL" # or INTERNAL / INTERNAL_AND_CLOUD_LOAD_BALANCING
template {
service_account = google_service_account.app.email
scaling {
min_instance_count = 0
max_instance_count = 100
}
containers {
image = "${google_artifact_registry_repository.main.location}-docker.pkg.dev/${google_artifact_registry_repository.main.project}/${google_artifact_registry_repository.main.repository_id}/api:v1.2.0"
resources {
limits = {
cpu = "1"
memory = "512Mi"
}
cpu_idle = true # Request 処理中以外は CPU 0(コスト削減)
}
env {
name = "LOG_LEVEL"
value = "info"
}
env {
name = "DB_PASSWORD"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.db_password.secret_id
version = "latest"
}
}
}
ports {
container_port = 8080
}
startup_probe {
http_get {
path = "/health"
}
initial_delay_seconds = 10
timeout_seconds = 5
period_seconds = 10
}
}
# VPC アクセス(Cloud SQL Private IP 等)
vpc_access {
network_interfaces {
network = google_compute_network.main.id
subnetwork = google_compute_subnetwork.private.id
}
egress = "PRIVATE_RANGES_ONLY"
}
}
traffic {
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
percent = 100
}
}
# 全公開(認証なし)。本番は通常付けない
resource "google_cloud_run_v2_service_iam_member" "public" {
location = google_cloud_run_v2_service.api.location
name = google_cloud_run_v2_service.api.name
role = "roles/run.invoker"
member = "allUsers"
}
output "api_url" {
value = google_cloud_run_v2_service.api.uri
}
Cloud Run jobs
HTTP リクエストではなく「実行 → 完了」型のバッチ。AWS の ECS RunTask / Batch 相当。
resource "google_cloud_run_v2_job" "nightly" {
name = "nightly-cleanup"
location = "asia-northeast1"
template {
template {
service_account = google_service_account.app.email
timeout = "600s"
max_retries = 3
containers {
image = "asia-northeast1-docker.pkg.dev/myapp-prd/main/cleanup:latest"
command = ["./cleanup"]
args = ["--mode=full"]
resources {
limits = {
cpu = "2"
memory = "1Gi"
}
}
}
}
}
}
# Cloud Scheduler で毎日 03:00 JST に起動
resource "google_cloud_scheduler_job" "nightly" {
name = "nightly-cleanup"
schedule = "0 18 * * *" # UTC 18:00 = JST 03:00
time_zone = "Etc/UTC"
http_target {
http_method = "POST"
uri = "https://${google_cloud_run_v2_job.nightly.location}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/myapp-prd/jobs/${google_cloud_run_v2_job.nightly.name}:run"
oauth_token {
service_account_email = google_service_account.scheduler.email
}
}
}
Cloud Functions v2
イベントトリガで動く関数。実体は Cloud Run の薄いラッパー。Eventarc 経由で各種 GCP イベントから起動可能。
resource "google_cloudfunctions2_function" "process_upload" {
name = "process-upload"
location = "asia-northeast1"
build_config {
runtime = "nodejs20"
entry_point = "handler"
source {
storage_source {
bucket = google_storage_bucket.source.name
object = google_storage_bucket_object.source.name
}
}
}
service_config {
max_instance_count = 10
available_memory = "256M"
timeout_seconds = 60
service_account_email = google_service_account.app.email
ingress_settings = "ALLOW_INTERNAL_ONLY"
}
event_trigger {
trigger_region = "asia-northeast1"
event_type = "google.cloud.storage.object.v1.finalized"
retry_policy = "RETRY_POLICY_RETRY"
service_account_email = google_service_account.app.email
event_filters {
attribute = "bucket"
value = google_storage_bucket.uploads.name
}
}
}
Artifact Registry
resource "google_artifact_registry_repository" "main" {
location = "asia-northeast1"
repository_id = "main"
format = "DOCKER"
description = "myapp container images"
cleanup_policies {
id = "keep-latest-20"
action = "KEEP"
most_recent_versions {
keep_count = 20
}
}
cleanup_policies {
id = "delete-old-untagged"
action = "DELETE"
condition {
tag_state = "UNTAGGED"
older_than = "604800s" # 7 日
}
}
}
# Cloud Run の SA に pull 権限
resource "google_artifact_registry_repository_iam_member" "app_reader" {
location = google_artifact_registry_repository.main.location
repository = google_artifact_registry_repository.main.name
role = "roles/artifactregistry.reader"
member = "serviceAccount:${google_service_account.app.email}"
}
GKE Autopilot との比較
| シナリオ | 推奨 |
|---|---|
| シンプルな API・Web | Cloud Run |
| 定期バッチ | Cloud Run jobs + Scheduler |
| イベント駆動(Storage / Pub/Sub) | Cloud Functions v2 |
| 複雑なマイクロサービス・StatefulSet | GKE Autopilot |
| 既存 Kubernetes 資産あり | GKE |