vSphere IaaS Control Plane を構築してみる (HA Proxy)

# 概要

vSphereの機能であるvSphere IaaS Control Plane (旧vSphere with Tanzu) を構築してみたため、その内容の備忘となります。
今回は構築後簡易的にPodを構築してみるところまで見てみます。
また、vSphere 8.0u3から利用可能なConsumption Interfaceという機能も用いてみます。
※ 特にそれぞれの細かい機能の説明等は省いて、構築の流れ中心です


## vSphere IaaS Control Planeとは
> vSphere IaaS control plane を使用すると、vSphere を、Kubernetes ワークロードをハイパーバイザー レイヤーでネイティブに実行するためのプラットフォームに変換できます。vSphere クラスタで vSphere IaaS control plane を有効にすると、Kubernetes ワークロードを ESXi ホストで直接実行し、専用の名前空間（vSphere 名前空間）内にアップストリーム Kubernetes クラスタを作成する機能が提供されます。
> https://docs.vmware.com/jp/VMware-vSphere/8.0/vsphere-with-tanzu-concepts-planning/GUID-70CAF0BB-1722-4526-9CE7-D5C92C15D7D0.html

すごくざっくり言うと、vSphereの機能を用いてvSphere上にKubernetes環境を展開できる機能になります。必要なノードも仮想マシンとして自動で作成を行ってくれます。
※ vSphere8.0u2bまではvSphere with Tanzuという名称でした


## 前提環境

今回は以下環境で実施を行っています。

- バージョンは8.0u3 (ESXi & vCenter)
- ESXi × 3台
    - CPU 12コア
    - メモリ 40GB
- vSAN構成済み
- DRS & HA有効化済み (動作要件)
- 分散ポートグループ作成済み (VLAN0 & VLAN1)

利用している上記環境は以下手順で作成しています

https://qiita.com/strawberryjam/items/06c8240b3b30d7fe8e1e

システム要件は以下ドキュメントをご参考ください。

https://docs.vmware.com/jp/VMware-vSphere/8.0/vsphere-with-tanzu-concepts-planning/GUID-C3048E95-6E9D-4AC3-BE96-44446D288A7D.html


## ロードバランサーの構成について

vSphere IaaS Control Planeではロードバランサーを準備する必要があり、選択肢は以下3つになります。

- NSX
- NSX Advanced Load Balancer
- HA Proxy

今回はタイトルにもある通り、OSSのHA Proxyを使っていきます

https://github.com/haproxytech/vmware-haproxy


# vSphere IaaS Control Plane 構築
## ネットワークの構成思案

初めにネットワークの構成を考えておきます。

基本的には3種類のIPレンジを決めていく形となります。
今回はそれぞれ以下のようなIPレンジにして進めていきます。

| 項目               | IPレンジ             | 用途                                                                                                   |
| ---------------- | ----------------- | ---------------------------------------------------------------------------------------------------- |
| Supervisor Node  | 192.168.0.132~135 | - IaaS Control Planeを有効化時に展開されるSupervisor Control Plane VMに振られるIPアドレス<br>- 指定したIPアドレスから4つ割り振られる      |
| Workload Cluster | 192.168.1.16~31   | - Kubernetes ClusterのControl Plane & Worker Nodeの仮想マシンに振られるIPアドレス<br>- Supervisor Nodeとはネットワークを分けておく |
| Virtual IP       | 192.168.1.32~63   | - Kubernetes内のExternel IPに振られる<br>- 他にもユーザーがkubectlでアクセスする際の制御プレーンのIPアドレスにも使われる                                                                       |


vSphere Client上で確認できるネットワークトポロジに書き加えると以下のようなイメージです。
※一番左の131のIPアドレスはHA Proxyのアプライアンスに振るIPアドレスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/2809bf13-6c5a-ef0e-f21b-43c5cdeb1d52.png)

上記図の通り、大きくネットワークとしては3つありますが、Frontend Networkはオプションのため、今回はWorkload Networkと同じネットワーク上のIPレンジとしています。

## HA Proxy の展開

それではHA Proxyを展開していきます。

まずHA ProxyのOVFをダウンロードします。
以下githubからダウンロードできるため、本記事執筆時点で最新のv0.2.0をダウンロードしておきます。
https://github.com/haproxytech/vmware-haproxy#download
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/542a14f9-3367-566d-ec8d-be6618c74d3d.png)

そうしたら、OVFテンプレートのデプロイを進めていきます。

名前や展開先を指定後、デプロイ構成を聞かれます。
ここではFrontend Networkを分けて構成するかしないかの選択になります。
今回はFrontend Networkは分けないため、Defaultで進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/c3b1bd0a-7d01-f57d-0e7a-5636ca5aa6fe.png)

