G-gen の佐々木です。当記事では Google Cloud (旧称 GCP) のサーバーレスなコンテナサービスである Cloud Run の タグ付きリビジョン(tagged revision)機能を解説します。
Cloud Run とは
Cloud Run は、Google Cloud のサーバーレスな基盤でコンテナアプリケーションを実行できるサービスです。Cloud Run の中でも HTTP リクエストをトリガーとするものは Cloud Run services といい、コンテナとサーバーレスの利点を活かしたスケーラビリティの高い Web アプリケーション実行基盤として非常に有用なサービスとなっています。
Cloud Run services の詳細については以下の記事をご一読ください。
タグ付きリビジョンとは
Cloud Run service でデプロイしたコンテナアプリケーションは、リビジョン という単位でバージョン管理されます。Cloud Run ではリビジョンに対するトラフィック分割機能により、新旧のリビジョンに対して一定割合でトラフィックをロードバランスし、新しいリビジョンを段階的にロールアウトすることができます。
デプロイしたリビジョンに対しては、タグを付与することができます。タグ付きリビジョンには タグを含む URL が発行され、トラフィックを新しいリビジョンにルーティングすることなくアクセスすることができるようになります。 これにより、Cloud Run 環境で新しいリビジョンのテストを行い、テストが終わったらそのままトラフィックをルーティングすることができます。
# Cloud Run サービスの通常の URL 例 https://servicename-xxxxxxxxxx-an.a.run.app # タグ付きリビジョンの URL 例(リビジョンに dev タグを付与した場合) https://dev---servicename-xxxxxxxxxx-an.a.run.app
参考:テスト、トラフィックの移行、ロールバックにタグを使用する
タグ付きリビジョンを使用する
Cloud Run サービスのデプロイ
使用するコード(Go)
当記事では、公式ドキュメントの クイックスタート のコードをベースにし、Cloud Run サービスをデプロイします。
package main import ( "fmt" "log" "net/http" "os" ) func main() { log.Print("starting server...") http.HandleFunc("/", handler) // Determine port for HTTP service. port := os.Getenv("PORT") if port == "" { port = "8080" log.Printf("defaulting to port %s", port) } // Start HTTP server. log.Printf("listening on port %s", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatal(err) } } func handler(w http.ResponseWriter, r *http.Request) { s := "Hello, World!" fmt.Fprintf(w, "%s\n", s) // ブラウザに文字列を表示する }
コンテナイメージのビルド
Cloud Run にデプロイするため、コンテナイメージをビルドして Artifact Registry にプッシュします。ここでは Dockerfile を使用せず、Buildpack を使用してコンテナイメージをビルドします。
イメージの新旧バージョンを分かりやすくするため、コンテナイメージには v1.0
タグを付与します。
# Buildpack を使用してイメージをビルドする $ gcloud builds submit --pack image={リポジトリの URL}/{コンテナイメージ名}:v1.0 # 実行例(リポジトリに Artifact Registry を使用) $ gcloud builds submit --pack image=asia-northeast1-docker.pkg.dev/myproject/myrepo/sample-service:v1.0
サービスのデプロイ
以下のコマンドを使用して Cloud Run サービスの最初のリビジョンをデプロイします。
# Cloud Run サービスのデプロイ $ gcloud run deploy {サービス名} \ --image {コンテナイメージのURL} \ --region {リージョン} \ --allow-unauthenticated # 実行例(v1.0のコンテナイメージを指定) $ gcloud run deploy sample-service \ --image asia-northeast1-docker.pkg.dev/myproject/myrepo/sample-service:v1.0 \ --region asia-northeast1 \ --allow-unauthenticated
サービスへのアクセス
サービスのデプロイ後に URL が出力されるので、ブラウザからサービスの URL にアクセスします。
# デプロイ後の出力抜粋 Service [sample-service] revision [sample-service-00001-xuh] has been deployed and is serving 100 percent of traffic. Service URL: https://sample-service-ai4qoprwhq-an.a.run.app
最初のリビジョンでは、ブラウザ上に「Hello, World!」の文字列が表示されます。
タグ付きリビジョンのデプロイ
使用するコード(Go)
最初のリビジョンと区別するため、新しいリビジョンではブラウザに表示する文字列を変更します。
当記事では、新しいリビジョンにアクセスすると「Hello, G-gen!」の文字列が表示されるようにします。
package main import ( "fmt" "log" "net/http" "os" ) func main() { log.Print("starting server...") http.HandleFunc("/", handler) // Determine port for HTTP service. port := os.Getenv("PORT") if port == "" { port = "8080" log.Printf("defaulting to port %s", port) } // Start HTTP server. log.Printf("listening on port %s", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatal(err) } } func handler(w http.ResponseWriter, r *http.Request) { s := "Hello, G-gen!" // ここを修正する fmt.Fprintf(w, "%s\n", s) }
新しいコンテナイメージのビルド
最初のリビジョン同様に、コンテナイメージをビルドして Artifact Registry にプッシュします。
新しいイメージには v2.0
タグを付与します。
# Buildpack を使用してイメージをビルドする $ gcloud builds submit --pack image={リポジトリの URL}/{コンテナイメージ名}:v2.0 # 実行例(リポジトリに Artifact Registry を使用) $ gcloud builds submit --pack image=asia-northeast1-docker.pkg.dev/myproject/myrepo/sample-service:v2.0
タグ付きリビジョンのデプロイ
gcloud run deploy
コマンドで --tag
オプションを使用することで、タグ付きリビジョンをデプロイすることができます。ここで --no-traffic
オプションを指定することで、新しいリビジョンにトラフィックがルーティングされないようにします。
既存のサービスに対して新しいリビジョンをデプロイするため、サービス名
には最初に作成したサービスと同じ名前を使用します。
# タグ付きリビジョンをデプロイする $ gcloud run deploy {サービス名} \ --image {コンテナイメージのURL} \ --region {リージョン} \ --no-traffic \ --tag {タグ名} # 実行例(v2.0のコンテナイメージを指定し、「dev」タグを付与) $ gcloud run deploy sample-service \ --image asia-northeast1-docker.pkg.dev/myproject/myrepo/sample-service:v2.0 \ --region asia-northeast1 \ --no-traffic \ --tag dev
タグ付きリビジョンへのアクセス
タグ付きのリビジョンをデプロイするとタグが含まれる URL が発行されるので、ブラウザで URL にアクセスします。
タグ付きリビジョンの URL には、サービスの本来の URL に dev---
のような形式でタグが付与されています。
# タグ付きリビジョンのデプロイ後の出力抜粋 Service [sample-service] revision [sample-service-00002-caw] has been deployed and is serving 0 percent of traffic. The revision can be reached directly at https://dev---sample-service-ai4qoprwhq-an.a.run.app
コンソールからタグをクリックすることでもアクセスすることが可能です。
「Hello, G-gen!」が表示されているため、トラフィックがルーティングされていない新しいリビジョンにアクセスできていることがわかります。
タグがついていないサービスの URL にアクセスすると、現在トラフィックがルーティングされている最初のリビジョンにアクセスできるため、新しいリビジョンがまだ公開されていないことがわかります。
トラフィックの移行
タグ付きリビジョンへのトラフィック移行
タグ付きリビジョンのテストが終わったら、最初のリビジョンからトラフィックを移行します。
gcloud run services update-traffic
コマンドの --to-tags
オプションでタグ名を指定し、トラフィックを何パーセント割り当てるかを指定します。
# タグ付きリビジョンにトラフィックをルーティングする $ gcloud run services update-traffic {サービス名} \ --region {リージョン} \ --to-tags {タグ名}={ルーティングするトラフィックの割合} # 実行例(dev タグが付与されたリビジョンにトラフィックを 100% ルーティングする) $ gcloud run services update-traffic sample-service \ --region asia-northeast1 \ --to-tags dev=100
サービスの URL にアクセスすると、新しいリビジョンにアクセスできるようになっています。
タグの削除
タグが不要になったら --remove-tag
オプションでタグを指定し、サービスを更新します。
# リビジョンからタグを削除する $ gcloud run services update-traffic {サービス名} \ --region {リージョン} \ --remove-tags {タグ名} # 実行例(dev タグを削除) $ gcloud run services update-traffic sample-service \ --region asia-northeast1 \ --remove-tags dev
佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2025 Fellowに選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805