7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kubernetes: CSI を使ったEphemeral Volumeの動作検証

Last updated at Posted at 2021-06-29

はじめに

本検証では、CSI を使った Ephemeral Volume として Kubernetes v1.16 で Beta となったCSI Ephemeral Volume と、Kubernetes v1.21 で Beta となった Generic Ephemeral Volume について検証を行い、その違いを示します。

Ephemeral Volume とは

Ephemeral とは「儚い、短命な」という意味です。これに対して Persistent は「永続的な」という意味です。つまり、Ephemeral Volume とはデータの永続化を目的としたものでなく、一時的なデータの保存を目的としたボリュームになります。
Kubernetes においては、Pod のライフタイムに従い、Podと共に作成/削除されるボリュームを指します。
Kubernetes では、以下の種類のEphemeral Volumeをサポートしています(こちらを参考)。

  • emptyDir
    • kubelet のベースディレクトリ又はRAM(メモリ)から空の領域をPodへボリュームとして割り当てます
    • データはkubeletが稼働しているノード上に格納されます
  • configMap, downwardAPI, secret
    • KubernetesのリソースをPodへボリュームとして割り当てます
  • CSI Ephemeral Volume (※)
    • 特定のCSI Driver を通じ作成されるボリュームをPodへ割り当てます
    • データはCSI Driverのターゲットとなるストレージに格納されます
  • Generic Ephemeral Volume
    • 通常のPVC/PVの仕組み(Dynamic Provisionig)を使い作成されるボリュームをPodへ割り当てます
    • データはCSI Driverのターゲットとなるストレージに格納されます

上記に示すように、CSI Ephemeral Volume と Generic Ephemeral Volume は、emptyDir と異なり、ノードのメディアやRAM上の保存するのではなく、CSI Driverのターゲットとなるストレージに保存されます。
そのため、ノードのメディア(SSD/HDD)やRAMの容量を超えるサイズのデータを保存できます。
CSI Ephemeral Volume と Generic Ephemeral Volume の違いについては、以下の動作検証を通じ紹介します。

※ CSI Ephemeral Volumeは、以前 CSI Inline Volume と呼ばれていたこともあり、各種 CSI Driver のドキュメントでは Inline Volume と記載されていることがあります。

動作検証

CSI Ephemeral Volume と Generic Ephemeral Volume の動作検証を行います。

検証環境

  • minikube v1.19.0
    • Kubernetes v1.21.0
  • CSI Driver: csi-driver-host-path

動作検証

事前準備 (csi-driver-host-path のセットアップ)

minikubeを使いKubernetes v1.21.0を--feature-gates=CSIVolumeHealth=true を指定し立ち上げます。

$ minikube start --vm-driver=virtualbox --kubernetes-version=1.21.0 

minikubeによりKubernetes v1.21.0が起動したことを確認します。
次に、Volume Health Monitorに対応しているcsi-driver-host-pathをセットアップします。

$ git clone git@github.com:kubernetes-csi/csi-driver-host-path.git
$ cd csi-driver-host-path/
$ deploy/kubernetes-latest/deploy.sh
...
error: unable to recognize "/Users/ysakashi/code/golang/src/github.com/kubernetes-csi/csi-driver-host-path/deploy/kubernetes-latest/snapshotter/csi-hostpath-snapshotclass.yaml": no matches for kind "VolumenapshotClass" in version "snapshot.storage.k8s.io/v1"

VolumenapshotClassでエラーが出ますが、今回はVolumenapshot関連のリソースをデプロイしていないため、無視します。
csi-driver-host-pathのPodが起動していることを確認します。

$ kubectl get pod 
NAME                   READY   STATUS    RESTARTS   AGE
csi-hostpathplugin-0   8/8     Running   0          30m
...

次に、StorageClassをセットアップします。

$ kubectl apply -f examples/csi-storageclass.yaml 
storageclass.storage.k8s.io/csi-hostpath-sc created 

