Satellite Linkを使ってプライベートクラスタをIBM Cloud Load Balancerで外部公開する

# 目的

IBM Cloud Satelliteで構築したRed Hat OpenShift on IBM Cloud（ROKS）クラスタは、通常はそのままインターネットからアクセスすることができません。なぜなら、各ノードのIPはプライベートアドレスになるためです。

ROKSのコンソールからこのクラスタに割り当てられたIngressサブドメインを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/c0d305a8-4d74-da24-3eb8-c49858ed31e9.png)

名前解決すると、各ノードのIPであることがわかります。

```
$ dig +short roks-satellite-tok-********81bb6d6d7afea007d1a8cafd-0000.upi.containers.appdomain.cloud
10.244.2.30
10.244.66.26
10.244.130.23
```

よって、このIngressサブドメインはROKSとプライベートIPで通信可能なネットワーク内で使用することが想定されており、インターネットからの利用には使えません。

> ノードのIPをパブリックIPにすればこの制限はなくなりますが、通常はそのようなことはしないと思います。

そのため、クラスタをインターネットから利用するためには、別途ロードバランサーなどを用意する必要があります。

ロードバランサーはクラスタがあるインフラストラクチャー側で用意することが一般的と思いますが、オンプレミスや他社クラウドの場合はそちらの環境やサービスメニューに依存します。そこで今回は、Satellite Linkを使って、IBM Cloud経由でROKSクラスタのアプリを公開してみます。

# 環境

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/4df19af7-e7d0-b193-271f-c459661c0c94.png)

# 手順

## アプリ

テスト用のアプリをデプロイします。

```
$ oc new-project qiita 2>/dev/null || oc project qiita
$ oc new-app --docker-image ibmcom/hello
$ oc expose svc/hello
$ oc get route hello
NAME    HOST/PORT                                                                                             PATH   SERVICES   PORT       TERMINATION   WILDCARD
hello   hello-qiita.roks-satellite-tok-********81bb6d6d7afea007d1a8cafd-0000.upi.containers.appdomain.cloud          hello      8080-tcp                 None
```

このときのURLはプライベートIPなので、インターネットからはアクセスできません。

```
$ dig +short hello-qiita.roks-satellite-tok-********81bb6d6d7afea007d1a8cafd-0000.upi.containers.appdomain.cloud
roks-satellite-tok-********81bb6d6d7afea007d1a8cafd-0000.upi.containers.appdomain.cloud.
10.244.2.30
10.244.66.26
10.244.130.23
```

## Satellite Linkエンドポイント

エンドポイントの作成を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/339e8b81-b702-3fb1-daa0-57791e55bea0.png)

Satelliteロケーションを選択して次へ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/880fad45-222a-b156-db93-0416b1035c1d.png)

エンドポイント名と宛先FQDN、ポートを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/4be67ec1-e6cb-57c2-0da6-83f4bc785f4c.png)

ここの通信はTLSは使いません。すでにトンネリングされているからです。HTTPまたはTCPにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5ef8bf5c-4e3e-0271-3fbf-ff5b9924d387.png)

エンドポイントを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/b83a0fae-95b4-cc21-cac9-1226b2428bc8.png)

エンドポイントのアドレスを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/263ef5af-e2dd-2423-71c4-094481a01545.png)

このときのアドレスを解決します。

```
$ dig +short c-04.private.jp-tok.link.satellite.cloud.ibm.com
satellite-link.jp-tok.serviceendpoint.cloud.ibm.com.
166.9.40.11
166.9.42.86
166.9.44.79
```

これらのアドレスがIBM Cloud側のアドレスです。このアドレスにアクセスするとROKSまで到達できます。ただ、これらのアドレスはまだIBM Cloud内部のアドレスですので、インターネットからはアクセスできません。

## VPC Load Balancer

エンドポイントアドレスにインターネットからアクセスするためにロードバランサーを立てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/586813ca-5777-a2d3-3af8-e66ef386ebd1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5d452be7-c0cc-9ddb-4fd5-69e7016b6d93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/64294228-3589-8c5f-8001-5b94db8f9ae6.png)

ここからはCLIで操作します。コンソールではバックエンドプールのメンバーに任意のIPアドレスを指定できないためです。

ロードバランサーのIDを確認します。

```
$ ibmcloud is lbs
ID                                          名前                                                         ファミリー    サブネット                                                                     パブリックです   プロビジョン状況   作動状況   リソース・グループ
r022-2d2e3d06-97d5-480b-be80-d009aaf2be14   lb-satellite-tok                                             Application   subnet-roks-public-tok1, subnet-roks-public-tok2                               true             active             online     teruz
```

