Google Cloudで実践! クラウドネイティブな開発

サーバーレス開発の基本と簡単に使い始められるCloud Runの特徴

本連載は、Google Cloudのアプリ開発とDBプロダクトにおけるスペシャリスト達が、Google Cloudプロダクトを利用した、クラウドネイティブな開発を実践する方法を解説しています。

第3回では、サーバーレス開発とGoogle Cloudのサーバーレス製品であるCloud Runに焦点を当てます。

まず、サーバーレス開発の基本概念と利点について説明し、従来のサーバーに依存しないアプリケーション開発手法の重要性を探ります。次に、Cloud Runの概要を紹介し、コンテナイメージの実行をサポートするサーバーレスプラットフォームとしての役割を説明します。この回を通じて、サーバーレス開発の基礎を学び、Cloud Runを利用して効率的なアプリケーション開発を実現する方法を理解できます。

主に対象となる読者は、クラウドを利用してアプリケーションを開発するエンジニア、またはその基盤を構築するエンジニア、サービス開発に携わるプロダクトマネージャーを想定しています。

サーバーレス開発とは

サーバーレスとはクラウドにおけるアプリケーションの実行環境の提供形態の一種です。サーバーレスと言ってもサーバーが実際に存在しないわけではなく、アプリ開発者やインフラエンジニアが「サーバーが稼働している」ということを意識する必要なく利用できる構成を指します。

従来のアプリケーション開発では、アプリケーションの実行環境としてサーバーの構築や管理が必要となるため、多くの手間・コストがかかっていました。サーバーレスでは構築や管理はフルマネージドに提供されるため、これらの負担を大幅に削減できます。

サーバーレス開発は次のような特徴があります。

フルマネージド

サーバーレス開発に使われるサービスはフルマネージドで提供していますので、ユーザーはサーバーのバックアップや冗長性などといった耐障害性への対応、OSのインストールやバージョンアップ、パッチ適用などといった運用作業を行う必要がありません。そのためユーザーはアプリケーション開発に集中できます。実際にはサービスの裏側で動くインフラの管理はGoogleが行なっていますので「インフラ管理をGoogleに任せる」と考えることもできます。

オートスケール

サーバーレスではトラフィック増加やCPU・メモリ負荷に応じたリソースのスケールアウト・スケールインが自動的に行われます。

サービスへのトラフィックが突発的に増加したとしても、ユーザー側での作業を行う必要なく対応できます。またリソースが過剰に確保されることもないため、コスト効率的にスケールさせることができます。

Google Cloudの各サービスはGoogleのサービスと同じインフラストラクチャ上で実行されるため、非常に大規模なスケーラビリティを実現するアプリケーションを構築することも可能です。

従量課金

サーバーレス開発に使われるサービスの利用料は従量課金制のため、コスト効率的に利用できます。

従来のアプリケーション実行環境ではサーバーを常時稼働させる方式を取る場合が多く、アプリケーションがエンドユーザーに利用されていない時間帯も固定費がかかっていました。サーバーレスのアプリケーション実行環境では利用されているときだけリソースがプロビジョニングし、利用されなくなったら自動的にリソースを削除します。そのため従来のアプリケーション実行環境と比較するとランニングコストを大幅に削減できる可能性があります。

簡単に始められる

サーバーレス開発で使われるサービスの多くはアプリ開発者にとって簡単に使えるように機能が設計されています。例えばCloud Runでは、アプリケーションコードさえあればサービスをデプロイできるようになっています。そのためサーバーレス開発ではアジリティのあるアプリケーション開発が可能です。

またサーバーレス開発では少数のエンジニアのみで開発・運用することが可能なため、最初は小規模かつ短期間で始めたい場合も有効な選択肢です。

代表的なサーバーレスアーキテクチャのユースケース

サーバーレスでよく採用されるユースケースについて紹介します。

WebアプリケーションやAPIサーバー