$ kubectl get sc
NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-hostpath-sc      hostpath.csi.k8s.io        Delete          Immediate           true                   32m
standard (default)   k8s.io/minikube-hostpath   Delete          Immediate           false                  46m

CSI Ephemeral Volume の動作検証

まず、CSI Ephemeral Volume の動作検証を行います。
CSI Ephemeral Volume は、これをサポートしている CSI Driver でしか利用できません。
既に使われている CSI Driver がサポートしているかは、csidrivers リソースの Mode を確認してください。

$ kubectl get csidrivers.storage.k8s.io 
NAME                  ATTACHREQUIRED   PODINFOONMOUNT   STORAGECAPACITY   TOKENREQUESTS   REQUIRESREPUBLISH   MODES                  AGE
hostpath.csi.k8s.io   true             true             false             <unset>         false               Persistent,Ephemeral   49m

Mode にEphemeralがない(Persistentのみの)CSI Driver は CSI Ephemeral Volume は利用できません。
また、Kubernetes CSI Developer Document/Drivers に記載の表の"Persistence (Beyond Pod Lifetime)" の列でも Ephemeral をサポートしているか否かを確認できます。

以下に CSI Ephemeral Volume を使ったManifest(inline.yaml)を示します。

  • inline.yaml
kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
      - mountPath: "/data"
        name: my-csi-inline-vol
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-csi-inline-vol
      csi:
        driver: hostpath.csi.k8s.io

spec.volumes.csi.driver に CSI Driver 名を記載します。
これにより、Pod の作成/削除時に、指定された CSI Driver へ Volume の作成/削除のリクエストが飛びます。

inline.yaml をデプロイします。

$ kubectl apply -f inline.yaml 
pod/my-csi-app created

$ kubectl get pod,pvc,pv
NAME                       READY   STATUS    RESTARTS   AGE
...
pod/my-csi-app             1/1     Running   0          28s

csi-driver-host-path の CSI Ephemeral Volume では、PVC/PV は作成されません。
kubectl describe コマンドで確認します。

$ kubectl describe pod my-csi-app 
...
Volume:
  my-csi-inline-vol:
    Type:              CSI (a Container Storage Interface (CSI) volume source)
    Driver:            hostpath.csi.k8s.io
    FSType:            
    ReadOnly:          false
    VolumeAttributes:  <none>
...

上記のように、my-csi-inline-vol として Type: CSI の Volume がマウントされているのが確認できます。
Pod のコンテナに入り確認すると /data にマウントされているのがわかります。

$ kubectl exec -ti my-csi-app -- mount |grep '/data'
tmpfs on /data type tmpfs (rw,relatime,size=5357132k)

csi-driver-host-path では、tmpfs を割り当てる実装となっていますが、外部ストレージを利用する CSI Driver の場合は、外部ストレージ上に Volume が作成されコンテナにマウントされます。
Pod を削除します。

$ kubectl delete pod my-csi-app 
pod "my-csi-app" deleted

Pod の削除と共に、Volume も削除されます。
csi-driver-host-path では mock device で実際に Volume が削除されたかを確認出来ないため、ここでは割愛します。

Generic Ephemeral Volume の動作検証

次に、Generic Ephemeral Volume の動作検証を行います。
Generic Ephemeral Volume は Dynamic Provisioningをサポートしている CSI Driver で利用できます。
言い換えると、Generic Ephemeral Volume は、CSI Ephemeral Volumeとは異なり、csidrivers リソースの Mode が PersistentのみのCSI Driver でも利用できます。
また、Kubernetes CSI Developer Document/Drivers の "Dynamic Provisioning" の列でも確認できます。

以下に、Generic Ephemeral Volume を使ったManifest(generic.yaml)を示します。

  • generic.yaml
kind: Pod
apiVersion: v1
metadata:
  name: my-app
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
      - mountPath: "/data"
        name: generic-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: generic-volume
      ephemeral:
        volumeClaimTemplate:
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: csi-hostpath-sc
            resources:
              requests:
                storage: 1Gi

spec.volumes.ephemeral.volumeClaimTemplate に、PVC のテンプレートとなる内容を記載します。これにより Pod の作成/削除時に、volumeClaimTemplate に従い PVC が作成/削除されます。

