🦩

MinIO on k8s

2022/12/13に公開

こちらは エーピーコミュニケーションズ Advent Calendar 2022 13日目の記事となります!
リンクより他の記事も宜しくお願いします。

はじめに

今回は k8s 上に MinIO をデプロイしていきます。
MinIO は S3 互換のオブジェクトストレージです。

Terraform を使うと、stateファイルの管理に困っていまして。
S3 まで大げさにアカウントや権限の設定なく内部で軽く使いたいオブジェクトストレージが無いかと探していたところ MinIO にたどり着きました。

S3 互換ということで、AWS エンジニアには馴染みの aws-cli / API での開発・検証にはもってこいかと思います。

環境情報

Kubernetes:v1.24.5
MinIO operator:v.4.5.4
kubectl Plugin:krew
aws-cli:2.9.1
※インストールは以下より
https://krew.sigs.k8s.io/docs/user-guide/setup/install/

MinIO Operator Deploy

MinIO のデプロイは Operator を通して行います。実際は kubectl のプラグインを導入してパラメータを指定するだけでデプロイできるので本当に楽です。
Operator も kubectl のプラグインからデプロイします。普段は yaml マニフェストや helm チャートでのデプロイだったので、kubectl のプラグインとして提供されるのは新鮮です。

# plugin index update
$ kubectl krew update

# install minio plugin
$ kubectl krew install minio
・・・
Installing plugin: minio
Installed plugin: minio

# version
$ kubectl minio version
v4.5.4

早速 Operator をデプロします。

# deploy minio operator
$ kubectl minio init
# --- ここからコマンドの標準出力 --- #
namespace/minio-operator created
serviceaccount/minio-operator created
clusterrole.rbac.authorization.k8s.io/minio-operator-role created
clusterrolebinding.rbac.authorization.k8s.io/minio-operator-binding created
customresourcedefinition.apiextensions.k8s.io/tenants.minio.min.io created
service/operator created
deployment.apps/minio-operator created
serviceaccount/console-sa created
clusterrole.rbac.authorization.k8s.io/console-sa-role created
clusterrolebinding.rbac.authorization.k8s.io/console-sa-binding created
configmap/console-env created
service/console created
deployment.apps/console created
-----------------

To open Operator UI, start a port forward using this command:

kubectl minio proxy -n minio-operator

-----------------
# --- ここまでコマンドの標準出力 --- #

# resources
$ kubectl get all -n minio-operator
NAME                                  READY   STATUS    RESTARTS   AGE
pod/console-5bfdb9cd77-4fwx7          1/1     Running   0          20s
pod/minio-operator-868fc4755d-5zn49   1/1     Running   0          19s
pod/minio-operator-868fc4755d-ksg8v   1/1     Running   0          20s

NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/console    ClusterIP   10.108.123.191   <none>        9090/TCP,9443/TCP   22s
service/operator   ClusterIP   10.108.165.111   <none>        4222/TCP,4221/TCP   22s

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/console          1/1     1            1           22s
deployment.apps/minio-operator   2/2     2            2           22s

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/console-5bfdb9cd77          1         1         1       21s
replicaset.apps/minio-operator-868fc4755d   2         2         2       21s

Operator では WebUI が用意されていますのでアクセスしてみます。プラグインのコマンドを使ってポートフォワードできます。

$ kubectl minio proxy
Starting port forward of the Console UI.

To connect open a browser and go to http://localhost:9090

Current JWT to login: ・・・・

Forwarding from 0.0.0.0:9090 -> 9090

kubectl port-forward と同じ要領でポート転送されます。実行した VM ・クライアントの IP で上記(ポート:9090)にアクセスします。

kubectl minio proxy コマンドを実行した際に標準出力された JWT を使ってログインします。

まだ、MinIO をデプロイしていないので、テナントが1つも無いことが確認できます。

MinIO Deploy

Operator のデプロイが確認できたところで、早速 MinIO をデプロしていきます。
こちらも MinIO のプラグインでデプロイします。
今回の MinIO の構成は以下の通りです。最低限の構成で。

  • Pod 数(--servers):3
  • ボリュームの数(--volumes):6
    ※分散されるボリュームの数
    ※1 Pod に2つ以上のボリュームが必須で、今回は 3 Pod * 2 volume = 6
  • 総容量(--capacity):3Gi
  • StorageClass:minio-storage
    ※適宜利用する PVC 先のストレージクラスに変更を。

上記の構成でデプロイします。

# create namespace
$ kubectl create ns minio-tenant-1
namespace/minio-tenant-1 created

# deploy MinIO
$ kubectl minio tenant create minio-tenant-1 \
--servers 3 \
--volumes 6 \
--capacity 3Gi \
--storage-class minio-storage \
--namespace minio-tenant-1
# --- コマンドこの上まで --- #
Tenant 'minio-tenant-1' created in 'minio-tenant-1' Namespace

# --- 以下の情報はログインの際に利用するため控えておく ---#
  Username: admin
  Password: ****
  Note: Copy the credentials to a secure location. MinIO will not display these again.

+-------------+------------------------+----------------+--------------+--------------+
| APPLICATION | SERVICE NAME           | NAMESPACE      | SERVICE TYPE | SERVICE PORT |
+-------------+------------------------+----------------+--------------+--------------+
| MinIO       | minio                  | minio-tenant-1 | ClusterIP    | 443          |
| Console     | minio-tenant-1-console | minio-tenant-1 | ClusterIP    | 9443         |
+-------------+------------------------+----------------+--------------+--------------+