Webアプリケーションは最も代表的なサーバーレスアーキテクチャのユースケースです。例えばコンシューマ向けのWebアプリケーションの場合はトラフィックを予測することが難しい場合が多く、トラフィックに応じてオートスケールするサーバーレスアーキテクチャとの相性が非常に良いです。

Google Cloudではシングルページアプリケーション(SPA)はCloud Storageを使った静的なホスティング、サーバーサイドレンダリング(SSR)はCloud Runサービスを使った動的なホスティングで構成する方法があります。

イベントドリブンアーキテクチャ(EDA)

イベントドリブンアーキテクチャ(EDA)とは、アプリケーションやサービスがイベント(状態の変化)に対応するためのアーキテクチャです。イベントやメッセージを受け取り、それに応じて処理を実行するという形をシステムで実現します。

イベントは特定のアプリケーションやサービスから発行され、イベントドリブンアーキテクチャを構成することによってサービスとサービスを繋ぎ合わせ、一連のユースケースに対応するアーキテクチャが実現できます。

例えばストレージサービスであるCloud StorageにCSVファイルがアップロードされたときにCloud Runサービスを呼び出し、任意のデータ加工を処理したあとにBigQueryにインポートするといった構成もイベントドリブンアーキテクチャと言えます。

Cloud Runとは

Cloud RunはGoogle Cloudで提供している、サーバーレスでコンテナの実行環境を構築できるサービスです。コンテナイメージとしてビルドできるアプリケーションであれば任意のプログラミング言語で記述されたコードをデプロイできます

Cloud Runでは現在Cloud RunサービスCloud Runジョブという2つの提供形態があります。Cloud RunサービスはHTTPSエンドポイントを持つサービスを提供するためのサービスで、主にWebアプリケーションやAPIサーバーなどを構築したいユースケースで使用します。Cloud Runジョブは非同期処理をCloud Runのインフラストラクチャで実行するためのサービスで、バッチ処理を行うアプリケーションを構築したいユースケースで使用します。

Cloud Runのスペック

Cloud Runは仮想マシンのようなマシンタイプはなく、CPUやメモリの上限値のみが設定できます。そのため、スペックの設定を非常に簡単に行うことができます。

