IBM Cloud Satellite環境の構築 & SatelliteでのOpenShiftクラスターの作成をやってみた

# はじめに
[IBM Cloud Satellite](https://www.ibm.com/jp-ja/cloud/satellite)は、IBM Cloudで提供される分散クラウド環境です。

近年では、単一のクラウドベンダーだけを利用するのではなく、リスクの分散、ロックインの回避などのため、複数のクラウドベンダーを利用するケースがあります。ただ、「複数」を管理することは「単一」に比べて煩雑になりますし、それぞれのクラウドに関するスキルも必要となります。

また、重要なデータをセキュリティ上の理由によりクラウドに持ち出せず、オンプレミス環境で運用し続けるというケースもあります。ただ、そのような環境であっても、クラウドのメリット、例えばRed Hat OpenShift on IBM Cloud(ROKS)やRed Hat OpenShift Service on AWS(ROSA)といったマネージドなOpenShift環境や、IBM Cloudで提供されるサービスを享受したいというニーズがあります。

IBM Cloud Satelliteは、IBM CloudのサービスやOpenShiftクラスターを任意の場所で稼働させ、それらをIBM Cloudのコンソールで一元的に管理する機能を提供することで、上記の管理の煩雑さや、オンプレでのクラウドメリットの享受を実現します。

当記事では、**IBM Cloud Satellite環境をIBM Cloud上のVPCのサーバに構築し、さらにOpenShiftクラスターを作成する手順**をご紹介します。
※IBM CloudではマネージドOpenShift(Red Hat OpenShift on IBM Cloud)を提供しているため、IBM CloudでOpenShiftクラスターを構築するという意味ではSatelliteを使う理由がありませんが、構築の流れを知るという意味でやってみました。



# ロケーションの作成
IBM Cloud Satelliteを利用するうえで、まず最初に実施することはロケーションの作成です。ロケーションは、IBM CloudのサービスをSatelliteを用いて稼働させる環境のことです。オンプレミスのデータセンターや、AWS、Azureなどのクラウドサービス、あるいは、自宅のサーバでもOKです。ロケーションには3つの論理的なゾーンを定義し、Satelliteを構成するホストを各ゾーンに割り当てます。高可用性の観点で、3つのゾーンは物理的に分離された環境にあることが望ましいです。ただ、3つのゾーンに割り当てるホストは任意に設定できるので、可用性を無視するのであれば、同一マシン内のVMを各ゾーンに割り当てることも可能です。なお、[ロケーション内のホスト間のネットワーク遅延に関する要件](https://cloud.ibm.com/docs/satellite?topic=satellite-infrastructure-plan#plan-zone-host-reqs)がありますので、ネットワーク的に離れた環境をロケーションに含めることはできません。

ではロケーションを作成していきます。IBM Cloud Satelliteの[ロケーションの作成](https://cloud.ibm.com/satellite/locations/create)にアクセスします。

「拡張構成」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/0eed2087-1e3c-cf69-c304-0c27c902bbe1.png)

インフラストラクチャー・タイプとして「パブリック・クラウド」を選択し、「クラウド・プロバイダー」はIBM Cloudを使用するため「その他のクラウド」を選択します（IBM CloudのサービスであるにもかかわらずIBM Cloudが「その他のクラウド」となっているのは、前述の通り、本来はIBM Cloud上にSatellite環境を構築する意味がなく、AWSやAzureのように専用の構築スクリプトが用意されていないためと思います）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/2bed4a62-74ae-2e86-6f59-03714c9d4e42.png)

ワークフローでは「手動」を選択します。また、Satelliteロケーションでは、任意の名前を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e90f0c8f-182a-8b48-670e-e552c2ab040e.png)

管理元は、作成するSatelliteを管理する元のリージョンになります。今回、Satelliteを構成するホストは東京リージョンに作成するため、「東京」を選択します。また、Satelliteを構成する3つのゾーンの名前を入力します。ここでは「zone-1」「zone-2」「zone-3」としています。ここまで入力した後、「ロケーションの作成」ボタンをクリックします。これによりロケーションが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/b036b385-d5dd-3dd9-2499-ac87c7c26f2f.png)


# ホストの作成
次にロケーションに割り当てるホストを作成します。ロケーション内のホストは、大きく分けて、Satelliteを管理するためのコントロール・プレーンを稼働させるホストと、OpenShiftやIBM Cloudサービスを稼働させるためのホストに分類されます。このうち、コントロール・プレーンとなるホストは[PoC・検証目的でも最小3台、本番用途であれば最小6台が必要](https://cloud.ibm.com/docs/satellite?topic=satellite-infrastructure-plan#location-sizing)です。これに加えて、OpenShiftやサービスを稼働するためのホストが必要なので、本番用途では7台以上のホストを用意する必要があります。


ではホスト(VSI)をVPC(Gen2)に作成していきます（VPCは作成済みの前提です）。IBM Cloudの[VSIの作成](https://cloud.ibm.com/vpc-ext/provision/vs
)のページにアクセスします。

名前に任意の名前を入力します。ロケーションは、今回Satelliteロケーションの管理元として東京リージョンを選択しましたので、VSIも東京リージョンの「東京2」ゾーンに作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/599f295c-d841-35a7-2f60-cc52617f2964.png)

