目的
IBM Cloud Satelliteで構築したRed Hat OpenShift on IBM Cloud(ROKS)クラスタは、通常はそのままインターネットからアクセスすることができません。なぜなら、各ノードのIPはプライベートアドレスになるためです。
ROKSのコンソールからこのクラスタに割り当てられたIngressサブドメインを確認します。
名前解決すると、各ノードの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クラスタのアプリを公開してみます。
環境
手順
アプリ
テスト用のアプリをデプロイします。
$ 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エンドポイント
エンドポイントの作成を選択します。
Satelliteロケーションを選択して次へ。
エンドポイント名と宛先FQDN、ポートを指定します。
ここの通信はTLSは使いません。すでにトンネリングされているからです。HTTPまたはTCPにします。
エンドポイントを作成します。
エンドポイントのアドレスを確認します。
このときのアドレスを解決します。
$ 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
エンドポイントアドレスにインターネットからアクセスするためにロードバランサーを立てます。
ここからは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
ここからはわかりやすさのために再度コンソールで作業します。フロントエンドリスナータブで作成を選択します。
今回はプロトコルでHTTPを選択し、先ほど作成したバックエンドプールを選択します。
作成されたことを確認します。
概要タブを確認します。正常性の状態がOK(緑)になっていることを確認します。
ルートの作成
現時点でロードバランサー経由でROKSまで到達可能になっています。しかしブラウザからアクセスすすとApplication is not availableになります。これは、このときのURLに対応したルートが存在しないためです。
ルートを作成します。先ほど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
ブラウザをリロードします。
考慮点
- エンドポイントIPがもし将来変わるとロードバランサーから通信はできなくなります
- 今回はHTTPSなしでやりましたが、実運用を考えるとHTTPSを検討ください
- 今回はLBとRouteが1:1になっていますが、LBのFQDNをDNSでCNAME指定することで、複数のFQDNと対応するRouteを定義すれば、複数のアプリを1つのLBで公開可能です