その後アプライアンスのパスワードや利用するIPアドレスやポートグループの指定を進めます。
ポートグループの指定では、Frontend Network用のものも聞かれますが、Default設定で進めている場合は指定するだけで使われないため、適当に入れておいてください。
また、Load Balancer IP Rangesでは前段で決めておいたVirtual IPのレンジをサブネット形式で入れておきます。
今回は192.168.1.32~63のため、192.168.1.32/27となります。

展開した設定のサマリは以下のようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/19283b8b-7386-ef2b-d366-9cb58b403d7d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/380a4c15-6886-e946-4cd1-0ea84bfd750d.png)

展開し起動後IPアドレスに2つのネットワークそれぞれのものが振られていることを確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/2f87a619-875d-e031-f47f-24e920537fa3.png)


続いて、後ほど利用するため、HA Proxyの証明書を確認してコピーしておきます。
設定の編集の詳細パラメータで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/62ebd641-3c32-5b55-9bba-7915c38646d7.png)


この証明書の値はbase64でエンコードされているため、デコードして以下のような証明書のパラメータにしておいておきます。

    -----BEGIN CERTIFICATE-----
    MIIDoTCCAomgAwIBAgIJAM7daiRh/RKuMA0GCSqGSIb3DQEBBQUAMG4xCzAJBgNV
    ~~~
    ~~~
    ~~~
    92A9PgWeozxM9ACASCL3KaVXfrHX
    -----END CERTIFICATE-----

以上でHA Proxyの準備は完了です。

## ワークロード管理の有効化

それではワークロード管理の有効化を行っていきます。
このワークロード管理の有効化を行うことで、vSphere IaaS Control PlaneがvSphere上で利用可能となり、Kubernetesクラスタの構築等が実施出来ます。

vSphere Clietnのメニューからワークロード管理を選択して、開始するを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/83f77af5-dcc8-1fb1-1fd8-f0c33f5c503b.png)

ネットワークスタックを聞かれるため、vSphere Distributed Switchのまま次へ進みます。
(NSXを構成している場合は、NSXを選択可能)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/4a73af57-ae9b-d9a7-400e-55e8ffc3c5ea.png)

スーパーバイザーの配置を聞かれます。
vSphere Zoneを用いた展開と、クラスタ指定でのデプロイのどちらかを選ぶことができますが、今回はクラスタのデプロイを選択します。
なお、クラスタのデプロイを選択した場合でも、vSphere Zoneは自動で1つ作成されます。

クラスタ名をSCP、vSphere Zone名はとりあえずzone-1を入れておきます。
(vSphere Zone名は入れなくても自動で用意される)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/638533f9-cb53-16c9-9ad6-303e849669fe.png)

続いてストレージポリシーの選択となります。
任意のものを選択可能です。今回はあらかじめ環境に用意してあるFTT-0というストレージポリシーを選択します。
※ vSAN以外のデータストアを使う場合もポリシーの準備は必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/d00ca9bf-f82d-c85f-cef7-124267cd9465.png)


続いてロードバランサの設定です。
HA Proxyのデプロイ時に指定したユーザー名/パスワードや先ほど確認しておいた証明書などを入力しておきます。
仮想IPアドレスの範囲は、事前に決めておいたVirtual IPのレンジを入れておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/3d3aa8a1-f026-899d-1160-3fc18059bc5a.png)



管理ネットワークの設定を行います。
ネットワークモードは静的にして、利用するネットワークの情報等を入れていきます。
開始IPアドレスは事前に決めておいたSupervisor Nodeの一番初めのIPアドレスを入れておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/c04649e6-1ed4-71e1-ad0d-e191f650bf03.png)


ワークロードネットワークの設定も管理ネットワークと同様に静的にしつつネットワークの情報等を入れていきます。
IPアドレス範囲は事前に決めておいたWorkload Clusterの範囲を入力しておきます。
また、注意点としてネットワーク名はデフォルトで指定したポートグループ名が入りますが、大文字が利用不可となるため、注意が必要です。今回はworkload-01としておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/d0c60c46-9db9-969d-2f31-02cf066b8115.png)

最後に展開されるスーパーバイザー制御プレーン (Supervisor Control Plane VM) のサイズを指定します。今回は小にしてそのまま完了を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/3126f6ba-2a15-8b3c-a8ac-2998ffd8b116.png)


すると構築が開始されるため、完了を待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/286bda2b-e463-32a2-1e5d-db8e301e806f.png)