オペレーティング・システムは、「Red Hat Enterprise Linux」の「ibm-redhat-7-9-minimal-amd64-3」を選択します。Satelliteのホストの要件として、[「x86 アーキテクチャーで Red Hat Enterprise Linux 7」](https://cloud.ibm.com/docs/satellite?topic=satellite-host-reqs#reqs-host-compute)というものがあるためです。また、HW要件は[「少なくとも 4 つの vCPU、16 GB のメモリー」](https://cloud.ibm.com/docs/satellite?topic=satellite-host-reqs#reqs-host-compute)とされているため、ここでは「Balanced bx2d-4x16」を選択します。加えて、作成したVSIに後ほどsshでログインするため、SSH鍵を設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/41199f86-4a48-a354-6444-9b1db2797944.png)

VSIを作成する対象のVPCを選択し、「Virtual Server インスタンスを作成します」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/68c67950-2675-ec74-c20e-6493e58ff337.png)


VSIの作成完了後、そのVSIにフローティングIPアドレスを割り当てます。[フローティングIPアドレス](https://cloud.ibm.com/vpc-ext/network/floatingIPs)のページにアクセスし、「作成」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/40aa3410-3450-682a-9a67-1de179f7c77c.png)


浮動IP名に任意の名前を入力します。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/1120624d-650c-d205-3992-d8129de1f52e.png">

フローティングIPのロケーションはVSIと同じ東京リージョンの「東京2」を選択し、バインドするリソースに先ほど作成したVSIを選択し、「IPの予約」ボタンをクリックします。これで先ほど作成したVSIにフローティングIPアドレスが割り当てられます。
<img width="400" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/4f7decc7-6800-b4cd-d2b3-79b0fb09bab1.png">

今回は9台のホストをロケーションに接続するため、上記のVSIの作成、フローティングIPの作成を9台分繰り返し実施します。


# ロケーションへのホストの接続・割り当て
次に、作成したホストをロケーションに接続していきます。ロケーションへの接続は、IBM Cloudからダウンロードした専用のスクリプトを用いて実施します。ダウンロードには`ibmcloud sat`コマンドを使用しますが、これを使用するために、IBM Cloud CLI、および、`container-service`プラグインをインストールします。

未インストールの場合、[Satellite CLIのインストール](https://cloud.ibm.com/docs/satellite?topic=satellite-setup-cli)ページを参照し、インストールしてください。

インストール後、以下のコマンドを実行し、ロケーションへの接続用スクリプトをダウンロードします。コマンドを実行すると、ダウンロード先のファイルパスが出力されるため、そのパスを記録しておきます。

```bash
# 事前にibmcloud loginでログインしておくこと
ibmcloud sat host attach --location <Satelliteロケーション名>
```

以降のホスト接続の手順は、IBM CloudのRed Hat Enterprise LinuxのVSIを使用した場合の手順になります。[AWS、Azureなどの場合は手順が異なる](https://cloud.ibm.com/docs/satellite?topic=satellite-hosts#attach-hosts-cli)ためご注意ください（後述のホストの「割り当て」については共通の手順になります）。

以下のコマンドを実行し、scpでVSIに接続用スクリプトをアップロードします。秘密鍵ファイルは、VSIの作成時に指定したSSH鍵(公開鍵)に対応する秘密鍵を指定します。

```bash
scp -i <秘密鍵ファイル> <ダウンロードしたスクリプトのパス> root@<フローティングIPアドレス>:/tmp/attach.sh
```

以下のコマンドを実行し、VSIにログインします。

```bash
ssh -i <秘密鍵ファイル> root@<フローティングIPアドレス>
```

ログイン後、以下のコマンドで、Red Hat Enterprise Linuxのパッケージをリフレッシュします。

```bash
subscription-manager refresh
subscription-manager repos --enable=*
```

その後、接続用スクリプトを実行します。

```bash
nohup bash /tmp/attach.sh &
```

接続用スクリプトの実行には時間がかかります。以下のコマンドで接続用スクリプトの実行状況を確認することができるようですが、私が実行したときは同じ内容が繰り返されるだけでよく分からなかったので、後述の手順で接続結果を確認します。

```bash
journalctl -f -u ibm-host-attach
```

[Satelliteロケーションの一覧](https://cloud.ibm.com/satellite/locations)で先ほど作成したSatelliteロケーションを選択し、「ホスト」をクリックします。すると、下記のようにロケーションに接続したホストが表示されるので、「状況」が「作動可能」、「可用性」が「未割り当て」であることを確認します（まだコントロール・プレーンなどに割り当てていないため、「未割り当て」が正しい状態です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/56b357f5-b272-950a-5f50-a61aacd4dfa8.png)

ここから接続したホストをコントロール・プレーンに割り当てていきます。表示されているホストの右側の縦3点リードをクリックし、「ホストの割り当て」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/ceafe539-5060-eab6-1912-7f1a4a9adabd.png)

クラスターとして「Control plane」を選択し、さらにゾーンを設定します。ロケーションの作成時に3つのゾーンを作成しましたが、コントロール・プレーンとして割り当てるホストはこの3つのゾーンに均等に割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/df020322-d885-12ad-0420-bbba53b82fd7.png)

割り当てると、可用性が「割り当て済み」の状態となります。これを残りのホストに対しても繰り返していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/0698f459-20fa-49e8-442f-5ba56165f2fe.png)

6台のホストをコントロール・プレーンに割り当てた結果が以下になります。今回は6台を割り当てましたが、コントロール・プレーンは最小3台から動作します（本番用途では6台以上の3の倍数）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/9154f53b-3cbb-9c17-0136-02dc9cfbf0c3.png)

