Docker composeで導入したMilvusにユーザー認証を有効化する

ベクトルデータベースであるMilvus Standalone版はデフォルトでユーザー認証が有効化されていません。
当記事ではDocker composeで導入したMilvus(=Standalone版)にユーザー認証を有効化する方法を説明します。
尚、Milvusは既にDocker composeで導入し、動作確認済みの想定です。
参考: [M1 Mac上でcolimaを使ってベクトルDB Milvusをインストール](https://qiita.com/nishikyon/items/f529b63a1117d2f10099)(M1 Macである必要はありません)


Milvusのドキュメント「[Authenticate User Access](https://milvus.io/docs/authenticate.md#docker)」に書いてある内容です。

# 1. configuration fileを設定
参考: [Configure Milvus with Docker Compose](https://milvus.io/docs/configure-docker.md)

### 1.1 以下のコマンドで`milvus.yaml`をダウンロードします。
ここではダウンロードする場所は導入に使用する`docker-compose.yml　`がある場所と同じにしておきます。
[こちらの手順](https://qiita.com/nishikyon/items/f529b63a1117d2f10099#3-milvus-standalone%E3%81%AE%E5%B0%8E%E5%85%A5)で導入したと想定して、ここでは`~/milvus`にダウンロードします。

ダウンロードするコマンドは以下です(尚以下の`v2.3.11`は自分の導入するバージョンに合わせて変更してください):
```
wget https://raw.githubusercontent.com/milvus-io/milvus/v2.3.11/configs/milvus.yaml
```

### 1.2 `milvus.yaml`の編集
ダウンロードした`milvus.yaml`の以下を2点を変更します（ただし2番目任意）。
- `common:`セクションの`security:`の`authorizationEnabled:`の値を`false`から`true`　にします。
- `common:`セクションの`security:`の`# superUsers: root`の先頭のコメントアウト`#`を外して有効にします。
    - これは任意ですが、`superUsers`に設定したユーザーIDのみ、パスワード変更時に現在のパスワードが不要になります。通常、管理者がユーザーのパスワード変更する際は現在のパスワードは不明なことが多いですので、最低`root`は定義しておいた方がよいかと思います。


変更前の`milvus.yaml`:
```yaml
(最初の方は省略)
 ・ ・ ・  
common:
  chanNamePrefix:
    cluster: by-dev
    rootCoordTimeTick: rootcoord-timetick
    rootCoordStatistics: rootcoord-statistics
    rootCoordDml: rootcoord-dml
    replicateMsg: replicate-msg
    rootCoordDelta: rootcoord-delta
    search: search
    searchResult: searchResult
    queryTimeTick: queryTimeTick
    dataCoordStatistic: datacoord-statistics-channel
    dataCoordTimeTick: datacoord-timetick-channel
    dataCoordSegmentInfo: segment-info-channel
 ・ ・ ・   
(そして間も省略)
 ・ ・ ・   
  # Default value: auto
  # Valid values: [auto, avx512, avx2, avx, sse4_2]
  # This configuration is only used by querynode and indexnode, it selects CPU instruction set for Searching and Index-building.
  simdType: auto
  security:
    authorizationEnabled: false
    # The superusers will ignore some system check processes,
    # like the old password verification when updating the credential
    # superUsers: root
    tlsMode: 0
  session:
    ttl: 30 # ttl value when session granting a lease to register service
    retryTimes: 30 # retry times when session sending etcd requests
(以下省略)
 ・ ・ ・   
```
変更後の`milvus.yaml`:
```yaml
(最初の方は省略)
 ・ ・ ・  
common:
  chanNamePrefix:
    cluster: by-dev
    rootCoordTimeTick: rootcoord-timetick
    rootCoordStatistics: rootcoord-statistics
    rootCoordDml: rootcoord-dml
    replicateMsg: replicate-msg
    rootCoordDelta: rootcoord-delta
    search: search
    searchResult: searchResult
    queryTimeTick: queryTimeTick
    dataCoordStatistic: datacoord-statistics-channel
    dataCoordTimeTick: datacoord-timetick-channel
    dataCoordSegmentInfo: segment-info-channel
 ・ ・ ・   
(そして間も省略)
 ・ ・ ・   
  # Default value: auto
  # Valid values: [auto, avx512, avx2, avx, sse4_2]
  # This configuration is only used by querynode and indexnode, it selects CPU instruction set for Searching and Index-building.
  simdType: auto
  security:
    authorizationEnabled: true
    # The superusers will ignore some system check processes,
    # like the old password verification when updating the credential
    superUsers: root
    tlsMode: 0
  session:
    ttl: 30 # ttl value when session granting a lease to register service
    retryTimes: 30 # retry times when session sending etcd requests
(以下省略)
 ・ ・ ・   
```
編集が完了したら保存します。

# 2. docker-composeを設定
Milvusのドキュメント「[Configure Milvus with Docker Compose：　Modify the installation file](https://milvus.io/docs/configure-docker.md#Modify-the-installation-file)」に書いてある内容です。

`docker-compose.yml`を以下のように編集します。
**全て**の`volumes:`セクションに以下を追加します。<>は自分のPATHに置き換えます
```yaml
- <1で編集したローカルPC上のmilvus.yamlのフルパス>/milvus.yaml:/milvus/configs/milvus.yaml
```
`volumes:`セクションはversion: '3.5'で3箇所ありました。
1　. `services:`セクションの`etcd:`セクション
編集例: `~/milvus/milvus.yaml`は自分のPATHに要変更です
```yaml
volumes:
      - ~/milvus/milvus.yaml:/milvus/configs/milvus.yaml
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
```

2　. `services:`セクションの`minio:`セクション
編集例: `~/milvus/milvus.yaml`は自分のPATHに要変更です
```yaml
volumes:
      - ~/milvus/milvus.yaml:/milvus/configs/milvus.yaml
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
``` 
    
3　. `services:`セクションの`standalone:`セクション
編集例: `~/milvus/milvus.yaml`は自分のPATHに要変更です
```yaml
volumes:
      - ~/milvus/milvus.yaml:/milvus/configs/milvus.yaml
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
``` 

編集が完了したら保存します。

# 3. Milvusを起動
既にMilvusが起動している場合は、一旦停止します。
停止はdocker-compose.ymlを保存したフォルダーで、以下のコマンドを実行します:
```
docker-compose down
```

起動はdocker-compose.ymlを保存したフォルダーで、以下のコマンドを実行します:
```
docker-compose up -d
```

`docker ps`で表示されるStatusが`milvus-standalone`,`milvus-minio`, `milvus-etcd`の3つ全て **(healthy)** になるのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a2d1a7cc-46eb-1c90-03eb-6f46f0e3dfd7.png)

全て **(healthy)** になれば起動完了です(`milvus-standalone`がちょっと時間がかかります)

# 4. Attusで確認
[Attu](https://github.com/zilliztech/attu)で確認してみます。
参考: [Milvusのグラフィカルな管理ツール AttuをMacに導入してみた](https://qiita.com/nishikyon/items/addf2689812a2d9eb8e3)

[Attu](https://github.com/zilliztech/attu)を起動し、Milvus Addressを入れ、Milvus UsernameとMilvus Passwordはブランクのままで接続してみます。
以下のようなエラーが出で、接続できないようになりました。
> Error: Failed to connect to Milvus: Error: 16 UNAUTHENTICATED: missing authorization in header
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/cea9aca2-e1e7-a2b8-8f5b-8b32f87e6e7e.png)

では、Milvus UsernameとMilvus Password入れてみます。
初期設定は
- Milvus Username: `root`
- Milvus Password: `Milvus`
となっていますので、この値を入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4230d069-e08d-5c58-922b-14103dc6d63a.png)

無事接続できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/82fbde45-0ee6-030c-3aed-c4054800e7d1.png)

さすがにAdmin権限のrootのパスワードはデフォルトから変更した方がよいので、変更します。

1. 左側の「ユーザー」アイコンをクリック:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/7edea850-1c66-0e28-512b-f213ef6a2f8f.png)
1. rootの「Update password」をクリック:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/856bd273-db35-3752-4352-a910eed04954.png)
1. 「Update Milvus User」ウィンドウで必要な情報を入力:
- `Current Password`
    - milvus.yamlに`superUsers: root`を設定していれば、`Current Password`(現在のパスワード) はブランクのままでよいはずなのですが、このGUI,それを許さないので、適当な1文字を入れておきます。またはわかるのであれば現在のパスワードを入れます。
    -

- `New Password`
    - 新パスワード
    - 
- `Confirm Password`
    - 確認のためNew Passwordに入力したパワードと同じ文字列を入力)を入力します。


入力が完了したら「Create」をクリックします。
(ここは普通「Update」であるべきですよね。そのうち修正されるのだろうか??)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/b9de0b4f-08a5-be97-4764-4bdc3343a30e.png)