構成ステータスの欄の表示を選択すると進捗状況を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/fc97f46d-f505-d41d-0b13-f2e9635c4873.png)


また、構成の途中でSupervisor Control Plane VMが展開されます。
展開された後はホストノードの設定の進捗も確認できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/34fa14bf-8431-3eec-214c-db62523c923c.png)



しばらく待ち構築が完了すると、以下画面上のようにプラグインのデプロイ完了メッセージが表示されます。
そうしましたら、ブラウザの更新をしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/00ab826a-9ae7-172e-b092-4e1f972b8d47.png)


構成完了後は以下の様になっています。
Namespacesというの中にSupervisor Control Plane VMが3台展開されます。
また、svc-〇〇というものが2つvSphere名前空間として展開もされています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/b4d507b9-c2a2-ff38-09d4-c96ebcb3fd08.png)


この自動で展開されているものはvSphere8.0u3から行われるようになっており、実態はスーパーバイザーサービスと呼ばれるものです。
スーパーバイザーサービスはvSphere認定のKubernetesオペレータになっており、HarborやArgoCDなどの便利なアプリを簡単に展開できます。
利用可能なスーパーバイザーサービス: https://vsphere-tmm.github.io/Supervisor-Services/

ワークロード管理の画面からSCP (展開したスーパーバイザークラスタ名) を選び、構成の中から展開されているものは確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/5920b144-d92d-7878-cd47-a653f763dcfb.png)



## Consumption Interfaceの構成  (Options)

続いてConsumption Interfaceの構成を行っていきます。
こちらはスーパーバイザーサービスで提供されているものになり、vSphere IaaS Control Planeを利用する上で必須ではないですが、便利そうなので使っていきます。

ざっくり何ができるのかと言うと、vSphereのGUI上からKubernetsクラスタの展開ができるようになります。
本来はkubectlを用いてマニフェストを展開することでクラスタの作成等を行う形になるところを、vSphere Client上から実施できる感じになります。
(マニフェストの展開を肩代わりしてくれている感じ)
また、kubeconfigもこちら経由で用意できるようになります。

それでは構成をしていきます。
まず展開に必要な構成ファイルをダウンロードします。
以下のページ内からバージョンをクリックするとダウンロードできます。
https://vsphere-tmm.github.io/Supervisor-Services/#consumption-interface

続いてワークロード管理のサービスからサービスの新規追加を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/6c8b32ab-9525-cb97-8c1c-4adcc017bf9c.png)


サービスの登録画面が表示されるため、先程ダウンロードした構成ファイルをアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/f156623a-0480-9bd7-f5d0-d1ca55440490.png)

アップロードするとサービス名東が表示されます。
このまま完了を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/745be906-fbb3-76ab-447b-22f4cdc0fbb3.png)



先ほどのサービスの一覧に追加されるため、そのままアクションからサービスの管理を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/87ef4810-6ee1-4043-c728-255072f4368e.png)


表示されたポップアップで展開先のスーパーバイザーの選択を行い、そのまま完了を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/037aa458-d4d1-d222-7ab1-445662a9c0a7.png)


すると新しいvSphere名前空間が作成され、必要なリソースの展開が開始されるため待ちます。
進捗は対象のvSphere名前空間のポッドから見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/6a9e57a2-1de7-2015-53f6-09a8210a8778.png)

展開完了後、リソースを選択すると以下のような画面が新しく追加されます。
※サインアウトを一度しないと、作成したcluster等の情報が見れないため、しておく
以上でConsumption Interfaceの構成は完了となり、以降はKubernetesクラスタを展開したいvSphere名前空間のリソースタブから操作を行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/e75cb94a-5b0f-ca49-b11b-0304dd187af6.png)

ここまででvSphere IaaS Control Planeの構築は完了となり、Kubernetesクラスタの作成準備が整いました。

# Tanzu Kubernetes Gridの構築

それでは最後にTanzu Kubernetes Gridの構築を行っていきます。
Tanzu Kubernetes GridはvSphere IaaS Control Planeで展開されるKubernetesクラスタのことを指しています。

まず展開先とするvSphere名前空間を作成していきます。
ワークロード管理の名前空間から新規名前空間を選択して作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/6bd7d7e8-9376-0682-e022-cad218de7a14.png)

作成完了後は以下のような画面が表示されます。
権限, ストレージ, VMサービスの欄は指定をしておく必要があるため、選択しておきます。
今回は以下のように指定しています。

- 権限: Admoinistrator/編集可能
- ストレージ: FTT-0
- VMサービス: best-effort-small


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/d6927a05-cfae-26ca-dae9-7f732fed02a1.png)


