当意外删除PersistentVolumeClaim(PVC)时的对策示例
一切事物的起始
不慎执行了错误的 kubectl delete pvc ~ 命令,导致对非目标的物件进行了删除,这是一种令人遗憾的状态。
[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。
[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
情况
-
- 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 -o yaml >> 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 数据,这让我感到有点困惑。
由于是新建操作,所以容器中的数据会被写入到 pv 中。
#データが上書きされ NG
kubectl create -f pod-<pod名>.yaml
#データを再利用するので OK
kubectl apply -f pod-<pod名>.yaml
整个对策已经完成
尽管数据本来就不会消失,但我们可以利用Retain的特点。
-
- 用另一个名称创建 pv / pvc / deployment
-
- 将其集成到现有的 service 中(如 kubectl edit)
-
- 删除绑定到 Terminating 的 pvc 的 pod
- 删除 pv
我选择了这种方法,虽然这样做可能不会对服务产生影响,但是觉得太麻烦了。
以上。