エラーが出ます。**しかし、これでなぜか成功しているのです。** バグですかね？？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/a21df0b2-4a9a-03cb-6cf9-42dc74e39450.png)

4　. 右上のログアウトのアイコンをクリックしてログアウトします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c9c869ca-7cbe-4e3d-a56d-af8a3634a043.png)

5 . 変更後のパスワードでログインしてみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/be9d29d3-761b-48a3-59b3-737974bda7fc.png)


無事接続できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/82fbde45-0ee6-030c-3aed-c4054800e7d1.png)

なんかスッキリしないので次にpythonで確認してみます。

# 5. pymilvus(python)で確認

### 5-1. milvusへの接続、pwなし
詳細: [Connect to a Milvus server](https://milvus.io/docs/manage_connection.md#Connect-to-a-Milvus-server)
```py
from pymilvus import connections
conn= connections.connect(
  alias="default", 
  host='localhost', 
  port='19530'
)
```
エラーがでます:
> grpc RpcError: [__internal_register], <_InactiveRpcError: StatusCode.UNAUTHENTICATED, missing authorization in header>, <Time:{'RPC start': '2024-03-19 23:59:13.307493', 'gRPC error': '2024-03-19 23:59:13.319098'}>

### 5-2. user,passwordも入れて、milvusへの接続
詳細: [Connect Milvus with an authenticated user](https://milvus.io/docs/authenticate.md#Connect-Milvus-with-an-authenticated-user)

初期設定は
- Milvus Username: `root`
- Milvus Password: `Milvus`
となっていますので、この値を入れます。

```py
from pymilvus import connections
conn= connections.connect(
  alias="default", 
  host='localhost', 
  port='19530',
  user='root',
  password='Milvus',
)
```
接続成功しました。　ユーザー認証が有効になっているのが分かります。

### 5-3. rootのpassword変更
詳細: [Reset password](https://milvus.io/docs/authenticate.md#Reset-password)
milvus.yamlに`superUsers: root`を設定している場合は、現在のパスワードは不要です。
```py
from pymilvus import utility
utility.reset_password('root', '', 'P@ssword', using='default')
```
milvus.yamlに`superUsers: root`を設定がない場合は、現在のパスワードを入れます。
```py
from pymilvus import utility
utility.reset_password('root', 'Milvus', 'P@ssword', using='default')
```

### 5-4 rootのパスワード変更の確認
```py
from pymilvus import connections
conn= connections.connect(
  alias="default", 
  host='localhost', 
  port='19530',
  user='root',
  password='P@ssword',
)
```
エラーが出なければ無事変更できています。

参考までにユーザー作成は以下を参照ください:
[Create an authenticated user](https://milvus.io/docs/authenticate.md#Create-an-authenticated-user)

参考までにロール設定は以下を参照ください:
[Enable RBAC](https://milvus.io/docs/rbac.md#Enable-RBAC)

以上です。

# 参考: Milvus関連投稿
-  [M1 Mac上でcolimaを使ってベクトルDB Milvusをインストール](https://qiita.com/nishikyon/items/f529b63a1117d2f10099)

-  [Milvusのグラフィカルな管理ツール AttuをMacに導入してみた](https://qiita.com/nishikyon/items/addf2689812a2d9eb8e3)