はじめに
今回はPersistentVolume(PV)のパラメータの「Reclaim Policy」の動作を確認してみたいと思います。Reclaim PolicyはPVを利用し終わった後の処理を指定します。
Reclaim Policyには以下の3つがあります。
| Reclaim Policy | 概要 | 
|---|---|
| Delete | PVの実体を削除する。 | 
| Retain | PVの実体を保持する。 | 
| Recycle | PVのデータを削除し、再利用可能な状態にする。 | 
Delete
まずはDeleteの動作を確認します。
環境準備
以下のPV/PVC/Podのマニフェストをapplyします。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-delete-0001
spec:
  capacity:
    storage: 500Mi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /share
    server: k8s-client
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-dlt01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 500Mi
  storageClassName: slow
apiVersion: v1
kind: Pod
metadata:
  name: nginx-dlt01
spec:
  containers:
  - image: nginx:latest
    name: nginx-dlt01
    volumeMounts:
    - mountPath: /cache
      name: cache-pv01
  volumes:
  - name: cache-pv01
    persistentVolumeClaim:
      claimName: claim-dlt01
$ kubectl apply -f pv-delete.yaml
persistentvolume/pv-delete-0001 created
$ kubectl apply -f pvc-delete01.yaml
persistentvolumeclaim/claim-dlt01 created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-delete-0001   500Mi      RWX            Delete           Bound    default/claim-dlt01   slow                    2m40s
$ kubectl get pvc
NAME          STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-dlt01   Bound    pv-delete-0001   500Mi      RWX            slow           9s
$ kubectl apply -f nginx-delete01.yaml
pod/nginx-dlt01 created
動作確認
PodのPVの領域にファイルを作って書き込みます。
$ kubectl exec -it nginx-dlt01 /bin/bash
root@nginx-dlt01:/# echo `hostname` > /cache/testfile
root@nginx-dlt01:/# cat /cache/testfile
nginx-dlt01
root@nginx-dlt01:/# exit
exit
Podの削除
Podだけ削除して、再作成してみます。
$ kubectl delete -f nginx-delete01.yaml
pod "nginx-dlt01" deleted
$ kubectl apply -f nginx-delete01.yaml
pod/nginx-dlt01 created
$ kubectl exec -it nginx-dlt01 cat /cache/testfile
nginx-dlt01
Podを再作成しても、PVに書き込んだファイルは残ってますね。
PVCの削除
今度はPVCまで削除してみます。
$ kubectl delete -f nginx-delete01.yaml
pod "nginx-dlt01" deleted
$ kubectl delete -f pvc-delete01.yaml
persistentvolumeclaim "claim-dlt01" deleted
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-delete-0001   500Mi      RWX            Delete           Failed   default/claim-dlt01   slow                    16m
PVのSTATUSが「Failed」になりました。
このときのNFS Server側でファイルを確認してみます。
[k8s-client ~]$ cat /share/testfile
nginx-dlt01
ファイルは残ってますね。
ここでPVCを再作成してみます。
$ kubectl apply -f pvc-delete01.yaml
persistentvolumeclaim/claim-dlt01 created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-delete-0001   500Mi      RWX            Delete           Failed   default/claim-dlt01   slow                    18m
$ kubectl get pvc
NAME          STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-dlt01   Pending                                      slow           11s
$ kubectl describe pvc claim-dlt01
Name:          claim-dlt01
・・・
Events:
  Type     Reason              Age                From                         Message
  ----     ------              ----               ----                         -------
  Warning  ProvisioningFailed  11s (x3 over 30s)  persistentvolume-controller  storageclass.storage.k8s.io "slow" not found
PVCの再作成はできましたが、Pendingの状態ですね。
PVの削除
今度はPVまで削除してみたいと思います。
$ kubectl delete -f nginx-delete01.yaml
pod "nginx-dlt01" deleted
$ kubectl delete -f pvc-delete01.yaml
persistentvolumeclaim "claim-dlt01" deleted
$ kubectl delete -f pv-delete.yaml
persistentvolume "pv-delete-0001" deleted
再作成します。
$ kubectl apply -f pv-delete.yaml
persistentvolume/pv-delete-0001 created
$ kubectl apply -f pvc-delete01.yaml
persistentvolumeclaim/claim-dlt01 created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-delete-0001   500Mi      RWX            Delete           Bound    default/claim-dlt01   slow                    30s
$ kubectl get pvc
NAME          STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-dlt01   Bound    pv-delete-0001   500Mi      RWX            slow           15s
$ kubectl apply -f nginx-delete01.yaml
pod/nginx-dlt01 created
PVの領域を確認します。
$ kubectl exec -it nginx-dlt01 cat /cache/testfile
nginx-dlt01
残ってますね。
マニュアルには以下のように記載されています。
AWS EBS、GCE PD、Azure Disk、もしくはOpenStack Cinderボリュームに関連するストレージアセットを削除
確かにNFSだと実体のファイルシステムを削除されても困ると思いますので、NFSだとこういう動作になるのかもしれないですね。
AWSなどで確認する機会ができたら、確認してみたいと思います。
Retain
次にRetainの動作を確認します。
環境準備
以下のマニフェストのPV/PVC/Podをapplyします。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-retain-0001
spec:
  capacity:
    storage: 500Mi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /share
    server: k8s-client
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-rtn01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 500Mi
  storageClassName: slow
apiVersion: v1
kind: Pod
metadata:
  name: nginx-rtn01
spec:
  containers:
  - image: nginx:latest
    name: nginx-rtn01
    volumeMounts:
    - mountPath: /cache
      name: cache-pv01
  volumes:
  - name: cache-pv01
    persistentVolumeClaim:
      claimName: claim-rtn01
