誤ってクラスター内のすべてのPVを削除しようとしましたが、ありがたいことに、バインドされているPVCが残っているため、すべてのPVがステータス:終了中のままになっています。
どのようにしてPVを「終了」ステータスから外し、pvcに「バインド」されて完全に機能している健全な状態に戻すことができますか?
ここで重要なのは、データを失わないようにすることと、ボリュームが機能していて、クレームが解消されても終了するリスクがないことを確認したいことです。
PVのkubectl describe
の詳細を以下に示します。
$ kubectl describe pv persistent-vol-1
Finalizers: [kubernetes.io/pv-protection foregroundDeletion]
Status: Terminating (lasts 1h)
Claim: ns/application
Reclaim Policy: Delete
これがクレームの説明です。
$ kubectl describe pvc application
Name: application
Namespace: ns
StorageClass: standard
Status: Bound
Volume: persistent-vol-1
実際には、Status: Terminating
とPersistentVolume
をデフォルト(削除)に設定して、RetainPolicy
からデータを保存することができます。これで、 GKE、AWSまたはAzureについては不明ですが、それらは類似していると思います
私たちは同じ問題を抱えていたので、誰かがこのような問題を抱えている場合に備えて、ここに解決策を投稿します。
PersistenVolumes
は、ポッド、デプロイ、またはより具体的になるまで、つまりPersistentVolumeClaim
を使用するまで終了しません。
壊れた状態を修復するために実行した手順:
OPのような状況になったら、最初に、PersistentVolumes
のスナップショットを作成します。
GKEコンソールでCompute Engine -> Disks
に移動し、そこでボリュームを見つけ(kubectl get pv | grep pvc-name
を使用)、ボリュームのスナップショットを作成します。
スナップショットを使用してディスクを作成します:gcloud compute disks create name-of-disk --size=10 --source-snapshot=name-of-snapshot --type=pd-standard --zone=your-zone
この時点で、ボリュームを使用しているサービスを停止し、ボリュームとボリュームの要求を削除します。
ディスクのデータを使用して手動でボリュームを再作成します。
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: name-of-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
gcePersistentDisk:
fsType: ext4
pdName: name-of-disk
persistentVolumeReclaimPolicy: Retain
次に、ボリュームクレームを更新して、yamlファイルの最終行である特定のボリュームをターゲットにします。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
namespace: my-namespace
labels:
app: my-app
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
volumeName: name-of-pv
何をしているか分からない場合は、これを試さないでください
PVの削除を取り消すには、かなりハッキーな方法がもう1つあります。 etcdでオブジェクトを直接編集します。次の手順は、etcdを制御できる場合にのみ機能することに注意してください。これは、特定のクラウドプロバイダーやマネージドオファリングでは当てはまらない場合があります。また、物事をはるかに簡単に台無しにできることに注意してください。 etcd内のオブジェクトは直接編集することを意図したものではないため、注意してアプローチしてください。
私たちのPVにはdelete
のポリシーがあり、k8s 1.11でそれらの大部分を削除するコマンドを誤って実行したという状況がありました。 storage-object-in-use 保護のおかげで、すぐには消えませんでしたが、危険な状態でぶらついていました。 PVCをバインドしていたポッドを削除または再起動すると、kubernetes.io/pvc-protection
ファイナライザが削除され、基になるボリューム(この場合はEBS)が削除されます。リソースが終了状態にある場合、新しいファイナライザも追加できません-k8s設計の観点から、これは競合状態を防ぐために必要です。
以下は私が従ったステップです:
kubectl -n=kube-system port-forward etcd-server-ip-x.y.z.w-compute.internal 4001:4001
REST API、または etcdkeeper のようなツールを使用して、クラスターに接続します。
/registry/persistentvolumes/
に移動して、対応するPVを見つけます。 k8sのコントローラーによるリソースの削除は、コントローラー仕様の.spec.deletionTimeStamp
フィールドを設定することによって行われます。このフィールドを削除して、コントローラーがPVの削除を停止するようにします。これにより、Bound
状態に戻ります。これは、削除を実行する前の状態であると考えられます。
ReclaimPolicyを慎重に編集してRetain
にしてから、オブジェクトをetcdに保存することもできます。コントローラーはすぐに状態を再読み取りし、すぐにkubectl get pv
出力にも反映されるはずです。
PVは古い削除されていない状態に戻るはずです。
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-b5adexxx 5Gi RWO Retain Bound zookeeper/datadir-Zoo-0 gp2 287d
pvc-b5ae9xxx 5Gi RWO Retain Bound zookeeper/datalogdir-Zoo-0 gp2 287d
一般的なベストプラクティスとして、 [〜#〜] rbac [〜#〜] と適切な永続ボリューム再利用ポリシーを使用して、PVまたは基になるストレージが誤って削除されるのを防ぐのが最善です。
残念ながら、この場合、PVとデータを保存することはできません。 Reclaim Policy: Retain
を使用してPVを再作成するだけです-これにより、将来のデータ損失を防ぐことができます。再利用ポリシーの詳細については、 ここ および ここ を参照してください。
PersistentVolumeClaim(PVC)を削除するとどうなりますか?ボリュームが動的にプロビジョニングされた場合、デフォルトの再利用ポリシーは「削除」に設定されます。つまり、デフォルトでは、PVCが削除されると、基になるPVおよびストレージアセットも削除されます。ボリュームに格納されているデータを保持する場合は、PVがプロビジョニングされた後に、再利用ポリシーを「削除」から「保持」に変更する必要があります。