IBM Cloud Code Engineで複数リージョンを組み合わせた高可用性のアプリケーションを構成する

## はじめに
IBM Cloud Code Engineはコードさえあればすぐにアプリを動かすことのできるサーバーレスプラットフォームです。
Code Engineではアプリケーションを複数の地域にデプロイして高可用性を実現することができます。
今回は下図のように、東京・大阪・シドニーの3拠点にアプリをデプロイし、IBM Cloud Internet Services(通称CIS)の[グローバルロードバランサー機能](https://cloud.ibm.com/docs/cis?topic=cis-configure-glb)を使ってアプリにアクセスを分散する構成を検証します。
検証は以下のIBM Cloud Docsに従って進めていきます。
IBM Cloud Docs: [高可用性アプリケーションの構成](https://cloud.ibm.com/docs/codeengine?topic=codeengine-deploy-multiple-regions)

![スクリーンショット 2023-12-05 16.53.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/6c75b644-3678-9a3d-3436-4cbc7876109a.png)

## 事前準備
- 独自ドメインとDNS
[freenom](https://www.freenom.com/ja/index.html)でドメインを取得しました。
- CIS(IBM Cloud Internet Services)インスタンス
CISインスタンスをオーダー後に表示されるチュートリアルに従い、ドメインを登録してください。
- カスタム・ドメインの証明書の生成
以下リンクを参照して証明書を取得してください。
https://cloud.ibm.com/docs/codeengine?topic=codeengine-deploy-multiple-regions&locale=ja#custom-domain-cert

## Code Engineアプリのデプロイ
1. プロジェクトの作成
3つの異なる地域にCode Engineのプロジェクトを作成します。
![スクリーンショット_2023-06-21_14_20_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/3ca5443f-47a1-73f6-5f46-b917efc5e96e.png)
![スクリーンショット 2023-06-21 14.34.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/7f3971d0-e5b5-d83d-e2a3-a57a7894824e.png)

2. アプリケーションのデプロイ
各地域のプロジェクトに同じアプリをデプロイします。
![スクリーンショット_2023-06-21_14_42_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/c54990a0-7de0-3493-9a17-24cfac72c453.png)

アプリケーション作成画面ではコンテナイメージまたはソースコードを指定します。
今回はこちらのサンプルアプリのイメージを使用しました。
icr.io/codeengine/helloworld

Code Engineではインスタンスの最小数を0に設定(ゼロスケール)することもできますが、その場合は後ほど設定するGLBヘルスチェックのタイムアウト値を、インスタンスの立ち上げ時間を考慮して長めに1分くらいにセットすると良いと思います。
![スクリーンショット 2023-11-27 23.25.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/f1015e7f-b876-5414-33ad-99c852c3fb07.png)

3\. TLSシークレットの作成とドメインマッピングの構成
“Domain mappings”を選択し、「作成」をクリックします。
![スクリーンショット_2023-07-18_11_53_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/ef159942-ce7a-744e-13d0-5f465c7f2f43.png)
「ドメイン・マッピングの作成」 ダイアログが表示されるので必要事項を入力します。
![スクリーンショット 2023-07-18 12.00.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/43c1a99a-c636-64fe-bf44-706ce3786f9c.png)
* TLS secret
Certificate chain：中間証明書を含むfullchainのCA証明書の内容（let's encryptの場合はfullchain.pemの内容）
Private key：プライベートキーの内容（let's encryptの場合はprivkey.pemの内容）
* Domain name and target application
ドメイン・ネーム：アプリ公開に利用したいURL（今回はdemoapp.nakayama.tkと指定）
CNAMEターゲット：後ほどCISのGLBの設定の際に使うのでコピーしておく
ターゲット・アプリケーション：ターゲットとなるCode Engine上のアプリを選択

カスタムドメインマッピングの状態が"Ready"になったら次のステップに進みます。
![スクリーンショット 2023-12-05 16.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/215c4b74-43fa-2e9e-6191-36fd13ae3f49.png)
上記を各プロジェクトごとに行います。

## Cloud Internet Services(CIS) グローバル・ロードバランサーの構成
グローバル・ロードバランサー機能は「ヘルス・チェック」、「オリジン・プール」、「ロード・バランサー」という3つの要素で構成されます。
ヘルス・チェックはオリジン・サーバーが正常であるかを監視し、ロード・バランサーは正常なプールにトラフィックをルーティングします。

1. ヘルス・チェックの作成
* CISのコンソールで「信頼性(Reliability)」>「Global load balancers」>「Health checks」を選択し、「作成」をクリックします。
Name：今回はapplication-testというアプリを動かしているので、同じ名前をつけておきます。
Monitor type： HTTPS
Port：443
Path：今回はヘルスチェック用のパスを用意していないのでデフォルトの/(ルートパス)を利用します。ユーザーがアクセスしてくるトップページが開けるかをCISがテストするように設定しています。

Advanced optionsでヘルスチェックを行う間隔やタイムアウト値などを設定できます。
* 「作成」 をクリックします。

2\. オリジン・プールの作成
* CISのコンソールで「信頼性(Reliability)」>「Global load balancers」>「Origin pools」を選択し、「作成」をクリックします。
![スクリーンショット_2023-07-24_16_50_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/75410203-afea-ba44-6fa9-2798e9d5c4c0.png)
* 「Origin poolの作成」ダイアログが表示されるので必要事項を入力します。
Origin name：Code Engine上のアプリと同じ名前をつけていきます。
Origin address：Code Engineのドメイン・ネーム・マッピング設定時にメモしたCNAMEターゲットを設定します。
Weight：オリジンサーバーにトラフィックを割り振る際の優先度を0〜1の間で0.1刻みで設定します。今回は3拠点に平等に割り振るため全て1としています。
Host header (optional)：ドメイン名を設定します。今回はdemoapp.nakayama.tkです。
Health check：「Existing health check」を選択し、先ほど作成した「application-test」を選択します。
* 「保存」をクリックします。

アプリをデプロイした地域ごとに上記のステップを繰り返し、3つのオリジン・プールを作成します。(今回は東京、大阪、シドニー)
![スクリーンショット 2023-11-29 13.33.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/953a46ad-4915-1ae3-711f-97bf56c3bf28.png)

3\. ロード・バランサーの作成
* CISのコンソールで「信頼性(Reliability)」>「Global load balancers」>「Load balancers」を選択し、「作成」をクリックします。
* 「Load balancerの作成」ダイアログが表示されるので必要事項を入力します。
Name (optional)：アクセスする際のURLがdemoapp.nakayama.tkになるように、demoappという名前をつけます。
TTL：60秒〜600秒で設定できます。
Traffic steering：Geoに設定します。複数の地域でアプリを提供している場合に、Geo Routeの設定に従い、ユーザーから一番近い場所にあるオリジン・サーバーにアクセスさせることによりネットワーク遅延を最小限に抑えます。
Geo routes：アクセスしてくるユーザーの地域ごとにどのサーバーにトラフィックを割り振るかを設定できます。今回作成したアプリは日本のユーザーがアクセスしてくる想定なので、Regionは北東アジアを選択し、①東京②大阪③シドニーの優先順位でトラフィックを割り振る設定を追加します。その他(北東アジア以外)の地域からアクセスしてくるユーザーのためにデフォルトのオリジン・プールを設定することで、例えばアメリカのユーザーからのアクセスはデフォルトで設定されたオリジンサーバーへ割り振られます。
![スクリーンショット 2023-12-05 17.10.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/c0d8b743-58ac-6b26-d3aa-0bf72a26dd55.png)

## アプリにアクセスできるか確認
最後に接続確認として、 設定したドメインにアクセスしてみます。
今回のサンプルアプリではEnvironment情報が表示されるようにしています。
CE_DOMAIN=jp-tok.codeengine.appdomain.cloudとあるので、設定した通り優先順位1番の東京のサーバーに割り振られていることがわかります。
![スクリーンショット 2023-12-05 16.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396951/0a7da256-7a6f-1920-10dc-4eeb17caf574.png)