Cloud RunではコンテナインスタンスあたりのCPUやメモリに上限値を設定できます。デフォルトはCPUが1に設定されていますが、コンテナインスタンスあたりのパフォーマンスを上げたい場合はCPUやメモリの上限値を上げるように設定します。またCPUの設定値によってメモリの最小要件が異なります(詳しくはドキュメントを確認してください⁠⁠。

第1世代と第2世代の実行環境

Cloud Runには実行環境として、第1世代と第2世代を提供しています。

第1世代はCloud Runのサービス開始時から提供している実行環境で、第2世代はより高パフォーマンス、高機能な実行環境として提供しています。第2世代はCPUパフォーマンスの高速化やネットワークパフォーマンスの高速化、ネットワークファイルシステムのサポートなどを利用できますが、第1世代よりもコールドスタートが長くなるため、より高速にスケールさせたい場合は第1世代のほうが向いている場合があります。

Cloud Runサービスでは第1世代と第2世代のどちらかを設定でき、Cloud Runジョブは第2世代のみをサポートしています。

Cloud Runサービス

Cloud RunサービスはHTTPSエンドポイントを持つサービスを提供するためのサービスです。コンテナイメージを数ミリ秒〜数秒でデプロイでき、高速にスケールさせることができます。またデプロイするだけでHTTPSのエンドポイントが自動的に付与されるため、非常に手軽に使いはじめることができます。

Cloud Runサービスのリソースモデル

Cloud Runサービスの構成要素として、どのようなリソースがあるか理解しましょう。

図1 Cloud Runサービスのリソースモデル
図1
サービス
1つのアプリケーションを構築したい場合、まずは「サービス」を作成します。サービスはGoogle Cloudプロジェクト内に複数作ることができ、1アプリケーションにつき1サービスを準備します。
リビジョン
サービス内には「リビジョン」を作成できます。リビジョンはコンテナイメージごとに1つ用意します。リビジョンにはコンテナイメージ以外にも、実行する際に必要となるさまざまな設定情報(環境変数やサービスアカウントなど)も含まれます。
コンテナインスタンス
コンテナインスタンスはCloud Runサービスで実行するコンテナアプリケーションの実体そのものです。コンテナインスタンスはサービスでコンテナインスタンスが必要になったタイミングで、作成済みのリビジョンの設定情報をもとにデプロイされます。

リクエストベースの課金とAlways on CPU

Cloud Runサービスは2種類の課金オプションがあります。多くの場合はリクエストベースの課金が適していますが、特定のユースケースではAlways on CPUのほうが適している場合があります。それぞれの特徴を理解し、どちらが適しているか選択できるようにしましょう。

またいずれのオプションにおいても毎月適用される無料枠があります。小規模な利用であればかなり低いランニングコストで運用できる場合もあります。

リクエストベースの課金

リクエストベースの課金は、デフォルトの設定です。

Cloud Runサービスはリクエストを処理する必要がある際に、コンテナインスタンスをプロビジョニングします。コンテナインスタンスにはCloud Runサービスに設定されているCPUとメモリの上限までの数を割り当てますが、リクエストを受けてからレスポンスを返すまでの間に割り当てているCPUとメモリの数が秒単位で課金されます。

なお、起動してからリクエストを受け付けるまでの間の時間は課金されません。

リクエストベースの課金はCPUとメモリの割り当て時間ベースの課金に加え、リクエスト数による課金があります。

図2 リクエストベースの課金
図2

Always on CPU

Always on CPUはCPUとメモリ常に割り当てることができるオプションです。

リクエストベースの場合、コンテナインスタンスはリクエストを受け付けるときに起動し、レスポンスを返したら数分後に終了します。そのため、レスポンスを返したあとに長時間にわたるバックグラウンドタスクを処理したいようなユースケースには適していません。

Always on CPUでは、コンテナインスタンスが起動してからプロセスが完了するまでの間、稼働させることができます。そのため、レスポンスを返したあとにコンテナインスタンスが自動的に削除されることはありません。

また、最小インスタンスを1以上に設定することでコールドスタートを発生させないようにできるほか、リクエスト処理に依らない非同期処理(ポーリングなど)を行いたい場合などに適しています。

Always on CPUの場合はリクエストベースの課金とは異なり、リクエストを処理している時間ではなく、CPUとメモリの数と割り当てている秒数で課金されます。その代わり、リクエスト数による課金はありません。

図3 Always on CPU
図3

Cloud Runサービスの便利な機能

Cloud Runサービスにはさまざまな便利な機能があります。これらの機能を使うと、Cloud Runのパフォーマンスをコスト効率的に活用できます。使う機会の多い代表的な機能を理解しましょう。

オートスケーリング

Cloud Runサービスではリクエスト数に応じて、特に明示的な設定を行なっていなくても自動でスケーリングを行います。リクエストが増加した際には自動でスケールアウトし、リクエストが減少した際には自動でスケールインします。

図4 オートスケーリング
図4

コンカレンシー

コンカレンシーは、1つのコンテナインスタンスが同時に処理できるリクエスト数を指します。Cloud Runは一般的なFaaS(Function as a Service)と異なり、1つのコンテナインスタンスが複数のリクエストを同時に処理できます。デフォルトは80で設定されているため、特に指定がなければ1つのコンテナインスタンスが最大80リクエストまで処理できるようになります[1]

図5 コンカレンシー
図5

最小インスタンス数と最大インスタンス数

Cloud Runサービスではコンテナインスタンスが常時稼働する最小数、またはスケールした際の最大数を設定できます。

デフォルトの設定では最小インスタンス数は0に設定されているため、リクエストがない時間帯はコンテナインスタンスは0になりコストがかかりません。一方でリクエストが発生したタイミングでコンテナインスタンスが1つ新規にプロビジョニングされるため、コールドスタートが発生します。

Cloud Runサービスではコンテナインスタンスのプロビジョニングは高速に行われるため、コンテナイメージで使用されているプログラミング言語やフレームワークによってはコールドスタートを気にする必要がない場合も多いです。その上で、コールドスタートが気になる場合やリクエストが常時あるようなサービスでは、最小インスタンスを1以上に設定する方法が有効的です。

最大インスタンス数は、同時に実行されるコンテナインスタンスの数を指します。Cloud Runサービスはリクエスト数によって自動でスケールしますが、⁠これ以上スケールしてほしくない」という場合に最大インスタンス数を指定します。コスト効率的に運用したい場合や、データベースへの負荷をコントロールしたい場合などに有効な手段です。

CPUブースト

CPUブーストを使うと、コンテナインスタンスが新たにプロビジョニングされる際、起動が完了するまでの間のみCPUを増やすことができます。起動するときだけCPUを多く必要とするフレームワークなどを使用している場合などに有効です。

図6 CPUブースト
図6

Cloud Runジョブ

Cloud Runジョブは非同期処理をCloud Runのインフラストラクチャで実行するためのサービスです。

Cloud Runジョブのリソースモデル

Cloud Runサービスの構成要素として、どのようなリソースがあるか理解しましょう。

図7 Cloud Runジョブのリソースモデル
図7
ジョブ
ジョブはCloud Runジョブのルートリソースです。Google Cloudプロジェクト内に複数作成でき、実行したいジョブごとにそれぞれ作成します。ジョブには実行したいコンテナイメージやタスク数、並行稼働数などのほか、CPUやメモリのサイズ、環境変数なども設定します。
タスク
タスクはジョブで実行する処理そのものです。ジョブで指定したタスクの数だけ実行され、1つのタスクにつき1つのコンテナインスタンスが起動し、処理を実行します。
エグゼキューション
エグゼキューションはジョブの実行を表し、ジョブを1回実行すると1つのエグゼキューションが作成されます。エグゼキューションはタスク全体を管理します。エグゼキューションの実行中はタスクがいくつ終わっているか進捗ステータスを提供し、すべてのタスクが完了すると完了のステータスになります。

Cloud Runジョブの便利な機能

Cloud Runジョブではさまざまな機能を提供しており、それらの機能を活用することでさまざまな非同期処理のユースケースに対応できます。代表的な機能を確認しましょう。

タスク数と並列数

ジョブには実行するタスク数と同時に実行する並列数を設定できます。これらを組み合わせて使うことで、ジョブの処理を直列に実行させたり、同時に実行される数を制御したりといったカスタマイズが可能です。

例えばタスク数を3、並列数を3とした場合、タスクは3つ同時に実行されます。一方で直列にしたい場合は並列数を1にすることで、タスクが1つずつ実行されるように挙動を変えることができます。

各タスクで参照可能な環境変数

Cloud Runジョブではタスクとして実行されるコンテナインスタンス内から参照可能な環境変数を付与します。

ジョブにはコンテナイメージを1つだけ設定可能なため、そのままでは複数のタスクを実行しても全く同じ処理を行うコンテナインスタンスが複数実行されてしまいます。そこでCloud Runジョブでは、各タスクの実行時にCLOUD_RUN_TASK_INDEXという環境変数をコンテナインスタンスに設定します。この環境変数はタスクごとにユニークになるため、CLOUD_RUN_TASK_INDEXの値ごとに処理を分岐させることができます。

図8 各タスクで参照可能な環境変数
図8

Cloud Runを便利に使うためのエコシステム

Cloud RunはGoogle Cloudの各サービスと組み合わせることによって、より便利にさまざまなユースケースで活用できます。Cloud Runと組み合わせて使う機会の多いGoogle Cloudサービスについて、どのようなメリットがあるか理解しましょう。

Cloud Load Balancing

Cloud Load Balancingは負荷分散のためのサービスで、トラフィックに対してパフォーマンスとスケーラビリティに優れたロードバランシングを実現します。

Cloud Runサービスだけでも十分な負荷分散は可能ですが、Cloud Load BalancingはCDNサービスであるCloud CDNやWAFサービスであるCloud Armorと統合されているため、簡単な設定だけでCloud RunサービスにCDNによるキャッシュコントロールやWAFの機能を追加できます。

またCloud Load Balancingではパスやヘッダーによってルーティングを切り替えることが設定できるため、複数のCloud Runサービスを同一のエンドポイントでパスによってルーティングを変えたり、特定のパスの向き先のみCloud Storage(静的ファイル)に変えたりといった構成が可能です。

Workflows

Workflowsはステートフルなワークフローをサーバーレスで実行するためのサービスです。一連のサービスの実行やAPIの呼び出しをワークフローとして管理し、オーケストレーションできます。

Workflowsは複数のAPIを呼び出す必要のある非同期処理や、データ処理のパイプラインを1つのワークフローとして実行したい場合などに便利です。ワークフローの中で複数のCloud RunサービスやCloud Runジョブを実行するような構成を取ることもできます。

Eventarc

Eventarcは状態の変更(イベント)を管理するためのサービスで、イベントドリブンアーキテクチャを実現する上で欠かせないサービスです。

Eventarcでサポートされている各サービスのイベントを監視し、特定のイベントが発生した際にCloud Runを呼び出すことができます。これによって他のサービスのイベントをきっかけにCloud Runの処理を実行するといった構成を実現できます。現在ではGoogle Cloudサービスのイベント以外にもサードパーティのサービスのイベントを管理できるようになっています。

Cloud Build

Cloud BuildはサーバーレスのCI/CDサービスです。CI/CDとして実行したいステップをYAMLで定義し、Cloud Runなどのコンピューティングサービスに対するビルド、テスト、デプロイなどをサーバーレスで実行できます。

代表的なGitリポジトリのホスティングサービスをサポートしており、GitHubやGitLab、BitbucketといったサービスでホスティングされているGitリポジトリのイベントをフックした実行が簡単に設定できます。

Cloud RunにはCloud Buildと統合する機能があり、この機能を使うとGitリポジトリを指定するだけでCloud Buildを使ったビルド・デプロイ構成を自動でプロビジョニングできます。まずは統合機能を経由してCloud RunへのCI/CD環境を構成し、徐々にカスタマイズしていく方法がおすすめです。

Cloud Deploy

Cloud Deployはデプロイパイプラインを管理するためのサービスです。GKEやCloud Runといったコンテナベースの実行環境に対するデプロイをサポートし、複数の環境にわたるリリースのためのデプロイパイプラインを構成できます。

例えば1つのCloud Runサービスにおいて、まずはテスト環境にデプロイして動作確認をして、問題がなければ次にステージング環境にデプロイ、最後に本番環境にデプロイするといったリリースフローをCloud Deployで管理できます。

まとめ

本記事ではGoogle Cloudでのサーバーレス開発について、そしてCloud Runの概要や特徴について紹介しました。

Cloud RunはGoogle Cloudのサービスの中で、コンテナで構成されたアプリケーションを最も簡単に扱うことができるサービスと言えるでしょう。アプリケーション開発者の方でも簡単に使えるようにデザインされているため、まずは試してみて、クラウドでのアプリケーション開発の容易さを体験してみてください。

次回はクラウドネイティブなデータベースとCloud Spannerについて紹介します。

おすすめ記事

記事・ニュース一覧