Google Cloud ロードバランサの構成をすっきりさせる「URL マスク」機能の紹介
はじめに
こんにちは、クラウドエースの牧川です。
この記事では、Google Cloud ロードバランサの「URL マスク」機能を使って、サーバレス アプリケーションの構成をシンプルに設定する方法を紹介します。
特に最近出た新しい機能という訳ではないのですが、社内であまり知名度が高くない機能のようだったので記事にしてみました。
なお、この記事ではグローバル外部アプリケーション ロードバランサを前提に記載しています。
他のロードバランサについてはそれぞれ読み替えて解釈してください。
Google Cloud のロードバランサの概要
まず、Google Cloud で提供されるグローバル外部アプリケーション ロードバランサのコンポーネントについて簡単に確認しておきます。
Google Cloud では、下図にあるようにいくつかのリソースが組み合わさってロードバランサを構成しています。
グローバル外部アプリケーション ロードバランサのコンポーネント
構成するコンポーネントは上記が基本となり、これに加えてグローバル IP アドレスや Cloud Armor のセキュリティポリシーなどを併用して構成することが多いと思います。
さらに、ロードバランサのバックエンドに位置するアプリケーションとして Cloud Run や Cloud Functions といったサーバレス サービスを採用する場合、ロードバランサと繋ぐ役割として Network Endpoint Group(以下、NEG)の1つである Serverless NEG というリソースを作成する必要があります。
今回ご紹介する「URL マスク」機能は、この Serverless NEG が持つ機能になります。
Serverless NEG とは
Serverless NEG は、その名の通りいくつかある NEG のうちの 1 つで、Cloud Run や Cloud Functions などのサーバレス サービスをロードバランサのバックエンド エンドポイントに指定するために利用するリソースです。
NEG には他に外部サービスをバックエンドにとる Internet NEG や、オンプレミス環境や他クラウドなどをバックエンドにとる Hybrid connectivity NEG などがあります。
「URL マスク」機能の紹介
ここからは「URL マスク」機能の使い方や注意点について紹介します。
機能の概要
「URL マスク」機能は Serverless NEG にある機能の 1 つで、プロジェクトに存在するサーバレス サービスの中から、リクエストを送信するサービスを動的に選択してくれる機能です。
Serverless NEG をこの機能を使わずに利用する場合、1 つのサーバレス サービスに対して 1 つの Serverless NEG を作成し、1 対 1 対応で宛先を指定する必要があります。
一方、「URL マスク」機能を利用した場合、ユーザーからのリクエストをもとに、Serverless NEG が動的に適切なサーバレス サービスを宛先として選択してくれます。
1 つの Serverless NEG をロードバランサに接続するだけで複数の Cloud Run などにリクエストを送信できるようになるため、よりシンプルな構成を取ることができます。
ただし、Cloud Run や Cloud Functions を併用している場合は、それぞれに対応する Serverless NEG を作成する必要がある点には注意が必要です。
利用有無による構成の比較
URL マスクを使用する場合としない場合で構成を比較することで、この機能のメリットを直感的に理解することができると思います。
URL マスクを利用しない構成
バックエンド(以降 Cloud Run / Cloud Functions などのサーバレス サービスを指します)が複数ある場合、その数だけ Backend Service と Serverless NEG を作成する必要があり、URL Map でもそれぞれのパスを設定する必要があります。
この場合の具体的な構成のイメージは以下のようになります。
URL マスクを使用しない構成
URL マスクを利用する構成
一方で、URL マスクを利用することで同一タイプのバックエンドを 1 つの Serverless NEG からルーティングすることができるようになります。
ロードバランサとしては、同じく 1 つの Serverless NEG ごとに、対応する Backend Service を URL Map で指定する設定だけで済みます。
以下の構成イメージを先のものと比較していただくと、必要なリソース数が単純に減り、構成がシンプルになっていることが伝わると思います。
URL マスクを使用する構成
設定方法
通常 Serverless NEG では対象となるサービスを個別に指定するのですが、「URL マスク」を利用する場合は、適切なサービスを動的に選択するためにプレースホルダを用いた設定を行います。
より具体的には、サービスの URL(=ユーザーがリクエストする URL)から、バックエンドのサービス名にあたる部分を URL マスクのプレースホルダに置き換えることで、適切なバックエンドを選択できるようにします。
具体的なプレースホルダの使い方は公式ドキュメントのサンプルを見ていただくのが一番理解しやすいと思います。
下の表は、Cloud Function に対して URL マスクを適用する例です。
サービスの URL からサービス名を含む部分を <functions>
というプレースホルダに置き換えるだけで、自動的に login
という文字列から同名の Functions にリクエストを送信してくれます。
ホストやサブドメイン、最後のプレースホルダより後のパス部分の、読み取る上で必要ない所は記載を省ける点も嬉しいポイントです。
引用: URL マスクを使用する(Cloud Functions)
同じく下の表は、同様に Cloud Run に対して URL マスクを適用する例です。
Cloud Run ではサービス名を表すために <service>
というプレースホルダを利用できるのですが、それに加えて <tag>
というプレースホルダを利用することで、Cloud Run のサービスとタグを柔軟に指定することができます。
実際の設定例
最後に簡単にですが、実際に私が担当したシステムの設定を紹介します(都合によりリソース名は隠しています)。
API のシンプルなパスから Cloud Run のサービス名を抽出することで、1 つの Serverless NEG から 10 以上のサービスにリクエストを振り分けています。
設定自体は非常にシンプルですが、この機能のおかげでリソース数を減らして構成をすっきりさせることができました。
URL マスク: /api/v1.0/<service>
実際のシステムにおける設定例
メリットと注意点
自分が考える「URL マスク」機能を利用するメリットと注意点は以下の通りです。
メリット 1: 構成がシンプルになる
最大のメリットは、なんと言っても構成がシンプルになる点です。
先ほど構成比較を見て頂きましたが、システムの規模によっては作成するリソース数を大きく減らせる可能性があります。
リソース数が少なければ、それだけシステム自体の管理コストや認知負荷を減らすことにつながります。
メリット 2: 機能の追加が簡単にできる
もう 1 つのメリットは、機能追加が簡単にできる点です。
新しいバックエンドの機能を追加したい場合にも、適切な設定をしていれば Cloud Run や Cloud Functions を作成するだけで自動的にリクエストが流れるようになるため、ロードバランサに対して設定変更が不要になります。
すでに稼働中の環境に手を入れるのは場合によっては大きなコストがかかりますが、変更を伴わない単純なリソース追加で構成を変更できる点は大きな強みと言えます。
注意点 1: バックエンドの命名に制約が生まれる
まずは、先ほどの設定方法でも述べた通り、ユーザーからのリクエスト URL から対象となるサービスを自動的に選択する必要があるため、バックエンドのサービス名称をきちんと設計しておく必要があります。
サービスの名前に何かしらのプレフィックスをつけて作成・管理し、ユーザーからのリクエストに含めたくない文字列が含まれてしまっている場合など、そのままでは適切にサービスを選択する事が出来ない状況が考えられます。
注意点 2: 予期せぬリクエストがサービスに流れる恐れがある
前項と関連して、プロジェクト内に存在する全てのサーバレス サービスが抽出の対象になる点にも注意が必要です。
うっかり無関係のサービスの名前がプレースホルダと合致してしまい、意図せぬリクエストが流れてしまう、といったこともケアしてあげる必要があります。
本記事の執筆時点では、リクエストを流したいサービス群をあらかじめ指定しておくような機能は提供されていないため、同じプロジェクトに別の用途のサービスが含まれている場合など特に注意が必要です。
終わりに
本記事では、ロードバランサの構成をシンプルにすることができる「URL マスク」機能をご紹介しました。
特に目新しい機能という訳ではないのですが、ご存知ない方もいらっしゃったのではないでしょうか?
「URL マスク」を使うと、バックエンドのサービスが沢山あるようなシステムでも細かくパスを切って設定することなく、少ないリソース数でシンプルな構成にすることができます。
うまく使えるとリソースの数を大きく減らせますし、なんとなくお洒落な構成が取れてやったった感も出せる(個人の感想です)ので、機会があれば是非導入を検討してみてください。
Discussion