MinioをK3SでStandaloneモードで動かす(NodePort編)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

皆さんも、ちょっとS3互換のストレージ(ファイル置き場)が欲しいなと思ったことありますよね。
AWS S3を使うのもいいのですが、社内で使うだけだし、外部のトラフィックを使う事もないよなぁ、キャッシュ目的で使うだけだしなぁ、と思ったことが一度や二度ではないはずです。

そこで簡単にMinioをインストールしようとしたのですが、ググっても出てきたのはMinio Operatorを使って大規模にデリバリーする話ばかりでした。別に1台2台から接続するだけなので複数で分散させずにStandaloneモードで動かせばいいし、Diskの冗長化も必要ないし、メモリーも最小限で動かしたかったのですが情報がありませんでした。
そんな皆さんのために、K3S上でMinioをサクッとお手軽に動かそうというお話です(※)。
今回はIngressは使用せずNodePortで動かしますので、K3SじゃないKubernetesでも普通に利用できると思います。

※注:一般的にはDockerで動かす方が楽だと思います。

注意！！！
**Standaloneモードで動かして、K3Sもシングルノードと冗長性がないのでマシンが失われるとデータも失われます。
これらのリスクを理解した上でご利用ください。**


# 1. K3Sを動かす仮想マシンを用意する

K3Sを動かす仮想マシンを用意します。VMwareでもいいですし、VirtualboxやHyper-Vでもいいですね。
x86_64の仮想マシンであれば何でもいいです。今回は、Ubuntuのmultipassを使って仮想マシンを用意しました。
CPUを4、メモリーを4GB、Diskを20GBとしました。

```bash
$ multipass launch 20.04 
  --name k3s-minio \
  -c 4 -m 4g -d 20g \
  --network name=br0,mode=manual
```

