本連載は、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ではシングルページアプリケーション
イベントドリブンアーキテクチャ(EDA)
イベントドリブンアーキテクチャ
イベントは特定のアプリケーションやサービスから発行され、イベントドリブンアーキテクチャを構成することによってサービスとサービスを繋ぎ合わせ、一連のユースケースに対応するアーキテクチャが実現できます。
例えばストレージサービスであるCloud StorageにCSVファイルがアップロードされたときにCloud Runサービスを呼び出し、任意のデータ加工を処理したあとにBigQueryにインポートするといった構成もイベントドリブンアーキテクチャと言えます。
Cloud Runとは
Cloud RunはGoogle Cloudで提供している、サーバーレスでコンテナの実行環境を構築できるサービスです。コンテナイメージとしてビルドできるアプリケーションであれば任意のプログラミング言語で記述されたコードをデプロイできます。
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つのアプリケーションを構築したい場合、まずは
「サービス」 を作成します。サービスはGoogle Cloudプロジェクト内に複数作ることができ、1アプリケーションにつき1サービスを準備します。 - リビジョン
- サービス内には
「リビジョン」 を作成できます。リビジョンはコンテナイメージごとに1つ用意します。リビジョンにはコンテナイメージ以外にも、実行する際に必要となるさまざまな設定情報 (環境変数やサービスアカウントなど) も含まれます。 - コンテナインスタンス
- コンテナインスタンスはCloud Runサービスで実行するコンテナアプリケーションの実体そのものです。コンテナインスタンスはサービスでコンテナインスタンスが必要になったタイミングで、作成済みのリビジョンの設定情報をもとにデプロイされます。
リクエストベースの課金とAlways on CPU
Cloud Runサービスは2種類の課金オプションがあります。多くの場合はリクエストベースの課金が適していますが、特定のユースケースではAlways on CPUのほうが適している場合があります。それぞれの特徴を理解し、どちらが適しているか選択できるようにしましょう。
またいずれのオプションにおいても毎月適用される無料枠があります。小規模な利用であればかなり低いランニングコストで運用できる場合もあります。
リクエストベースの課金
リクエストベースの課金は、デフォルトの設定です。
Cloud Runサービスはリクエストを処理する必要がある際に、コンテナインスタンスをプロビジョニングします。コンテナインスタンスにはCloud Runサービスに設定されているCPUとメモリの上限までの数を割り当てますが、リクエストを受けてからレスポンスを返すまでの間に割り当てているCPUとメモリの数が秒単位で課金されます。
なお、起動してからリクエストを受け付けるまでの間の時間は課金されません。
リクエストベースの課金はCPUとメモリの割り当て時間ベースの課金に加え、リクエスト数による課金があります。
Always on CPU
Always on CPUはCPUとメモリ常に割り当てることができるオプションです。
リクエストベースの場合、コンテナインスタンスはリクエストを受け付けるときに起動し、レスポンスを返したら数分後に終了します。そのため、レスポンスを返したあとに長時間にわたるバックグラウンドタスクを処理したいようなユースケースには適していません。
Always on CPUでは、コンテナインスタンスが起動してからプロセスが完了するまでの間、稼働させることができます。そのため、レスポンスを返したあとにコンテナインスタンスが自動的に削除されることはありません。
また、最小インスタンスを1以上に設定することでコールドスタートを発生させないようにできるほか、リクエスト処理に依らない非同期処理
Always on CPUの場合はリクエストベースの課金とは異なり、リクエストを処理している時間ではなく、CPUとメモリの数と割り当てている秒数で課金されます。その代わり、リクエスト数による課金はありません。
Cloud Runサービスの便利な機能
Cloud Runサービスにはさまざまな便利な機能があります。これらの機能を使うと、Cloud Runのパフォーマンスをコスト効率的に活用できます。使う機会の多い代表的な機能を理解しましょう。
オートスケーリング
Cloud Runサービスではリクエスト数に応じて、特に明示的な設定を行なっていなくても自動でスケーリングを行います。リクエストが増加した際には自動でスケールアウトし、リクエストが減少した際には自動でスケールインします。
コンカレンシー
コンカレンシーは、1つのコンテナインスタンスが同時に処理できるリクエスト数を指します。Cloud Runは一般的なFaaS
最小インスタンス数と最大インスタンス数
Cloud Runサービスではコンテナインスタンスが常時稼働する最小数、またはスケールした際の最大数を設定できます。
デフォルトの設定では最小インスタンス数は0に設定されているため、リクエストがない時間帯はコンテナインスタンスは0になりコストがかかりません。一方でリクエストが発生したタイミングでコンテナインスタンスが1つ新規にプロビジョニングされるため、コールドスタートが発生します。
Cloud Runサービスではコンテナインスタンスのプロビジョニングは高速に行われるため、コンテナイメージで使用されているプログラミング言語やフレームワークによってはコールドスタートを気にする必要がない場合も多いです。その上で、コールドスタートが気になる場合やリクエストが常時あるようなサービスでは、最小インスタンスを1以上に設定する方法が有効的です。
最大インスタンス数は、同時に実行されるコンテナインスタンスの数を指します。Cloud Runサービスはリクエスト数によって自動でスケールしますが、
CPUブースト
CPUブーストを使うと、コンテナインスタンスが新たにプロビジョニングされる際、起動が完了するまでの間のみCPUを増やすことができます。起動するときだけCPUを多く必要とするフレームワークなどを使用している場合などに有効です。
Cloud Runジョブ
Cloud Runジョブは非同期処理をCloud Runのインフラストラクチャで実行するためのサービスです。
Cloud Runジョブのリソースモデル
Cloud Runサービスの構成要素として、どのようなリソースがあるか理解しましょう。
- ジョブ
- ジョブはCloud Runジョブのルートリソースです。Google Cloudプロジェクト内に複数作成でき、実行したいジョブごとにそれぞれ作成します。ジョブには実行したいコンテナイメージやタスク数、並行稼働数などのほか、CPUやメモリのサイズ、環境変数なども設定します。
- タスク
- タスクはジョブで実行する処理そのものです。ジョブで指定したタスクの数だけ実行され、1つのタスクにつき1つのコンテナインスタンスが起動し、処理を実行します。
- エグゼキューション
- エグゼキューションはジョブの実行を表し、ジョブを1回実行すると1つのエグゼキューションが作成されます。エグゼキューションはタスク全体を管理します。エグゼキューションの実行中はタスクがいくつ終わっているか進捗ステータスを提供し、すべてのタスクが完了すると完了のステータスになります。
Cloud Runジョブの便利な機能
Cloud Runジョブではさまざまな機能を提供しており、それらの機能を活用することでさまざまな非同期処理のユースケースに対応できます。代表的な機能を確認しましょう。
タスク数と並列数
ジョブには実行するタスク数と同時に実行する並列数を設定できます。これらを組み合わせて使うことで、ジョブの処理を直列に実行させたり、同時に実行される数を制御したりといったカスタマイズが可能です。
例えばタスク数を3、並列数を3とした場合、タスクは3つ同時に実行されます。一方で直列にしたい場合は並列数を1にすることで、タスクが1つずつ実行されるように挙動を変えることができます。
各タスクで参照可能な環境変数
Cloud Runジョブではタスクとして実行されるコンテナインスタンス内から参照可能な環境変数を付与します。
ジョブにはコンテナイメージを1つだけ設定可能なため、そのままでは複数のタスクを実行しても全く同じ処理を行うコンテナインスタンスが複数実行されてしまいます。そこでCloud Runジョブでは、各タスクの実行時にCLOUD_
という環境変数をコンテナインスタンスに設定します。この環境変数はタスクごとにユニークになるため、CLOUD_
の値ごとに処理を分岐させることができます。
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/
代表的なGitリポジトリのホスティングサービスをサポートしており、GitHubやGitLab、BitbucketといったサービスでホスティングされているGitリポジトリのイベントをフックした実行が簡単に設定できます。
Cloud RunにはCloud Buildと統合する機能があり、この機能を使うとGitリポジトリを指定するだけでCloud Buildを使ったビルド・
Cloud Deploy
Cloud Deployはデプロイパイプラインを管理するためのサービスです。GKEやCloud Runといったコンテナベースの実行環境に対するデプロイをサポートし、複数の環境にわたるリリースのためのデプロイパイプラインを構成できます。
例えば1つのCloud Runサービスにおいて、まずはテスト環境にデプロイして動作確認をして、問題がなければ次にステージング環境にデプロイ、最後に本番環境にデプロイするといったリリースフローをCloud Deployで管理できます。
まとめ
本記事ではGoogle Cloudでのサーバーレス開発について、そしてCloud Runの概要や特徴について紹介しました。
Cloud RunはGoogle Cloudのサービスの中で、コンテナで構成されたアプリケーションを最も簡単に扱うことができるサービスと言えるでしょう。アプリケーション開発者の方でも簡単に使えるようにデザインされているため、まずは試してみて、クラウドでのアプリケーション開発の容易さを体験してみてください。
次回はクラウドネイティブなデータベースとCloud Spannerについて紹介します。