ここまででSatellite環境を管理するコントロール・プレーンが準備できました。以降ではこのSatelliteロケーションにOpenShiftクラスターを作成していきます。

# OpenShiftクラスターの作成
先ほど接続、割り当てしたホストはコントロール・プレーン用のため、OpenShiftクラスター用にさらに追加でホストが必要となります。前述の手順に従い、VSIを作成し、Satelliteロケーションに「接続」するところまでを実施して、「未割り当て」のホストを用意してください（「割り当て」はしないでください）。ここでは以下のように3台の「未割り当て」のホストを用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/3510cd31-7c2a-c20f-70bc-cf94fb8cc273.png)

[OpenShiftクラスター作成](https://cloud.ibm.com/kubernetes/catalog/create?platformType=openshift)のページにアクセスします。

「手動セットアップ」を選択し、OpenShiftのバージョンを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/6c48125f-0523-e868-a3a5-1d0336dadd1a.png)

インフラストラクチャーでは「Satellite」を選択し、ロケーションとして先ほど作成したSatelliteロケーションを選択します。ここでホストの使用率が表示されていますが、未割り当てのホストが存在している必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/9c760550-14c3-5096-11fe-48a00d4fb85a.png)

ワーカー・プールとして、Satelliteロケーションの3つのゾーンを選択します。ワーカー・プールのvCPU、メモリーは、Satelliteロケーションに接続したホストのスペックです。今回は未割り当てのホストが3つありますので、ゾーンあたりのワーカー・ノードは1台で、3つのゾーンで合計3個のワーカー・ノードとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/a6c348c5-ae2d-e5ca-bddb-2b73be7d8843.png)

Satellite Configは、「クラスター管理者のSatellite Configのアクセス権限を有効にしてください」を選択します。最後に（OpenShiftの）クラスター名を設定し、「作成」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/51e2bb9c-a43f-a57d-5116-be4161f8615b.png)

しばらく待つとOpenShiftクラスターの状態が「正常」となり、3台のワーカー・ノードを持つクラスターができあがります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/d93a07d6-6b24-de93-7924-58d3313e71e3.png)


# OpenShiftクラスターにアクセスするための設定
OpenShiftクラスターができたので、早速上記のスクリーンショットの「OpenShift Webコンソール」ボタンをクリックしてOpenShiftにアクセスしたいところですが、このままではアクセスできません。

OpenShift Webコンソールにアクセスするためには以下の設定が必要となります。

## IBM Cloudの Client VPN for VPCを使用し、VPCに対してVPNアクセスする

Satelliteで作成したOpenShiftのWebコンソールは、デフォルトではパブリックからのアクセスができないようで、VPCに対してVPN接続し、プライベートでアクセスする必要があるようです。

そのため、IBM Cloudで提供されている[Client VPN for VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-client-to-site-overview)サービスを利用してVPN接続します（2022年1月時点でベータ版）。セットアップ手順は以下のQiita記事が詳しいので、こちらをご参照ください。

Qiita記事：[Client VPN for VPC（Client to Site型VPN）（ベータ版）でVPC環境に接続する](https://qiita.com/y_tama/items/16987e07842262cd9068)

Client VPN for VPCを作成し、VPNサーバー経路を作成します。アクションを「配信」、宛先CIDRをOpenShiftクラスターのワーカー・ノードとして追加したホストのフローティングIPアドレスの範囲として経路を作成します。作成後は以下のような状態となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e6bc7904-850f-42d7-ff9f-561e46008ac4.png)


## VPCのセキュリティ・グループの設定
VPCのセキュリティ・グループで、インバウンドのポート443、1024-65535を許可します。これらのポートを許可する根拠は[OpenShiftのAWS VPCへのインストール要件](https://docs.openshift.com/container-platform/4.8/installing/installing_aws/installing-aws-vpc.html#installing-aws-vpc)ですが、これが正しいかはいまいち分かりません(後日訂正するかもしれません)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e0e8bd43-37ef-2696-6940-4e6ea128753c.png)


ここまでを設定することで、無事に「OpenShift Webコンソール」ボタンでOpenShiftのWebコンソールを開けるようになっているはずです。また、Webコンソールで`oc`コマンドでのログイン用コマンドも取得できるようになっているはずです。