事の始まり
誤って 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 のデータが上書きされてしまったような気が。
新規作成であるため、container 中の data が 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 を削除
ってやればサービス影響もないんでしょうけど、面倒くさくてこの方法をとりました。
以上。