$ kubectl apply -f pv-retain01.yaml
persistentvolume/pv-retain-0001 created
$ kubectl apply -f pvc-retain01.yaml
persistentvolumeclaim/claim-rtn01 created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-retain-0001   500Mi      RWX            Retain           Bound    default/claim-rtn01   slow                    13s
$ kubectl get pvc
NAME          STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-rtn01   Bound    pv-retain-0001   500Mi      RWX            slow           9s
$ kubectl apply -f nginx-retain01.yaml
pod/nginx-rtn01 created
動作確認
同様にPodのPVの領域にファイルを作って書き込んでおきます。
$ kubectl exec -it nginx-rtn01 cat /cache/testfile
nginx-rtn01
PVCの削除
PodとPVCを削除してみます。
$ kubectl delete -f nginx-retain01.yaml
pod "nginx-rtn01" deleted
$ kubectl delete -f pvc-retain01.yaml
persistentvolumeclaim "claim-rtn01" deleted
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                 STORAGECLASS   REASON   AGE
pv-retain-0001   500Mi      RWX            Retain           Released   default/claim-rtn01   slow                    10m
STATUSが「Released」となりました。
なお、この時NFS Server側では、作成したファイルは保持されています。
[k8s-client ~]$ cat /share/testfile
nginx-rtn01
PVCを再作成してみます。
$ kubectl apply -f pvc-retain01.yaml
persistentvolumeclaim/claim-rtn01 created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                 STORAGECLASS   REASON   AGE
pv-retain-0001   500Mi      RWX            Retain           Released   default/claim-rtn01   slow                    12m
$ kubectl get pvc
NAME          STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-rtn01   Pending                                      slow           10s
$ kubectl describe pvc claim-rtn01
Name:          claim-rtn01
・・・
Events:
  Type     Reason              Age               From                         Message
  ----     ------              ----              ----                         -------
  Warning  ProvisioningFailed  9s (x4 over 46s)  persistentvolume-controller  storageclass.storage.k8s.io "slow" not found
PVのSTATUSは「Released」のままで、PVCがPendingになってますね。
PVの削除
PVまで削除し、PV/PVCを再作成することで、保持されているPVおよびファイルを再利用することができます。
RetainはPVの利用が終わった後(PVCを削除した後)にPVの実体を保持しますが、そのPVを再度利用する際は、PVを再作成する必要があります。
Recycle
最後にRecycleの動作を確認します。
環境準備
以下のマニフェストのPV/PVC/Podをapplyします。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-recycle-0001
spec:
  capacity:
    storage: 500Mi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /share
    server: k8s-client
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim-rcc01
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 500Mi
  storageClassName: slow
apiVersion: v1
kind: Pod
metadata:
  name: nginx-rcc01
spec:
  containers:
  - image: nginx:latest
    name: nginx-rcc01
    volumeMounts:
    - mountPath: /cache
      name: cache-pv01
  volumes:
  - name: cache-pv01
    persistentVolumeClaim:
      claimName: claim-rcc01
$ kubectl get pv
NAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-recycle-0001   500Mi      RWX            Recycle          Bound    default/claim-rcc01   slow                    13s
$ kubectl get pvc
NAME          STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-rcc01   Bound    pv-recycle-0001   500Mi      RWX            slow           7s
$ kubectl get pod
NAME                  READY   STATUS      RESTARTS   AGE
nginx-rcc01           1/1     Running     0          3m6s
動作確認
同様にPodのPVの領域にファイルを作って書き込んでおきます。
$ kubectl exec -it nginx-rcc01 cat /cache/testfile
nginx-rcc01
PVCの削除
PodとPVCを削除してみます。
$ kubectl delete -f nginx-recycle01.yaml
pod "nginx-rcc01" deleted
$ kubectl delete -f pvc-recycle01.yaml
persistentvolumeclaim "claim-rcc01" deleted
$ kubectl get pv
NAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-recycle-0001   500Mi      RWX            Recycle          Available           slow                    8m21s
DeleteやRetainと違って、STATUSが「Available」に戻ってますね。
この時のNFS Server側のファイルを確認します。
[k8s-client ~]$ cat /share/testfile
cat: /share/testfile: そのようなファイルやディレクトリはありません
PVのSTATUSが「Available」ですので、PVを再作成しなくてもPVCを再設定できます。
$ kubectl apply -f pvc-recycle01.yaml
persistentvolumeclaim/claim-rcc01 created
$ kubectl get pv
NAME              CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pv-recycle-0001   500Mi      RWX            Recycle          Bound    default/claim-rcc01   slow                    12m
$ kubectl get pvc
NAME          STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim-rcc01   Bound    pv-recycle-0001   500Mi      RWX            slow           8s
まとめ
Deleteは想定した動きにはなりませんでしたが、Reclaim Policyの動きをまとめると以下になります。
PVCを削除したとき
| Delete | Retain | Recycle | |
|---|---|---|---|
| PV中のファイル | 削除される※ | 保持される | 削除される | 
| PV | 削除される※ | 保持される | 保持される | 
| PVの実体 | 削除される※ | 保持される | 保持される | 
※Deleteは今回の検証では違う動き。本やマニュアルを見るとこうなる模様。
PVを再利用するとき
| Delete | Retain | Recycle | |
|---|---|---|---|
| PVC | 再設定 | 再設定 | 再設定 | 
| PV | 再設定 | 再設定 | 再設定不要 | 
| PVの実体 | 再設定? | 再設定不要 | 再設定不要 |