PersistentVolumeClaim(pvc)を誤って削除してしまった時の対処例

#事の始まり
誤って kubectl delete pvc ～ を、対象外のものに実行してしまった、残念な状態が次の通り。

```shell

[root@k8s-master1 ~]# kubectl get pvc
NAME                                  STATUS        VOLUME                                CAPACITY   ACCESS MODES   STORAGECLASS   AGE
chat-rocketchat                       Terminating   chat-rocketchat                       20Gi       RWX                           62d
datadir-chatdb-mongodb-replicaset-0   Terminating   datadir-chatdb-mongodb-replicaset-0   20Gi       RWX                           62d
datadir-chatdb-mongodb-replicaset-1   Terminating   datadir-chatdb-mongodb-replicaset-1   20Gi       RWX                           62d
datadir-chatdb-mongodb-replicaset-2   Terminating   datadir-chatdb-mongodb-replicaset-2   20Gi       RWX                           62d
[root@k8s-master1 ~]#
[root@k8s-master1 ~]#
```

ちなみに PersistentVolume の状態は次の通りで、未だに STATUS は Bound のままです。

```shell
[root@k8s-master1 ~]# kubectl get pv
NAME                                  CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                                         STORAGECLASS   REASON    AGE
chat-rocketchat                       20Gi       RWX            Retain           Bound      default/chat-rocketchat                                                62d
datadir-chatdb-mongodb-replicaset-0   20Gi       RWX            Retain           Bound      default/datadir-chatdb-mongodb-replicaset-0                            62d
datadir-chatdb-mongodb-replicaset-1   20Gi       RWX            Retain           Bound      default/datadir-chatdb-mongodb-replicaset-1                            62d
datadir-chatdb-mongodb-replicaset-2   20Gi       RWX            Retain           Bound      default/datadir-chatdb-mongodb-replicaset-2                            62d
```

<br>


#状況  

- pvc に対し、間違って delete を実行してしまった。
- pod が pvc を必要としているため、pvc は削除されず、Terminating となる。
⇒ そのためボリュームに対しての読み書きに支障はない。(サービス影響なし)
　 また、pod も crash することはなく、Running のままの状態。
- ちなみに pod は deployment によって管理されている。 
- Terminating をキャンセルしたり、元の状態に遷移させることはできない模様。



#対応

- 対象のボリュームをマウントし、必要なデータのバックアップを行う。  
⇒ この環境で利用しているストレージは glusterfs なので、対象ボリュームをマウントしてデータのバックアップを行った。

以下、pvc / pv の yaml があるのであれば不要。

- pvc のバックアップを行う。

```
kubectl get pvc <pvc名> -o yaml >> pvc-<pvc名>.yaml
```

- pv のバックアップを行う

```
kubectl get pv <pv名> -o yaml >> pv-<pv名>.yaml
```
⇒ 今回は RECLAIM POLICY が Retain のため、pvc 削除後も pv 内のデータは残る模様。


### ここからサービス影響あり

- pod の削除を行い、pvc を削除する。  
  ⇒ サービス停止発生。

```
kubectl delete pod <pod名>
```

複数の pod がある場合は次のように pod をすべて指定する

```
kubectl delete pod <pod名> <pod名> <pod名>　・・・
```

注）pod は deployment によって制御されているので、yaml の出力を行っていない。
　必要に応じて kubectl get pod <pod名> -o yaml >> pod-<pod名>.yaml などでバックアップが必要。

- pvc が削除されていることを確認する

```
kubectl get pvc
```

- pv を確認し、pvc に紐付いていた pv の STATUS が Released となっていることを確認する。

```
kubectl get pv
```

- pv を削除する

```
kubectl delete pv <pv名>
```

- pv を作成する

```
kubectl apply -f pv-<pv名>.yaml
```

- pvc を作成する

```
kubectl apply -f pvc-<pvc名>.yaml
```

### ここでサービス復旧

- pod は deployment により再作成されており、Pendig のステータスだったが、
pvc を割り当てることで Pendig が解除され動作し始める。

```
kubectl get pod 
```

## うろ覚えだけど・・・
pod を再度作成する際、create を使うと pv のデータが上書きされてしまったような気が。
新規作成であるため、container 中の data が pv に書き出されるためだと思われます。

```
#データが上書きされ NG 
kubectl create -f pod-<pod名>.yaml

#データを再利用するので OK
kubectl apply -f pod-<pod名>.yaml
```


<br>

# 対応を終えて

本当は、データが消えない Retain の特徴を活かして、

1. 別の名前で pv / pvc / deployment を作って
2. 元からある service に組み込む(kubectl edit とか？)
3. Terminating の pvc に紐付いている pod を削除
4. pv を削除

ってやればサービス影響もないんでしょうけど、面倒くさくてこの方法をとりました。

以上。