🥋

k8s-csi-s3 を使ってストレージを節約する

2024/05/02に公開

はじめに

kubernetes を個人で利用する際にコストに影響してくるのがストレージですね。特にクラウドサービス等では1度に作れるストレージの最小サイズが決められており、またそのストレージを分割して使うという使い方も出来なかったりします。
helm でインストールする様なアプリケーションでは PVC (PersistentVolumeClaim) により確保されるストレージサイズが個別に決められる事が多いのですが、そうするとそのたびにストレージが最小サイズで作られてしまいます。僕がお借りしている Oracle Cloud もブロックボリュームの最小単位が 50Gi なので、helm で oci-bv ストレージクラスを使う物があれば PVC の require を越えて 50Gi のブロックボリュームが作られてしまいます。

そこで k8s-csi-s3

そこで便利なのが miniok8s-csi-s3 です。

minio は S3 互換のストレージシステムで、k8s-csi-s3 は S3 をディスクストレージかの様にマウントしてしまう CSI ドライバです。kubernetes クラスタ内に minio を建て、そのバケットの一部をマウントしつつアプリケーションのストレージとして利用できる訳です。

インストール方法

minio のインストール方法は調べて下さい。k8s-csi-s3 を利用するには StorageClass を作る必要があります。

storageclass.yaml
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: csi-s3
provisioner: ru.yandex.s3.csi
parameters:
  mounter: geesefs
  # you can set mount options here, for example limit memory cache size (recommended)
  options: "--memory-limit 1000 --dir-mode 0777 --file-mode 0666"
  # to use an existing bucket, specify it here:
  #bucket: some-existing-bucket
  bucket: manualbucket
  csi.storage.k8s.io/provisioner-secret-name: csi-s3-secret
  csi.storage.k8s.io/provisioner-secret-namespace: kube-system
  csi.storage.k8s.io/controller-publish-secret-name: csi-s3-secret
  csi.storage.k8s.io/controller-publish-secret-namespace: kube-system
  csi.storage.k8s.io/node-stage-secret-name: csi-s3-secret
  csi.storage.k8s.io/node-stage-secret-namespace: kube-system
  csi.storage.k8s.io/node-publish-secret-name: csi-s3-secret
  csi.storage.k8s.io/node-publish-secret-namespace: kube-system

k8s-csi-s3 には PVC 毎にバケットを作る方法と、ルートバケットを用意してその中に pv-xxx のディレクトリを作る方法の2つがあります。僕は好みでルートバケットがあった方が良かったのでそっちにしています。あとは csi-s3-secret という認証情報を作ります。

csi-s3.yaml
apiVersion: v1
kind: Secret
metadata:
  namespace: kube-system
  name: csi-s3-secret
stringData:
  accessKeyID: "YYYYYYYYYYYYYYYYY"
  secretAccessKey: "XXXXXXXXXXXXXXXXXXXXXXXXXX"
  endpoint: "http://10.XX.XX.XX" # minio のエンドポイント

namespace や credentials、あとは minio のエンドポイントはご自分の物を設定して下さい。最後に helm の values 等から storageclass を csi-s3 として指定してあげれば、指定のボリュームが S3 上に確保されます。

 persistence:
  type: pvc
  enabled: true
  # storageClassName: default
  storageClassName: csi-s3
  accessModes:
    - ReadWriteOnce
  size: 10Gi
  # annotations: {}
  finalizers:
    - kubernetes.io/pvc-protection

ちなみにファイルシステムとして利用するアプリケーションのアクセス頻度に従って S3 に API 呼び出しが行われるので、個人であれば Amazon S3 等を利用するよりクラスタ内に minio を建ててしまう方が安心です。

使い物になるか

いろいろ試した感じですが、prometheus や grafana が扱うストレージ程度であれば十分使えます。uptime-kuma のストレージに使っても問題無かったです。
ただし wordpress のストレージに使うと、ウェブサイトを表示する度に S3 にアクセスが行われるため、動きはするけど使い物にはなりませんでした。

おわりに

kubernetes クラスタ内に S3 互換ストレージシステム minio を建て、そのバケットを PVC として使う事で helm インストールするアプリケーションのストレージを節約する方法を紹介しました。
使い物にならないかなと思っていたのですが、個人利用の範囲ではほぼ問題が起きなくて体験が良かったです。またコンテナが出力したファイルに S3 経由でアクセス出来るためアプリ情報のバックアップを得るのも非常に簡単でした。

Discussion