NICはブリッジモードで用意しました。multipassでブリッジモードで仮想マシンを起動する方法については、 「
[Ubuntu 20.04でMultipassをブリッジネットワークで動かす(Ver1.7.0)](https://qiita.com/ynott/items/01e2913539c664b6559d) 」をご参照ください。

IPアドレスは、192.168.1.10にしました。

# 2. K3Sを仮想マシンにインストールする

K3Sをインストールするには、k3supを使うのが便利なのでこいつを使います。

```bash
$ k3sup install --ip 192.168.1.10 \
  --user ubuntu \
  --ssh-key ~/.ssh/multipass-ssh-key_id_rsa 
```

k3supについては、「 [k3supを使ってk3sをインストールする](https://qiita.com/ynott/items/25df249040ceb7430c3f)」 をご参照ください。multipassのSSH鍵は~/.ssh/以下にコピーしておきましょう。

kubectlコマンドをインストールして、K3Sに接続できるか確認しておきます。

```bash
$ sudo snap install kubectl --classic
$ export KUBECONFIG=./kubeconfig
$ kubectl get node
```

# 3. helmコマンドをインストールする

minioは、helmコマンドでインストールしますのでこれを用意します。Ubuntuの場合は、snapとかでインストールするのが楽でいいでしょう。

```bash
$ sudo snap install helm --classic
```

# 4. Minioをインストール
## 4-1. Minioをhelmに追加

helm repoにminioを追加します。
ついでにインストールできるバージョンなども以下のコマンドで確認しておきます。

```
$ helm repo add minio https://operator.min.io/ 
$ helm repo update
$ helm search repo minio/minio --versions
```

## 4-2. K3SにMinioをインストール

以下のHelmコマンドでminioを`Standaloneモード` で動かします。
StorageClassはK3Sに組み込みの`local-path`を使います。
namespaceは、`minio`が自動的に作られます。
メモリー(resources.requests.memory)がデフォルトだと16GiBになって動かないので`512MiB`まで減らしています。
ファイル領域(persistence.size)は、デフォルトだと500GiBなので`10GiB`まで減らしています。
外部から接続するためにnodePortを`32000`に設定しています。

```bash
$ helm install minio \
  --namespace minio --create-namespace \
  --set accessKey=minio,secretKey=minio123 \
  --set mode=standalone \
  --set service.type=NodePort \
  --set service.nodePort=32000 \
  --set persistence.enabled=true \
  --set persistence.size=10Gi \
  --set persistence.storageClass=local-path \
  --set resources.requests.memory=512Mi \
   minio/minio
```

上記の値は各自調整してください。
以下のようなHelmコマンド実行結果が返ります。

```bash
NAME: minio 
LAST DEPLOYED: Fri Dec 17 21:37:45 2021 
NAMESPACE: minio 
STATUS: deployed 
REVISION: 1 
TEST SUITE: None 
NOTES: 
MinIO can be accessed via port 9000 on the following DNS name from within your cluster: 
minio.minio.svc.cluster.local 
To access MinIO from localhost, run the below commands: 
  1. export POD_NAME=$(kubectl get pods --namespace minio -l "release=minio" -o jsonpath="{.items[0].metadata.name}") 
  2. kubectl port-forward $POD_NAME 9000 --namespace minio 
Read more about port forwarding here: http://kubernetes.io/docs/user-guide/kubectl/kubectl_port-forward/ 
You can now access MinIO server on http://localhost:9000. Follow the below steps to connect to MinIO server with mc client: 
  1. Download the MinIO mc client - https://docs.minio.io/docs/minio-client-quickstart-guide 
  2. export MC_HOST_minio-local=http://$(kubectl get secret minio -o jsonpath="{.data.rootUser}" | base64 --decode):$(kubectl get secret minio -o jsonpath="{.data.rootPassword }" | base64 --decode)@localhost:9000 
  3. mc ls minio-local
```

# 5. minioへ接続確認
## 5-1. curlコマンドで接続テスト

手始めに簡単に接続テストしてみます。nodePortへcurlコマンドで接続すれば返事が返ってくるはずです。
以下のように`Access Denied`が帰ってくればMinioとしては動いています。
もし何も返ってこない場合はPodが起動していないか、ポート番号を間違えています。
ログを確認してみてください。

```bash
$ curl http://192.168.1.10:32000/
<?xml version="1.0" encoding="UTF-8"?> 
<Error><Code>AccessDenied</Code><Message>Access Denied.</Message><Resource>/</Resource><RequestId>16C1CCED7D6A1F39</RequestId><HostId>16ab49cc-c8a2-472c-a62b-d 
d0f007f73e6</HostId></Error>
```

## 5-1. mcコマンドをインストール

minioへ接続テストするためにmcコマンドをインストールします(間違えてMidnightCommanderをインストールしないように(間違えたのは私だ))。ちょっと接続テストするだけなのでホームディレクトリに仮置きします。

```bash
$ sudo apt install wget
$ mkdir ~/bin/ && pushd ~/bin/
$ wget https://dl.min.io/client/mc/release/linux-amd64/mc
$ chmod +x mc
```

## 5-2. mcコマンドで接続先を設定

mcコマンドで接続先を設定する前にrootユーザーとrootパスワードを読み込みます。

Rootユーザーを以下で取得

```bash
$ kubectl get secret minio -n minio -o jsonpath="{.data.rootUser}" | base64 --decode
NQ9GSSz2oXH1yhAGfOl6
```

Rootユーザーパスワードを以下で取得

```bash
$ kubectl get secret minio -n minio -o jsonpath="{.data.rootPassword}" | base64 --decode
Ld70XU5GT0HGahqhahqvnHe8bxrHDWBpaBDHMqpc
```

上記のRootユーザーとパスワードを使って登録します。登録名を`localminio`とします。
接続先は、IP:Portの形式で記載します。

```bash
$ ./mc alias set localminio http://192.168.1.10:32000 NQ9GSSz2oXH1yhAGfOl6 Ld70XU5GT0HGahqhahqvnHe8bxrHDWBpaBDHMqpc
Added `localminio` successfully.
```

`Added ~~~ successfully`と出ればOKです。 

## 5-3. バケットを作成

登録したのでバケットを作っておきます。

```bash
$ ./mc mb localminio test-1
```

バケットができたか確認します。

```bash
$ ./mc ls localminio/
[2021-12-12 18:32:40 JST]     0B test-1/
```

後は、S3と同じように利用できます。

# 6. まとめ

サクッとMinioをK3S上で稼働させました。
外部から接続するためにNodePortにしましたが、Kubernetes内からしか使わないのであれば、`ClusterIP`で良いかと思います。