7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Cloud Load Balancingを使ってCloud Functionsに独自ドメインを割り当てる

Last updated at Posted at 2020-08-31

はじめに

GCPの Cloud Functions はちょこっとした処理を記述するのに便利です。ただ提供されるURLは以下のような形式になっていて少し長いです。

https://<region-name>-<project-name>.cloudfunctions.net/<function-name>

そのためURLを公開する場合は独自ドメインを適用してわかりやすいURLを使いたくなります。

またCloud FunctionsのURLは少しクセがあって、以下のような特徴があります。 (2020年8月現在)

  • Server Name Indication(SNI)が必須

    • SNIは同一のIPアドレスで複数のSSL証明書を扱う方法です。詳しくはこちらを参照ください。
    • 組み込み機器など非SNI端末でアクセスすると、返却されるサーバ証明書が*.google.comとなっておりcloudfunctions.netと一致しないためSSL接続でエラー(証明書が無効)になります。
  • バーチャルホストで運用されている風の挙動

    • 直IPアドレス指定やCNAMEで別のドメイン指定してアクセスすると404が返却されるため、独自ドメインでアクセスさせることができない。

そこで今回はCloud Load Balancing を使って独自ドメインでのアクセスを試してみました。GCPのコンソールのぽちぽち操作で独自ドメインを利用したい場合向けの記事となっています。公開するCloud FunctionsがAPIっぽかったり、APIマネジメントの機能がほしかったりする場合はこちらの記事が参考になります。

Cloud Load Balancingを経由することで次のようなメリットがあります。

  • 独自ドメインを割当られる
  • 専用のIPアドレスでアクセスできる
  • 非SNI端末へもサービスを提供できる
  • セルフマネッジド証明書、自己署名証明書(オレオレ証明書)が使える
  • SSL Policyで厳密にCipherSuiteを限定できる

構成

gcp-cloudfunctions.png

ポイントはインターネットネットワークエンドポイントグループ(Internet NEG)を使うところです。
Internet NEGはロードバランサーのバックエンドとして外部サービスを利用できるようにするものです。接続できる外部サービスはFQDNやIPアドレスでアクセスできるインターネット上のHTTP(S)リソースになります。

手順

1. Cloud Functionsを作る

今回はクイックスタートのHello Worldを表示する関数を独自ドメインでアクセスできるようにします。
手順に従い作成しますが「未認証の呼び出しを許可する」にチェックをつけておきます。

以下、手順上は作成した関数名を「function-1」としています。

2. インターネットネットワークエンドポイントグループ(Internet NEG)を作る

GCPのコンソールのメニューから「ComputeEngine」-「ネットワークサービスグループ」を選び、次の設定でネットワークエンドポイントグループを作成します。完全修飾ドメイン名には作成したCloud Functions(function-1)のFQDNを指定してください。

項目 設定値
名前 任意の名前です。ここではfunction-1-negとします
ネットワーク エンドポイント グループの種類 ネットワークエンドポイントグループ(インターネット)
リージョン Global
デフォルトポート 443
新しいネットワーク エンドポイント
追加手段 完全修飾ドメイン名とポート
完全修飾ドメイン名 <region-name>-<project-name>-cloudfunctions.net
ポートタイプ デフォルト

3. Cloud Load Balancing を作る

GCPのコンソールのメニューから「ネットワークサービス」-「負荷分散」を選び、画面上部の「ロードバランサを作成」ボタンで作成を開始します。

項目 設定値
タイプ HTTP(S) 負荷分散
インターネット接続または内部専用 インターネットから自分のVMへ

3-(1) バックエンドの設定

続いてバックエンドの設定をします。

gcp-createbackendservice.png

「バックエンド サービスとバックエンド バケット」の項目で「バックエンドサービス」ー「バックエンドサービスの作成」を選択して、次の設定でバックエンドサービスを作成します。バックエンドには手順2で作成したInternet NEGを指定します。

項目 設定値
名前 任意の名前です。function-1-backend
バックエンドタイプ インターネットネットワークエンドポイントグループ
プロトコル HTTPS
タイムアウト 30秒
バックエンド インターネットエンドポイントグループ:前の手順で作成したインターネットNEGを指定(function-1-neg)