# resources
$ kubectl get all -n minio-tenant-1
NAME                                                 READY   STATUS    RESTARTS      AGE
pod/minio-tenant-1-log-0                             1/1     Running   0             58s
pod/minio-tenant-1-log-search-api-74b9d5c566-c9npd   1/1     Running   3 (39s ago)   58s
pod/minio-tenant-1-ss-0-0                            1/1     Running   0             58s
pod/minio-tenant-1-ss-0-1                            1/1     Running   0             57s
pod/minio-tenant-1-ss-0-2                            1/1     Running   0             56s

NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/minio                           ClusterIP   10.103.201.45    <none>        443/TCP    119s
service/minio-tenant-1-console          ClusterIP   10.111.41.27     <none>        9443/TCP   119s
service/minio-tenant-1-hl               ClusterIP   None             <none>        9000/TCP   119s
service/minio-tenant-1-log-hl-svc       ClusterIP   None             <none>        5432/TCP   59s
service/minio-tenant-1-log-search-api   ClusterIP   10.108.212.169   <none>        8080/TCP   58s

NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/minio-tenant-1-log-search-api   1/1     1            1           59s

NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/minio-tenant-1-log-search-api-74b9d5c566   1         1         1       59s

NAME                                   READY   AGE
statefulset.apps/minio-tenant-1-log    1/1     59s
statefulset.apps/minio-tenant-1-ss-0   3/3     59s

PVC も見事に6分割されてます。

$ kubectl get pvc -n minio-tenant-1
NAME                                      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
0-minio-tenant-1-ss-0-0                   Bound    pvc-047524c8-10ac-42b4-8fd6-399b74815c3e   512Mi      RWO            minio-storage     90s
0-minio-tenant-1-ss-0-1                   Bound    pvc-83421577-9e2e-42c5-94cf-393547e63300   512Mi      RWO            minio-storage     89s
0-minio-tenant-1-ss-0-2                   Bound    pvc-5bf5824b-7f20-4b79-a745-84005d67b327   512Mi      RWO            minio-storage     88s
1-minio-tenant-1-ss-0-0                   Bound    pvc-1e1d861d-ec73-4e01-9d5b-c317796af6ae   512Mi      RWO            minio-storage     90s
1-minio-tenant-1-ss-0-1                   Bound    pvc-262bf08f-692f-4885-bfa6-baafa040374c   512Mi      RWO            minio-storage     89s
1-minio-tenant-1-ss-0-2                   Bound    pvc-1c66ea1f-dc83-4ca2-aebd-1b727357dc62   512Mi      RWO            minio-storage     88s
minio-tenant-1-log-minio-tenant-1-log-0   Bound    pvc-4661b77c-80e1-4cdf-a7a1-3378faf5836b   5Gi        RWO            rook-ceph-block   90s

コンソールアクセス

デプロイできたので早速アクセスしていきます。
まずは WebUI から。ポートフォワードでアクセスしてみます。

$ kubectl port-forward service/minio-tenant-1-console \
--address 0.0.0.0 19443:9443 \
-n minio-tenant-1

デプロイした際に標準出力されているアカウント情報でログインします。

aws コマンドで接続

今度は aws コマンドで接続してみます。
まだバケットは無いので、バケット作成から。

# アカウント情報を環境変数に
$ AWS_ACCESS_KEY_ID=XXXX(Username)
$ AWS_SECRET_ACCESS_KEY=****(Password)


# aws-cli をコンテナで実行
# 環境変数にアカウント情報を指定
# "--" 以降が実際の aws コマンド、ここでは "my-bucket" バケットを作成
$ kubectl run awscli -it --rm --image amazon/aws-cli --command \
--env=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
--env=AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-- aws --endpoint-url https://minio:443 --no-verify-ssl s3 mb s3://my-bucket
# ここまでコマンド

# 以下コマンドの出力
If you don’t see a command prompt, try pressing enter.
# 以下エラーは無視で。
urllib3/connectionpool.py:1045: InsecureRequestWarning: Unverified HTTPS request is being made to host 'minio'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
# 作成成功の出力
make_bucket: my-bucket
# Pod 削除の出力
Session ended, resume using 'kubectl attach awscli -c awscli -i -t' command when the pod is running
pod "awscli" deleted

作成できたので、バケット一覧を確認してみます。

$ kubectl run awscli -it --rm --image amazon/aws-cli:2.9.1 --command \
--env=AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
--env=AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
-- aws --endpoint-url https://minio:443 --no-verify-ssl s3 ls
# ここまでコマンド
# 以下、前述の不要な内容を省略した出力
2022-11-25 15:34:16 my-bucket

WebUI でもバケットが確認できます。

まとめ

MinIO で簡単 S3 互換のオブジェクトストレージが準備できました。
S3 でバケットを用意しても良いのですが、内部で IAM やバケットポリシーを気にせずに試せるので気軽に使えるかと思います。大量のファイルをアップロードするわけでは無いので、Terraform の State ファイルであればこれで十分かと思います。
別で MinIO を使った Terraform も試せればと思います。

参考

https://github.com/minio/operator
https://docs.min.io/minio/k8s/deployment/deploy-minio-operator.html
https://docs.min.io/minio/k8s/tenant-management/deploy-minio-tenant.html

Discussion