17
3

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 1 year has passed since last update.

KubernetesAdvent Calendar 2021

Day 14

Auto remove PVCs created by StatefulSetについて

Last updated at Posted at 2021-12-13

はじめに

このページはKubernetes v1.23でアルファ機能となったAuto remove PVCs created by StatefulSetに関するまとめになります。

Kubernetes 1.23: SIG-Apps の変更内容を確認する中で、面白いなと思ったので記事にしてみました。

Auto remove PVCs created by StatefulSetについて

Auto remove PVCs created by StatefulSetはStatefulSet削除にvolumeClaimTemplatesで作成されてPVCを削除する機能になります。

機能追加の背景

StatefulSetではvolumeClaimTemplatesを使用することにPersistentVolumeClaim(PVC)が作成され、Storage ClassがPVCを元にPersistentVolume(PV)を作成することにより、利用者はPVCとPVのリソースを明示的に作成することなくVolumeを使用することができます。

利用者は以下の例示するようなyamlを作成する必要がなくなったことがvolumeClaimTemplatesのメリットになります。

  • PersistentVolumeClaim(PVC)の例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}
  • PersistentVolume(PV)の例
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

StatefulSetを削除した際にvolumeClaimTemplatesによって作成されたPVCは削除されないため、利用者は必要に応じてPVCを手動で削除する必要があります。

これはPodのライフサイクルとデータのライフサイクルが異なるために、データの削除については意図してStatefulSetから分離されているためです。あくまでStatefulSetはPodのライフサイクルを管理する機能であって、データのライフサイクルを管理するためのものではないことに気をつけてください。

ただ、こちらのissueにあるようにStatefulSetを削除した際にvolumeClaimTemplatesによって作成されたPVCが削除されて欲しいという声も多かったため、機能として追加されることになりました。

機能の利用方法

以下のようにStatefulSetのspecpersistentVolumeClaimRetentionPolicyが追加されており、Deleteを指定することで該当機能が有効になります。

apiVersion: apps/v1
kind: StatefulSet
  :
spec:
  persistentVolumeClaimRetentionPolicy:
    whenDeleted: Retain  # デフォルトは`Retain`
    whenScaled: Delete  # デフォルトは`Retain`
  :
  • whenDeleted
    StatefulSetが削除された時にDeleteの場合は、PVCを削除する機能になります。

  • whenScaled
    StatefulSetのレプリカ数が減った時にDeleteの場合は、PVCを削除する機能になります。

実際の動作結果

  • クラスタの作成

今回の例ではminikubeを使用します。

$ minikube start --kubernetes-version v1.23.0 --feature-gates=StatefulSetAutoDeletePVC=true

アルファ機能なので、feature-gatesのStatefulSetAutoDeletePVCを有効化する必要があります。

  • Manifestの作成

以下のようにpersistentVolumeClaimRetentionPolicyDeleteを設定したManifestを用意します。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx 
  serviceName: "nginx"
  replicas: 3 
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  persistentVolumeClaimRetentionPolicy:
    whenDeleted: Delete
    whenScaled: Delete
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1G
  • Manifestの適用
$ kubectl apply -f StatefulSet.yaml    
statefulset.apps/web created

$ kubectl get sts,po,pvc,pv
NAME                   READY   AGE
statefulset.apps/web   3/3     44s

NAME        READY   STATUS    RESTARTS   AGE
pod/web-0   1/1     Running   0          44s
pod/web-1   1/1     Running   0          32s
pod/web-2   1/1     Running   0          29s

NAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/www-web-0   Bound    pvc-81240f89-c62e-4536-be78-3d27f292a770   1Gi        RWO            standard       44s
persistentvolumeclaim/www-web-1   Bound    pvc-e3221c3d-cf3e-4c0f-8ce6-96d20d126876   1Gi        RWO            standard       32s
persistentvolumeclaim/www-web-2   Bound    pvc-200dc5d9-dd8d-4037-b3bb-fc1a13eb34e5   1Gi        RWO            standard       29s

NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pvc-200dc5d9-dd8d-4037-b3bb-fc1a13eb34e5   1Gi        RWO            Delete           Bound    default/www-web-2   standard                29s
persistentvolume/pvc-81240f89-c62e-4536-be78-3d27f292a770   1Gi        RWO            Delete           Bound    default/www-web-0   standard                39s
persistentvolume/pvc-e3221c3d-cf3e-4c0f-8ce6-96d20d126876   1Gi        RWO            Delete           Bound    default/www-web-1   standard                32s

StatefulSetではvolumeClaimTemplatesとStorage Classの機能により、PVまで作成されていることが確認できます。

  • Manifestの削除
$ k delete -f StatefulSet.yaml
statefulset.apps "web" deleted

$ kubectl get sts,po,pvc,pv   
No resources found

StatefulSetではvolumeClaimTemplatesで作成されたPVCがStatefulSetの削除後に自動で削除されることが確認できます。

ここで一点気をつけて欲しいのが、PVが削除されたのはあくまでPVのReclaim Policyに基づいたものであり、 Auto remove PVCs created by StatefulSetとは直接関係ないということです。

whenDeletedwhenScaledの使い分け

whenDeletedwhenScaledに対して、RetainDeleteが設定できるため、Auto remove PVCs created by StatefulSetでは4つのパターンが存在します。それぞれの使い分け方について説明します。

  1. whenDeleted=Retain & whenScaled=Retain(未指定時の動作)
    k8s v1.22以前と同じ動作になります。StatefulSetからデータのライフサイクルが分離されているため、StatefulSetの削除によりPVCが削除されることはありません。

  2. whenDeleted=Delete & whenScaled=Retain
    StatefulSet削除時にPVCが削除されますが、レプリカ数が減少した時にPVCが削除されることはありません。再度スケールする際に、PVの作成コストが減らせるというメリットがあります。

  3. whenDeleted=Delete & whenScaled=Delete
    StatefulSet削除時とレプリカ数が減少した時にPVCを削除します。そのためPod数以上にPVCが作成されることがありません。Podの削除以降に、該当のデータを使用する必要がない場合に使用します。

  4. whenDeleted=Retain & whenScaled=Delete
    StatefulSet削除にPVCは削除せず、レプリカ数が減少した時にPVCを削除します。これはスケールアップ時のデータについては保持する必要がないが、起動時のデータは保持しておきたい場合などに使います。最低限3個のPVは必要だが、それ以降にスケールアップしたときに作成されたPVは不要な場合などに有用です。
    ただし、最低3個のPVを保持したい場合でも、whenScaledは有効化されてるのでレプリカ数が1になればPVCも1個になります。HPAと併用する場合はminReplicasを3にするなど、この機能とは別のところでレプリカ数に対するガードをかけないとPVが消える可能性がある点に注意してください。

気をつける点

Auto remove PVCs created by StatefulSetはStatefulSetに対してデータのライフサイクルに関する権限の譲渡する機能になります。そのため、StatefulSetの削除による誤ったデータ削除のリスクがあることに気をつけてください。

個人的には以下の3つくらいのパターンは起こっても不思議はないなと思っています。

  • Manifest更新時に削除してしまう。
    手動で作業時にapplyを使う場面で、一度きれいにしておきたくてdeleteをする。商用環境でやることはなかなかないと思いますが、テスト中くらいなら普通にやるケースはある気がしてます。

  • kubectl apply --pruneで誤って削除してしまう
    pruneの機能は非常に便利なんですが、誤った利用による事故も多いのでこれはこの機能限らず気をつけてほうがいいと思います。個人的には商用環境での手動でのpruneの利用は禁止してもいいんじゃないかなくらいに、使いたくないです。

  • CDツールによる意図しないdeleteの実行
    通常はapplyを使用してると思うのですが、force syncみたいな機能では中でdelete実装されてるケースもあるのかなという不安があります。Deploymentの場合は意図せずdeleteが走っても一時的にPodがなくなるだけなんですが、今回の機能を利用しているとデータが削除される可能性があるので大変心配してます。この機能を有効化する際には必ずお使いのCDツールの挙動を把握するようにしてください。

所感

データを誤って削除するリスクは怖いものの、便利な機能かなと思います。手元でテストした後にPVCを手動で消すのは正直、めんどくさいのでこの機能があるとありがたいです。

参考

Auto remove PVCs created by StatefulSetに関連する情報は以下を参考にしました。

17
3
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
17
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?