KubeflowをTanzu Mission Controlでインストールして使ってみる

masanaraさんの[この記事](https://qiita.com/masanara/items/2c05e2e11a3932c0a42a)とかgowatanaさんの[この記事](https://vm.gowatana.jp/entry/2023/12/01/054938)で紹介されている[vSphere Machine Learning Extension](https://vmware.github.io/vSphere-machine-learning-extension/)を使ってKubeflowを試してみたくなったので、Tanzu Mission Control(以下TMC)で導入してみた時のメモ。

なお、ベースとするインストール手順は[こちら](https://vmware.github.io/vSphere-machine-learning-extension/install/tkgs.html)を利用する。

## vSphere Machine Learning Extensionとは
vSphere Machine Learning ExtensionはvSphere上で簡単にKubeflowを展開するOSSのようだが、現時点ではあまり情報がなくてよく分からない。
商用製品とかではないので、実験的にKubeflowをTKG上で使いたい場合に使うのが良さそう。

## 導入の前提
今回は以下があるものとする。
- TKGm2.4のWorkload Cluster (k8s 1.25)
- Tanzu Mission Control (上記のWorkload Clusterは登録済み)
- `type: LoadBalancer`が利用可能（ここではMetalLBを利用）

Tanzu packages内のKubeflowに含まれるHPAのAPIバージョンが古く、おそらくK8sが1.26以上だとHPAのバージョンがv2betaが削除されてv2のみとなっているはずで、以下のエラーでインストールに失敗する。
```sh
    kapp: Error: Expected to find kind 'autoscaling/v2beta2/HorizontalPodAutoscaler', but did not:
```
なのでk8sのバージョンは1.25以下を使うようにした方がよい。
また、Workerノードの要求リソースは[そこそこ大きい](https://vmware.github.io/vSphere-machine-learning-extension/install/tkgs.html#minimally-required-resources-for-tkg-cluster-to-install-kubeflow)ので注意。

## インストール
TMC上でクラスタを選択し、`Add-ons`->`Tanzu repositories`->`ADD PACKAGE REPOSITORY`を選択する。
![1701407261523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/c2eac673-8f7f-6632-76d1-a94db466c60e.png)
リポジトリ追加画面になるので、以下を入力して`ADD REPOSITORY`をクリックする。
- `Name`：kubeflow-carvel-repo
- `Repository URL`：projects.registry.vmware.com/kubeflow/kubeflow-carvel-repo:1.6.1
![1701407395481.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/86e44a7b-1548-bf35-f966-32c3eaa6f877.png)
 
クリック後、`Catalog`->`Tanzu packages`->`Available Tanzu pakcages`でkubeflowが表示されるので、これをクリックする。
![1701407788953.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/931c0dbc-0806-47f0-efc5-1f3f67ed5732.png)

右上の`INSTALL PACKAGE`->`CARVEL SETTINGS`から`Carvel Resources Namespace`で`Custom`を選び、PackageリソースがインストールされるNamespaceを設定する。
ここでは慣例？に従ってmy-packagesとする。
なお、Namespaceはなくても自動で生成される。
設定後、インストール画面に戻り、以下のように設定する。
- `Package name`：kubeflow
- `Overlay YAML`：以下

※'23/12/15追記：
Package versionに1.6.0が表示されるようになっており、デフォルトでこちらが選択される。
ただ、1.6.0だとインストールに失敗するため、Package versionのプルダウンをクリックして**必ず1.6.1を選ぶようにすること**。

```yaml:Overlay YAML
service_type: "LoadBalancer"

IP_address: ""
CD_REGISTRATION_FLOW: True
```
![1701408233539.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/dd99bdb5-06ed-6165-1ee5-718b745f877b.png)

入力後、右上の`INSTALL PACKAGE`をクリックすればインストールが開始される。
環境にも依るかも知れないが、10分以上は掛かるので気長に待つ。
ステータスが緑色に変わればインストール完了となる。
![1701420806758.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/9b182db3-7b2d-11cc-1df2-32eb5957569a.png)

## Kubeflowの利用
ログインするところまで確認する。
KubeflowをイントールするとIstioもインストールされ、IngressGatewayがIPを公開している。
```sh
$ kubectl get svc -n istio-system istio-ingressgateway
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                                                      AGE
istio-ingressgateway   LoadBalancer   100.66.112.220   10.180.84.210   15021:32502/TCP,80:32658/TCP,443:31929/TCP,31400:30899/TCP,15443:32184/TCP   16m
```
そのIPにアクセスするとDexのログイン画面になる。
デフォルトでは`user@example.com` / `12341234`でログインできるようになっている。
![1701421409203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/e1e820f7-77c4-585d-b731-b1a8921543df.png)
ログインするとそのアカウントで使うNamespaceを聞かれるのでNamespaceを指定する。
ここではデフォルト値の`user`のまま進める。
![1701421494673.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/87f7c59b-38f7-8d35-cc59-66561a0de51d.png)

ダッシュボードが確認できた。
![1701422776075.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/96728e89-c789-87cd-31de-ad20a539c6ca.png)

なお、裏では指定した`user`というNamespaceが作成され、Kubeflowのコンポーネントが展開されている事がわかる。
```
$ kubectl get pod  -n user
NAME                                              READY   STATUS    RESTARTS   AGE
ml-pipeline-ui-artifact-79586568b6-5h2dz          2/2     Running   0          32m
ml-pipeline-visualizationserver-8479bf4bd-d85dn   2/2     Running   0          32m
```
ここではついでに[Get Stared](https://vmware.github.io/vSphere-machine-learning-extension/user-guide/notebooks.ｍhtml#get-started)もやっておく。
最初にTensorflow界隈ではよく使われる開発環境である[Jupyter Notebook](https://jupyter.org/)を起動する。
左上の三本線をクリックし、`Notebooks`->`New Notebook`を押すと作成画面となるため、名前や割り当てリソースなどを設定して`LAUNCH`から起動する。
なお、選択できるコンテナイメージはTensorFlow用のイメージである`jupyter-tensorflow-full`を選ばないと後で躓くので、その点だけ注意すること。
![1701425398363.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/415f1221-3960-7519-5cd8-42c7110e93c5.png)

起動後は以下のような画面となる。
![1701424301219.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/d04c39c9-82cf-fc3c-8570-85d7a540c0f5.png)
なお、裏ではJupyter NotebookのPodが起動する。
```
$ kubectl get pod -n user
NAME                                              READY   STATUS    RESTARTS   AGE
getting-started-0                                 2/2     Running   0          27m
ml-pipeline-ui-artifact-79586568b6-5h2dz          2/2     Running   0          109m
ml-pipeline-visualizationserver-8479bf4bd-d85dn   2/2     Running   0          109m
```
このPodにはPVCが割り当てられており、Notebookを削除してもPV、PVCは残る仕掛けとなっている。
削除する際は注意。
作成後の画面の`CONNECT`をクリックするとエディタの画面に遷移する。
![1701424356560.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/abc17462-d976-ab57-bdc4-db40775edc0e.png)
次に[TensorFlow 2 quickstart for experts](https://www.tensorflow.org/tutorials/quickstart/advanced?hl=ja)で配布されているnotebook(Download notebookから入手)をuploadする。
notebook(advaneced.ipynb)をダウンロード後、左サイドバーのアップロードのアイコン（↑マーク）をクリックし、advaneced.ipynbを指定する。
uploadが完了すると左サイドバーに表示されるため、これをクリックして開く。
![1701425981712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/0c9b5c03-245f-3b30-bf54-b99885ceadc8.png)
上部の再生ボタン(▶)をクリックするとチュートリアルが進むため、チュートリアルの内容を確認しつつ下まで実行する。
なお、再生ボタンを押した際、番号が`[*]`のように表示されている時は実行中なので番号が返ってくるまで待つこと。
また、最後のテストは時間が掛かるので少し待つ。
![1701427059349.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/01331463-df3a-b504-6a5e-1e8d4f945da0.png)
試行ごとの結果が以下のような感じで表示される。
```sh
Epoch 1, Loss: 0.1404857486486435, Accuracy: 95.72833251953125, Test Loss: 0.06229446455836296, Test Accuracy: 97.91999816894531
Epoch 2, Loss: 0.041998494416475296, Accuracy: 98.6383285522461, Test Loss: 0.05722526088356972, Test Accuracy: 98.06999969482422
```
Accuracyの値より、試行ごとに精度があがることが確認できた。
（メモリが少なかったのか、途中で強制再起動が掛かり5回実施することは出来なかった）。