続いてリソースタブに移り、Tanzu Kubernetes GridのOpenを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/38824a9d-62fe-e726-bf70-007fd821dc96.png)

表示された画面でCREATEを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/47d81cc4-4ce7-afce-024a-69183dc03a84.png)


するとKubernetesクラスタの作成画面が表示されます。
右側にマニフェストが表示されており、その内容にそって作成が行われます。
今回はデフォルトのまま先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/9793f3bd-d993-92a4-81aa-f2c7bbc5c2fe.png)


設定のサマリが表示されるため、問題なければFINISHを押して作成を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/d07ad1fa-2d2d-076b-44e1-8efbb1c522ce.png)



すると作成が開始され、先程の画面にステータスが表示されます。
PhaseがRunningになったら作成完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/4ea5a38d-b2b4-599f-b66c-87e3c88fd875.png)



vSphereのインベントリを見ると、コントロールプレーンとワーカーノードが作成されていることも確認出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/f2f9133c-1959-b19c-de06-ed24f9214fe6.png)




# 動作確認

それでは動作確認として、作成したTanzu Kubernetes GridにPodを立てて見ようと思います。

まずリソースタブからkubeconfigをダウンロードして、ローカルに配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/38f58621-18b5-e741-10ca-57dcccffddfb.png)


kubectlコマンドでkubeconfigを指定する形でget nodesをうち、表示されることを確認します。
コントロールプレーンとワーカーノードが表示されているので問題なしです。
```bash
kubectl get nodes --kubeconfig .\.kube\tkg-cluster-23tz-kubeconfig.yaml

NAME                                                           STATUS   ROLES           AGE     VERSION
tkg-cluster-23tz-jpzm6-fr4nc                                   Ready    control-plane   6m26s   v1.29.4+vmware.3-fips.1
tkg-cluster-23tz-tkg-cluster-23tz-nodepool-xdtfd-cpmkr-x77ld   Ready    <none>          31s     v1.29.4+vmware.3-fips.1
```


それではPodを立てるためにまずPod Securityの設定を当てておきます。
今回はdefault namespaceで作業します。
```bash
kubectl label namespace default pod-security.kubernetes.io/enforce=privileged --overwrite --kubeconfig .\.kube\tkg-cluster-23tz-kubeconfig.yaml
```

それではPodとserviceを展開します。
今回はnginxで簡単に確認します。
```bash
kubectl run nginx --image=nginx --port=80 --kubeconfig .\.kube\tkg-cluster-23tz-kubeconfig.yaml
kubectl expose pod nginx --port=80 --target-port=80 --type=LoadBalancer --kubeconfig .\.kube\tkg-cluster-23tz-kubeconfig.yaml
```

展開後以下コマンドでPodがRunning、serviceのExternel IPが振られていることを確認します。

```bash
kubectl get pods,svc --kubeconfig .\.kube\tkg-cluster-23tz-kubeconfig.yaml

NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   0          32s

NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
service/kubernetes   ClusterIP      10.96.0.1       <none>         443/TCP        7m29s
service/nginx        LoadBalancer   10.101.174.30   192.168.1.35   80:30361/TCP   31s
service/supervisor   ClusterIP      None            <none>         6443/TCP       7m18s
```

Externel IPに接続して、無事nginxにアクセスできたら完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/4ee11e3c-e53e-47ff-0942-67377d0b4a43.png)



# まとめ

今回はvSphere IaaS Control Planeを展開してみました。基本はvSphere with Tanzuと同じ構築方法な感じでした。
展開後のスーパーバイザーサービスが自動で作られたり、スーパーバイザーサービスを用いることでvSphere Client上からクラスタを作成できるのは便利だなという感触です。


## おまけ

私の環境特有の問題かもしれないですが、HA ProxyをOVFテンプレートからデプロイする際にローカルファイルを指定すると何故かエラーが出ることが多かったです。
コンテンツライブラリに一度上げてから展開すると安定したため、同事象が起きた場合はお試しください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406495/8d592cb4-134d-b9e2-b075-fcb7011f81a2.png)

## 参考にしたサイト

https://docs.vmware.com/jp/VMware-vSphere/8.0/vsphere-with-tanzu-concepts-planning/GUID-70CAF0BB-1722-4526-9CE7-D5C92C15D7D0.html

https://docs.vmware.com/jp/VMware-vSphere/8.0/vsphere-with-tanzu-installation-configuration/GUID-5673269F-C147-485B-8706-65E4A87EB7F0.html

https://core.vmware.com/resource/enabling-local-consumption-interface