(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】storageClass経由でPVCを要求するStatefulsetの1回目と2回目の挙動の違い

スポンサーリンク

はじめに

PodのspecにvolumeClaimTemplatesとしてPersistentVolumeClaimを要求してデータを固定化する際、1回目と2回目でイベントに違いががあります。

本記事はレプリカ数1のmongoイメージを例にステートフルセットの落とし上げをしました。
それによって、宣言型と言われるKubernetesにおいて不可逆性を持つ挙動を確認することが可能です。

環境情報
  • kubernetes v1.19

1回目の実行

以下のようなYAMLにてmongoというStatefulsetを作成します。

...
        volumeMounts:
        - mountPath: /data/db
          name: test-storage
...
  volumeClaimTemplates:
  - apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      creationTimestamp: null
      name: test-storage
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 20Gi
      storageClassName: xx
      volumeMode: Filesystem
....

同YAMLの初回実行タイミングにて以下のようにPVCと

$ kubectl get pvc
NAME   STATUS   VOLUME  CAPACITY   ACCESS MODES   STORAGECLASS  AGE
test-storage-mongo-0         Bound    pvc-xxx   20Gi       RWO           xx   2m1s

PVが新規作成されます。ちなみにPVの項目であるNAME欄とPVCの項目のVOLUME欄の値は同一です。

$ kubectl get pv
NAME  CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM  STORAGECLASS  REASON   AGE
pvc-xxx   20Gi       RWO            Retain           Bound      namespace/test-storage-mongo-0   44s

Statefulsetの詳細を見ると以下のようにVolume情報を要求しています。

  Type    Reason            Age   From                    Message
  ----    ------            ----  ----                    -------
  Normal  SuccessfulCreate  63s   statefulset-controller  create Claim test-storage-mongo-0 Pod mongo-0 in StatefulSet mongo success
  Normal  SuccessfulCreate  63s   statefulset-controller  create Pod mongo-0 in StatefulSet mongo successful

2回目以降の実行

mount済のフォルダである/data/dbに配置したファイル群は再起動後も残っています。

ただし、2回目以降のStatefulsetの詳細は以下となっており

  Type    Reason            Age   From                    Message
  ----    ------            ----  ----                    -------
  Normal  SuccessfulCreate  75s   statefulset-controller  create Pod mongo--0 in StatefulSet mongo successful

1回目にあったPVCの作成(create Claim test-storage-mongo-0)の部分が割愛されています。
なぜなら、初回に作成したPVCとPVはPodの起動停止に関わらず、削除されずにオブジェクトとして存在し続けるからです。そして次回以降は自動的にPVとPodがPVCを経由して紐づく流れです。

ちなみにPodとPVが紐づいているか否かでPVのステータスは変わり、Podが停止している状態ではPVの状態をYAMLで見ると

xx/dm: ""
xx/mountpath: ""
xx/mountstatus: ""

値は空欄ですがPod起動時にはmountstatusがmountedとなっています。

xx/dm: /dev/dm-1
xx/mountpath: /var/data/kubelet/plugins/kubernetes.io/xx/pvc-xx
xx.io/mountstatus: mounted

終わりに

Statefulsetで永続ボリュームを利用するとPodが再起動してもデータを失うことなくアプリケーションが利用できます。そして、その技術的ポイントは『Statefulesetを削除(停止)してもPVとPVCは削除されない』ことにあります。

以上、入門記事としてご参考になれば幸いです。