generic.yaml をデプロイします。

$ kubectl apply -f generic.yaml 
pod/my-app created

$ kubectl get pod,pvc,pv
NAME                       READY   STATUS    RESTARTS   AGE
...
pod/my-app                 1/1     Running   0          16s

NAME                                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
persistentvolumeclaim/my-app-generic-volume   Bound    pvc-57a8431b-9afd-4c53-addc-34615c95e03d   1Gi        RWO            csi-hostpath-sc   16s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                           STORAGECLASS      REASON   AGE
persistentvolume/pvc-57a8431b-9afd-4c53-addc-34615c95e03d   1Gi        RWO            Delete           Bound    default/my-app-generic-volume   csi-hostpath-sc            16s

Podの作成と共にPVCが作成され、Dynamic Provisioning により PVC に Bound される PV が自動生成後、Pod にマウントされます。
この PVC/PV、Podへのマウントの処理は、通常のPersistent Volume と同じです。
次に、Pod を削除します。

$ kubectl delete pod my-app 
pod "my-app" deleted

$ kubectl get pvc,pv
No resources found

Pod が削除されると、併せて PVC/PV も削除されます。
通常のPersistent Volume だと、Podが削除されてもPVC/PV は削除されませんが、Generic Ephemeral Volume では Pod の削除と連動し削除されます。

感想

今回は永続ボリューム(Persistent Volume)ではなく、短命なボリューム(Ephemeral Volume) について、動作検証を行いました。
検証により動作はわかったものの、次の2点が気になる人も多いのではないでしょうか。

  1. CSI Ephemeral Volume, Generic Ephemeral Volume のユースケース
  2. CSI Ephemeral Volume と Generic Ephemeral Volume のどちらを使うべきか?

1点目のユースケースを考えるにあたり、ポイントはノードのリソースを使う emptyDir よりも大きなデータを扱うシーンではないでしょうか。
さらに、Ephemeral Volumeのため、Podのライフサイクルに併せて使われる一時的なデータの保存領域が必要なユースケースが対象となります。
一例としては、以下のようなユースケースにマッチするのではないでしょうか

  • 画像処理や音声処理のように、中間データを出力するアプリケーション
    • 入力データと最終的な出力データは永続ボリュームに保存するが、処理中にのみ利用する中間データの格納場所としてEphemeral Volumeを活用

その他のユースケースとしては、Ephemeral Volume に格納するデータは小さいが、1台のノードに多数のPodを詰め込みたい場合も活用できます。
emptyDir はノードのリソース(メディアやRAM)を使うため、これらのリソースがネックになりノードあたりに配置できるPod数が少なくなってしまうことがあります。
このような場合に CSI Ephemeral Volume や Generic Ephemeral Volumeは有効な回避方法のひとつではないでしょうか。

2点目のCSI Ephemeral Volume と Generic Ephemeral Volume のどちらを使うべきかについては、特段の理由が無い限りは、Kubernetes v1.21でBetaとなった Generic Ephemeral Volume を利用するのが、個人的なお勧めです。理由としては以下です。

  • CSI Ephemeral VolumeをサポートしているCSI Driver は限定的(数が少ない)
  • CSI Ephemeral Volumeの仕様はCSI Driver毎に独自仕様(今回の動作検証では利用しなかったspec.volumes.csi.volumeAttributesで指定)
  • Generic Ephemeral Volumeの方が後発であり、今後CSI DriverをサポートするベンダーはPersistentEphemeralを区別せず楽に実装できるGeneric Ephemeral Volumeを選択すると予測
  • Generic Ephemeral Volumeは、永続ボリューム(Persistent)でサポートしている機能(Volume ExpansionやVolume Snapshotなど)が利用可能

CSI を使った Ephemeral Volume は、ステートフルアプリケーション以外でもKubernetes でストレージを使ったユースケースが広がるポテンシャルをもっているため、ユースケースの広がりに期待します。

参考情報

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?