OpenShiftにMilvusを立てた備忘録

## 概要
ベクトルDBのMilvusをRed Hat OpenShift (OCP)に立てようとして、思いがけず苦労したので備忘録として残しておきます。元々はオンプレミスのIBM watsonxでRAGの検証をしようと思った際に、検証用なので小さい構成のMilvusを同居させたかったという動機でした。

## 前置き
OCPにアプリを追加インストールしインスタンスを立てる場合はOperatorを利用することが多いと思いますが、Milvus Operatorの[公式](https://github.com/zilliztech/milvus-operator)を見るとHelmでのインストールの方が簡単そうでしたので、今回はHelmを使った方法を選びました。以下の手順は基本的に[こちら](https://milvus.io/docs/ja/install_cluster-helm.md)に沿ったものです。OCPは4.14を使用しました。また、OCPにはMilvusのデータを格納するためのストレージが必要なので、NFSやODFなどのストレージクラスをセットアップしておく必要があります。

## 手順
まず、前提準備としてOCPを操作するBastion環境(ocコマンドが使えるLinuxなど)を用意しておきます。
- ocコマンド
- Helmコマンド

---
- OCPにログイン
```
oc login --username=${OCP_USERNAME} --password=${OCP_PASSWORD} --server=${OCP_URL}
```
- プロジェクトの作成と切り替え
```
oc create namespace milvus
oc project milvus
```
- Helm repoの登録
```
helm repo add zilliztech https://zilliztech.github.io/milvus-helm/
helm repo update
```
- HelmでMilvusをインストール
```
helm install my-release zilliztech/milvus
```
するとこのような出力が見られます。
```
NAME: my-release
LAST DEPLOYED: Sat Feb 15 05:52:25 2025
NAMESPACE: milvus
STATUS: deployed
REVISION: 1
TEST SUITE: None
```
少し待つと、Podが起動してくるはずなのですが・・・ここで実際にはそうならずに、エラーが出て待ち状態になっていました。OCPコンソールに入り、StatefulSetsに移ると、my-release-etcdなどの３つほどのStatefulSetsでPodができない状態になっている(0/3)ことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/5cc0c811-2907-4966-b8b2-2c04733af71e.png)
そのmy-release-etcdのイベントタブで見ると、どうやら権限エラーになっている模様。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/62f17cf0-17f7-4975-8e48-e253361117c1.png)
```
create Pod my-release-etcd-0 in StatefulSet my-release-etcd failed error: pods "my-release-etcd-0" is forbidden: ....
```
あまりOCPに詳しくないために、この問題に対処するのに時間がかかってしまいましたが、最終的に次のようなコマンドを実行すれば、このエラーが解消できました。
```
oc create serviceaccount milvus
oc adm policy add-scc-to-user anyuid -z milvus
oc set serviceaccount statefulsets/my-release-etcd milvus
oc set serviceaccount statefulsets/my-release-pulsarv3-zookeeper milvus
oc set serviceaccount statefulsets/my-release-pulsarv3-bookie milvus
```
最終的に、必要となるPodがすべて立ち上がりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/0b4fa6e8-9f9e-42a9-b7de-223b69745bd1.png)

## 使ってみる
さて、Serviceのmy-release-milvusを見ると、ポートとして19530と9091を開いていることがわかります。19530はMilvus、9091はWebUIのポートです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/e0573860-fe6d-48f9-8d9c-30a82c1ccbf8.png)

まずPythonを使ってMilvusに接続するために、BastionからOCP上のMilvusサービスへのネットワーク経路を開いておきます。
```
oc port-forward --address 0.0.0.0 service/my-release-milvus 27017:19530
```
するとポートフォワードの待機状態になるので、クライアントPCからBastionの27017ポートに接続すれば、そこからOCP上のMilvusにつながります。以下はPythonで接続してみた例です。
```
from pymilvus import MilvusClient

milvus_host="Bastionのホスト名またはIPアドレス"
milvus_port="27017"

client = MilvusClient(
    uri="http://"+milvus_host+":"+milvus_port
)

print(client.list_aliases())

client.create_collection(
    collection_name="demo_collection",
    dimension=768,  # The vectors we will use in this demo has 768 dimensions
)

print(client.list_collections())
```
同様に、MilvusのWebUIを使うには、9091をBastionでポートフォワードします。
```
oc port-forward --address 0.0.0.0 service/my-release-milvus 27018:9091
```
すると、クライアントPCからWebUIを使うことができます。
```
http://(Bastionのホスト名またはIPアドレス):27018/webui/
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/3f61caf7-1940-44ac-887d-fce3ca03dc5f.png)
Pythonで作成したcollectionが見えていますね！

## まとめ
OpenShiftでMilvusを立てることができましたが、思わぬところで引っかかりました。ひょっとすると2025/2時点での不具合なのかもしれませんが、同じところでハマった方の助けになれば幸いです。