3-(2) ホストとパスのルール

次にホストとパスのルールを設定します。

項目 設定値
モード 単純なホストとパスのルール
デフォルトのルールのバックエンド 直前の手順で作成したバックエンドサービスを選択(function-1-backend)

3-(3) フロントエンドの設定

今回は手順省略のためHTTPで構築してみます。もちろんHTTPSを設定すればHTTPSでアクセスできます。HTTPはデフォルトで作成されているためそのまま。作成ボタンで作成します。

4. 動作確認する

しばらくすると作成したロードバランサの詳細画面にIPアドレスが表示されます。

:point_up: 構成および反映には少し時間がかかります。コンソール上で完了してから3分程度待ちましょう。

ここでは割り当てられたIPアドレスをxxx.xxx.xxx.xxxとします。

ブラウザからhttp://xxx.xxx.xxx.xxx/function-1にアクセスします。

やったね。「Hello World」って表示され…ない。

404.png

404が返ってきます…。 :cry:

修正する

さて原因についてですが、文頭のCloud FunctionsのURLの特徴で記載したように、IPアドレスやCNAME等で別名をつけてアクセスできません。

言い換えるとHTTPリクエストのHostヘッダーが<region-name>-<project-name>-cloudfunctions.netになっていないとアクセスできないことになります。

ドキュメントの制限事項の部分に以下の記載があります(これに気づかず数時間彷徨いましたが…)

HTTP リクエストの Host ヘッダーに特定の値を必要とするカスタムの送信元を使用する場合、バックエンド サービスを構成して Host ヘッダーをその値に設定する必要があります。ユーザー定義のリクエスト ヘッダーを構成しない場合、バックエンド サービスはクライアントが Google Cloud 外部 HTTP(S) ロードバランサへの接続に使用した Host ヘッダーを保持します。

これによるとさきほどはHostヘッダーにHost: xxx.xxx.xxx.xxxが設定されてCloud Functionsに送信しているためアクセスできなかったと推察できます。

:point_up: 実際にこの挙動を確認したい場合はInternet NEGのネットワークエンドポイントの指定を webhook.site 等に差し替えてHostヘッダーを確認してみてください。

Hostヘッダーを書き換える設定は作成したロードバランサーの「ホストとパスのルール」のところで「モード」を「詳細なホストとパスのルール(URLリダイレクト、URLの書き換え)」に変更します。

mode.png

さらに、デフォルトのルールを選択してホスト名の書き換えを設定します。

項目 設定値
アクション トラフィックを1つのバックエンドにルーティング
ホストの書き換え 自身のCloud Functionsのホスト名<region-name>-<project-name>-cloudfunctions.net
パス接頭辞の書き換え <未指定>
バックエンド 直前の手順で作成したバックエンドサービスを選択(function-1-backend)

デフォルトだと「ホストの書き換え」は非表示になっているので「アドオン アクション(URLの書き換え)」リンクを押して表示してください。

gcp-addonaction.png

動作確認する(再)

さて修正が反映されるのに3分程度かかりますので少し待ってから、再度ブラウザからhttp://xxx.xxx.xxx.xxx/function-1にアクセスしてみます。

画面に Hello World! が表示されれば成功です。:congratulations:

最後に

固定のIPアドレスでアクセスできるようになったので、あとはDNSにAレコードを設定して独自ドメインでのアクセス完了です。
Cloud Load Balancingへ証明書設定すればHTTPSアクセスにしたりできる状態ですね。

最後に数点補足です。

  • Hostヘッダの書き換えをしているのでリダイレクト伴うような挙動は影響をうける可能性があります。
  • 今回の用途により適しているServerless NEGもあります。ただし、2020年8月時点でベータ版で、GCPのコンソールからぽちぽち操作できません。

参考文献

この記事は以下の情報を参考にして執筆しました。

そして、

・Google、Google Cloud、Google Cloud PlatformおよびGCPは、Google LLCの商標または登録商標です。
・その他記載されている会社名、製品名、サービス名、ロゴ等は各社の商標または登録商標です。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?