バックエンドプールを作成します。

```
$ ibmcloud is lb-pc pool-satelite-tok-80 r022-2d2e3d06-97d5-480b-be80-d009aaf2be14 round_robin http 2 1 1 tcp

ID                           r022-ec767e54-5f73-4780-983b-16d96b851e45
名前                         pool-satelite-tok-80
プロトコル                   http
アルゴリズム                 round_robin
インスタンス・グループ       ID   名前
                             -    -

Proxy Protocol               disabled
ヘルス・モニター             タイプ   ポート   ヘルス・モニター URL   遅延   再試行回数   タイムアウト
                             tcp      -                               2      1            1

セッション・パーシスタンス   タイプ   Cookie 名
                             -        -

メンバー
プロビジョン状況             active
作成済み                     2021-09-26T12:43:12.18+09:00
```

先ほどのIPをメンバーとして追加します。

```
$ ibmcloud is lb-pmsu r022-2d2e3d06-97d5-480b-be80-d009aaf2be14 r022-ec767e54-5f73-4780-983b-16d96b851e45 --members '[{"port": 32785, "target": {"address": "166.9.40.11"}},{"port": 32785, "target": {"address": "166.9.4
2.86"}},{"port": 32785, "target": {"address": "166.9.44.79"}}]'
ID                                          ポート   ターゲット    重み   ヘルス    作成済み                        プロビジョン状況
r022-584ca51a-59d4-4add-85f3-023f86d1e7f1   32785    166.9.40.11   50     unknown   2021-09-26T12:44:56.551+09:00   create_pending
r022-b047a43c-66d5-4cab-b8a0-6623a7434f57   32785    166.9.42.86   50     unknown   2021-09-26T12:44:56.57+09:00    create_pending
r022-8f2768c5-e38e-4b80-a000-8161569e6658   32785    166.9.44.79   50     unknown   2021-09-26T12:44:56.585+09:00   create_pending
```

登録を確認します。

```
$ ibmcloud is lb-pms r022-2d2e3d06-97d5-480b-be80-d009aaf2be14 r022-ec767e54-5f73-4780-983b-16d96b851e45
ID                                          ポート   ターゲット    重み   ヘルス    作成済み                        プロビジョン状況
r022-584ca51a-59d4-4add-85f3-023f86d1e7f1   32785    166.9.40.11   50     unknown   2021-09-26T12:44:56.551+09:00   active
r022-b047a43c-66d5-4cab-b8a0-6623a7434f57   32785    166.9.42.86   50     unknown   2021-09-26T12:44:56.57+09:00    active
r022-8f2768c5-e38e-4b80-a000-8161569e6658   32785    166.9.44.79   50     unknown   2021-09-26T12:44:56.585+09:00   active
```

ここからはわかりやすさのために再度コンソールで作業します。フロントエンドリスナータブで作成を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/bfa76e08-03c3-64e2-63b0-b67cc1b9df65.png)

今回はプロトコルでHTTPを選択し、先ほど作成したバックエンドプールを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/9634861f-3752-e862-6913-8868248c6b86.png)

作成されたことを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/40a5e4e0-60ce-17c1-2c09-d47c1861df0a.png)

概要タブを確認します。正常性の状態がOK（緑）になっていることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/2f1beb75-1bfa-0bcf-67bd-e2820d3ba6f5.png)

## ルートの作成

現時点でロードバランサー経由でROKSまで到達可能になっています。しかしブラウザからアクセスすすとApplication is not availableになります。これは、このときのURLに対応したルートが存在しないためです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/385ac1a2-611d-7afe-026b-42c15844cf0c.png)

ルートを作成します。先ほどSatellite Linkを作成した際に通信を平文にしたので、ルートもHTTPで作成します。

```
$ oc expose svc/hello --name hello-link --hostname ********-jp-tok.lb.appdomain.cloud
$ oc get route hello-link
NAME         HOST/PORT                            PATH   SERVICES   PORT       TERMINATION   WILDCARD
hello-link   *******-jp-tok.lb.appdomain.cloud          hello      8080-tcp                 None
```

ブラウザをリロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/3eda1dd6-748b-46fa-45d3-6ee99c967baa.png)

# 考慮点

* エンドポイントIPがもし将来変わるとロードバランサーから通信はできなくなります
* 今回はHTTPSなしでやりましたが、実運用を考えるとHTTPSを検討ください
* 今回はLBとRouteが1:1になっていますが、LBのFQDNをDNSでCNAME指定することで、複数のFQDNと対応するRouteを定義すれば、複数のアプリを1つのLBで公開可能です