(2021/5/18 追記) Operator のインストールしかしてないじゃん、ってことでタイトル変更しました。 実際に Operator で構築した Minio を試して、続編として投稿したいと思います。
前回の投稿から 3 ヶ月ほど空いてしまいました。
その間に、誕生日に Japan Rook Meetup で登壇したり…
本日の登壇資料です。改めてありがとうございました! #japanrookhttps://t.co/WZzoEYEnku
— ののし (@nnstt1) April 2, 2021
CKA (Certified Kubernetes Administrator) の資格を取ったり…
CKA 受かりました!俺たちの Kubernetes はこれからだ!完 pic.twitter.com/ivkWe9FxzG
— ののし (@nnstt1) May 3, 2021
したのですが、まったくブログにアウトプットできてませんでした。
現在は CKAD (Certified Kubernetes Application Developer) に向けて勉強中なのですが、裏で MinIO Operator を触ってみたので気晴らしに久しぶりの投稿をします。
MinIO とは
MinIO は、Amazon S3 互換のオープンソースオブジェクトストレージです。
MinIO | Enterprise Grade, High Performance Object Storage
プライベート/ハイブリッドクラウドの標準オブジェクトストレージとなることを前提とした設計のようです。
そのためか、公式サイトではファイルシステムやブロックストレージには結構キツい物言いをしている感じがします(個人の感想です)。
ハイブリッドクラウドストレージは、パブリッククラウドで確立されたモデルに従い、パブリッククラウドプロバイダーは全会一致でクラウドネイティブオブジェクトストレージを採用しています。
パブリッククラウドの成功により、ファイルとブロックストレージは事実上時代遅れになりました。
すべての新しいアプリケーションは、POSIXではなくAWS S3API用に作成されています。
クラウドネイティブテクノロジーのようにスケーリングして実行するには、古いアプリケーションをS3 API用に書き直し、コンテナ互換になるようにマイクロサービスにリファクタリングする必要があります。
また、かつて Rook (v1.2)でもストレージプロバイダとして MinIO が対象となっていたのですが、残念ながら現在は対象外となってしまったようです。
minio: remove from rook · rook/rook@9a078bf
ちなみに、MinIO の読み方は「ミン・アイオー」のようです(ミニオって言ってしまってました…)。
MinIO(1) 概要とRookを使ったデプロイ方法 - Qiita
MinIO Operator
そんな MinIO を Kubernetes にデプロイして運用までしてくれる MinIO Operator がリリースされたようです。
MinIO adds mainstream object storage management features – Blocks and Files
今回は公式リポジトリの手順に沿って MinIO Operator をインストールして、オブジェクトを格納するためのテナントを作成するところまで試してみます。
minio/operator: MinIO Operator creates/configures/manages MinIO clusters on Kubernetes
前提条件
MinIO Operator のインストール、およびテナント作成の前提条件は以下の 4 つです。
-
Kubernetes クラスタのバージョンが 1.17.0 以上であること
1.17.0 未満だったら Kubernetes 公式を参照してアップグレードします。
今回使用したクラスタは v1.21.0 のため、そのまま使用します。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:31:21Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.0", GitCommit:"cb303e613a121a29364f75cc67d3d580833a7479", GitTreeState:"clean", BuildDate:"2021-04-08T16:25:06Z", GoVersion:"go1.16.1", Compiler:"gc", Platform:"linux/amd64"}
-
Kubernetes クラスタに MinIO テナント用の namespace があること
MinIO Operator はテナント毎に namespace を使用します。
今回は検証用の
minio-tenant-1
namespace を作成します。
$ kubectl create namespace minio-tenant-1
namespace/minio-tenant-1 created
-
Kubernetes クラスタに
volumeBindingMode: WaitForFirstConsumer
の StorageClass があることMinIO Operator は
volumeBindingMode: WaitForFirstConsumer
の StorageClass にデータを格納します。 今回使用する Kubernetes クラスタには Rook/Ceph が導入済みのため、Rook/Ceph を使って MinIO Operator 用の StorageClass を作成します。
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
name: minio-pool
namespace: rook-ceph
spec:
failureDomain: host
replicated:
size: 3
requireSafeReplicaSize: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: minio-rook-ceph-block
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
-
Krew がインストールされていること
MinIO Operator は kubectl コマンドラインツールの
Krew
を使用してインストールします。以下のサイトを参照して Krew をインストールします。
インストール
Krew を使って MinIO Operator をインストールしていきます。
$ kubectl krew update
Updated the local copy of plugin index.
$ kubectl krew install minio
Updated the local copy of plugin index.
Installing plugin: minio
Installed plugin: minio
\
| Use this plugin:
| kubectl minio
| Documentation:
| https://github.com/minio/operator/tree/master/kubectl-minio
| Caveats:
| \
| | * For resources that are not in default namespace, currently you must
| | specify -n/--namespace explicitly (the current namespace setting is not
| | yet used).
| /
/
WARNING: You installed plugin "minio" from the krew-index plugin repository.
These plugins are not audited for security by the Krew maintainers.
Run them at your own risk.
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
-----------------
上記出力の通り、proxy 経由で MinIO Operator の管理画面にアクセスできるようになります。
$ kubectl minio proxy -n minio-operator
Starting port forward of the Console UI.
To connect open a browser and go to http://localhost:9090
Current JWT to login: eyJhbGciOiJSUzI1NiIsImtpZCI6Ii0zbFc4cm51LXNPTWliSUVOYXdTNmI3ejRWeWRuVEF0dU9aenpKY0xaNGMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJtaW5pby1vcGVyYXRvciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjb25zb2xlLXNhLXRva2VuLWJmNDZyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNvbnNvbGUtc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3ZDgwZDNjOS0wMzUyLTRjNDItOWQ5Yy0xM2I3ZDg2ZjA4OWIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bWluaW8tb3BlcmF0b3I6Y29uc29sZS1zYSJ9.F8XsI2buT71U4QUi7tfShaDYAOs0rcgjPmZO5HiJYyWYZ0ZYN5LDZbIRf4il23CGRjGVUWksKsfeUqRFD0iG2lP21WxvTgIbUov3DbZtItB3Sj1dO4xI5WH7PLjyYAyE5eYGRQwd3K0qSpaexh4cKsG8vj5pxzd8g-f6vwWjE1Co7Ax83PzP_ATmNnOWVQE-6lI287QijtH-PfdK3UEHM1d1WU67yvei0YGLTyMgC3t6F8xKwqay0B2OLEUGirDcq74xZA5qB_Ipuvys5K05nOCKbQiWujv0J_gyyaEAwszRpGc4Gy8Mrc-bhAYe7EGLh8_BoQiwJ2d4UVcBEuEmmw
Forwarding from 0.0.0.0:9090 -> 9090
ブラウザで kubectl minio proxy
コマンドを実行しているサーバにアクセスするとログイン画面が表示されるので、コマンド実行時に出力された文字列を入力してログインします。
テナント作成
次に、MinIO Operator を使ってテナントを作成します。
デプロイされる Pod やストレージサイズを指定するオプションがあるのですが、クラスタと相談のうえ設定してください。
$ kubectl minio tenant create minio-tenant-1 \
--servers 1 \
--volumes 4 \
--capacity 4Gi \
--namespace minio-tenant-1 \
--storage-class minio-rook-ceph-block
Tenant 'minio-tenant-1' created in 'minio-tenant-1' Namespace
Username: admin
Password: ac8a676c-d4a3-4cb0-98b9-c432f3c9cd5c
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 |
+-------------+------------------------+----------------+--------------+--------------+
これでオブジェクトを格納するためのテナントが完成しました。
自分の環境では、テナントを正常に作成できた状態では以下のリソースが作られていました。
$ kubectl get secret -n minio-tenant-1
NAME TYPE DATA AGE
default-token-ntlzm kubernetes.io/service-account-token 3 2m24s
minio-tenant-1-console-secret Opaque 4 2m22s
minio-tenant-1-console-tls Opaque 2 62s
minio-tenant-1-creds-secret Opaque 2 2m22s
minio-tenant-1-tls Opaque 2 2m2s
operator-tls Opaque 1 2m17s
operator-webhook-secret Opaque 3 2m17s
$ kubectl get pods -n minio-tenant-1
NAME READY STATUS RESTARTS AGE
minio-tenant-1-console-6b7488946f-2mvkf 1/1 Running 0 2m43s
minio-tenant-1-console-6b7488946f-6djht 1/1 Running 0 2m43s
minio-tenant-1-ss-0-0 1/1 Running 0 3m43s
$ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
minio-tenant-1-console-minio-tenant-1-csr 17s kubernetes.io/legacy-unknown system:serviceaccount:minio-operator:minio-operator Approved,Issued
minio-tenant-1-minio-tenant-1-csr 77s kubernetes.io/legacy-unknown system:serviceaccount:minio-operator:minio-operator Approved,Issued
operator-minio-operator-csr 4m5s kubernetes.io/legacy-unknown system:serviceaccount:minio-operator:minio-operator Approved,Issued
$ kubectl get tenant -n minio-tenant-1
NAME STATE AGE
minio-tenant-1 Initialized 4m43s
ちなみに、--volumes
が 4 未満だった場合、エラーとなります。
$ kubectl minio tenant create minio-tenant-1 \
--servers 1 \
--volumes 3 \
--capacity 3Gi \
--namespace minio-tenant-1 \
--storage-class minio-rook-ceph-block
Error: pool #0 setup must have a minimum of 4 volumes per server
サーバ 1 台につき 4 ボリュームが必要なようです。
注意点
テナント作成時にユーザ情報が表示されますが、このとき表示される Password は再度表示することができないので、必ず控えておいてください。
また、万人に該当する注意点ではないかもですが、自分の環境では Operator の処理が遅く、上記のユーザ情報が表示されたあともテナントに必要なリソースがすべてデプロイされていませんでした。
厳密に言うと、minio-tenant-1-tls
Secret が作成されなかったため、Secret をマウントできずに Pod が起動してきませんでした。
原因は不要な CSR リソースが存在していたことで、テナント作成時にデプロイされるべき CSR リソースがすでに存在していたため、minio-tenant-1-tls
Secret が作成されなかったのだと推測しています。
この不要な CSR リソースは、テナント作成時のオプションを失敗して何度かテナント作成をやり直していたことで残っていたと思われます。
テナントを作成する際には CSR リソースも確認しておいたほうが良さそうです。
外部公開用サービス
ここまでの手順では Kubernetes クラスタ外のアプリケーションから MinIO テナントに接続するサービスがデプロイされていません。 そのため、Ingress や Load Balancer が必要です。
今回は MinIO テナント用の Load Balancer を作成します。
クラスタには MetalLB と ExternalDNS をデプロイ済みで、LoadBalancer を作成するとクラスタ外から接続可能な IP アドレスが振られて、 クラスタ外の DNS にレコードを登録してくれます。
外部から接続するサービスは minio
と console
の 2 種類があります。
MinIO
こちらは実際にオブジェクトストレージを操作するための API と GUI を提供するサービスです。
テナント作成時に表示された admin ユーザでログインします。
apiVersion: v1
kind: Service
metadata:
namespace: minio-tenant-1
name: minio-loadbalancer
labels:
component: minio-tenant-1
annotations:
external-dns.alpha.kubernetes.io/hostname: minio-tenant-1.nnstt1.work. # ExternalDNS 用アノテーション
spec:
type: LoadBalancer
ports:
- port: 9000
targetPort: 9000
protocol: TCP
selector:
v1.min.io/tenant: minio-tenant-1
Console
こちらは MinIO Operator と同時にリリースされた MinIO Console という管理ツールです。
テナントの管理や状態監視をおこなえます。 ログインは同じく admin ユーザを使用します。
ログインすると管理ポータルが表示されます。
apiVersion: v1
kind: Service
metadata:
namespace: minio-tenant-1
name: console-loadbalancer
annotations:
external-dns.alpha.kubernetes.io/hostname: minio-console.nnstt1.work. # ExternalDNS 用アノテーション
spec:
type: LoadBalancer
ports:
- name: https-console
port: 9443
protocol: TCP
targetPort: 9443
selector:
v1.min.io/console: minio-tenant-1-console
アンインストール
作成したテナントを削除し、MinIO Operator をアンインストールしてみます。
テナント削除も MinIO Operator アンインストールも kubectl minio
コマンドを使用します。
テナント
kubectl minio tenant delete
で削除するテナントを指定します。
ここで指定する tenant リソースは namespace 毎に作成されるため、-n
オプションで対象の namespace を指定してください。
# テナント削除
$ kubectl minio tenant delete minio-tenant-1 -n minio-tenant-1
This will delete the Tenant minio-tenant-1 and ALL its data. Do you want to proceed?: y
Deleting MinIO Tenant minio-tenant-1
Deleting MinIO Tenant Credentials Secret minio-tenant-1-creds-secret
Deleting MinIO Tenant Console Secret minio-tenant-1-console-secret
# namespace 確認
$ kubectl get pods -n minio-tenant-1
No resources found in minio-tenant-1 namespace.
$ kubectl get secret -n minio-tenant-1
NAME TYPE DATA AGE
default-token-swx2m kubernetes.io/service-account-token 3 2d
MinIO Operator
kubectl minio delete
で MinIO Operator がアンインストールされます。
$ kubectl minio delete
Are you sure you want to delete ALL the MinIO Tenants and MinIO Operator?: y
namespace "minio-operator" deleted
serviceaccount "minio-operator" deleted
clusterrole.rbac.authorization.k8s.io "minio-operator-role" deleted
clusterrolebinding.rbac.authorization.k8s.io "minio-operator-binding" deleted
customresourcedefinition.apiextensions.k8s.io "tenants.minio.min.io" deleted
service "operator" deleted
deployment.apps "minio-operator" deleted
serviceaccount "console-sa" deleted
clusterrole.rbac.authorization.k8s.io "console-sa-role" deleted
clusterrolebinding.rbac.authorization.k8s.io "console-sa-binding" deleted
configmap "console-env" deleted
service "console" deleted
deployment.apps "console" deleted
アンインストールはあっさりですね。
おわりに
今回は Amazon S3 互換のオブジェクトストレージ MinIO の オペレータ MinIO Operator
を試してみました。
MinIO 自体、Kubernetes にとても簡単にデプロイできるため Operator が活躍する場面はまだ見えてませんが、 そもそも MinIO を使い込んでいないので、色々試してみようと思います。
本来は Operator は簡単にインストールできるのですが、注意点の節でも述べた CSR リソースの件でかなり時間を持っていかれました。 なかなか思うようにできないですね。 だけど、今回の件で CSR リソースのことを注意するようになったのでヨシ!
全然関係ないですが、MinIO のロゴってかっこいいですよね。フラミンゴかな?