取消或撤消kubernetes集群中持久卷的删除

时间:2018-07-30 00:29:55

标签: kubernetes persistent-volumes

偶然地尝试删除群集中的所有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

5 个答案:

答案 0 :(得分:5)

实际上,可以将PersistentVolumeStatus: Terminating设置为默认值(删除)来保存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

答案 1 :(得分:2)

由于一个粗心的错误,我也处于同样的情况。它与Google Cloud / GKE上的状态相同。我的PVC表示终止,因为引用它的Pod仍在运行,并且PV的保留策略为Deleted。最后,我找到了一种更简单的方法来整理所有内容,同时保留了所有额外的Google / Kubernetes元数据和名称。

首先,我将根据另一个答案的建议为您的磁盘制作快照。您将不需要它,但是如果出现问题,可以使用此处的其他答案从中重新创建磁盘。

简短的版本是,您只需要将PV重新配置为“保留”,允许删除PVC,然后从PV中删除先前的声明。然后可以将新的PVC绑定到它上,一切都很好。

详细信息:

  1. 找到PV的全名:
    kubectl get pv
  1. 将PV重新配置为将回收策略设置为“保留” :(我在Windows上执行此操作,因此您可能需要根据操作系统来处理不同的报价)
    kubectl patch pv <your-pv-name-goes-here> -p "{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}"
  1. 验证PV的状态现在为“保留”。
  2. 关闭您的pod /状态集(并且不允许其重新启动)。完成后,将删除您的PVC,PV(及其引用的磁盘!)将保持不变。
  3. 编辑PV:
    kubectl edit pv <your-pv-name-goes-here>
  1. 在编辑器中,删除整个“ claimRef”部分。从“ claimRef:”(包括)中删除所有行,直到具有相同缩进级别的下一个标记。删除的行应大致如下所示:
      claimRef:
        apiVersion: v1
        kind: PersistentVolumeClaim
        name: my-app-pvc-my-app-0
        namespace: default
        resourceVersion: "1234567"
        uid: 12345678-1234-1234-1234-1234567890ab
  1. 保存更改并关闭编辑器。检查PV的状态,它现在应显示“可用”。
  2. 现在,您可以像最初一样完全重新创建PVC。然后,应该找到现在的“可用” PV并将其绑定到该PV。在我的情况下,我将用statefulset定义的PVC定义为volumeClaimTemplate,所以我要做的就是“套用kubectl apply”我的statefulset。

答案 2 :(得分:0)

不幸的是,在这种情况下,您无法保存PV和数据。 您可能要做的就是使用Reclaim Policy: Retain重新创建PV-这样可以防止将来丢失数据。 您可以阅读有关回收策略herehere的更多信息。

  

如果删除PersistentVolumeClaim(PVC),会发生什么?如果音量   是动态配置的,则默认回收策略设置为   “删除”。这意味着默认情况下,删除PVC时,   基础PV和存储资产也将被删除。如果你想   保留存储在卷上的数据,那么您必须更改回收   设置PV后,政策从“删除”到“保留”。

答案 3 :(得分:0)

您可以签出this tool,它将etcd中Terminating PV的状态更新为Bound

Anirudh Ramanathan在回答中提到了它的工作方式。

请务必先备份您的PV。

答案 4 :(得分:-1)

如果您不知道自己在做什么,请不要尝试

还有另一种撤消删除PV的方法。在etcd中直接编辑对象。请注意,以下步骤仅在您拥有对etcd的控制权时有效-在某些云提供商或托管产品上可能并非如此。还要注意,您很容易将事情弄糟。由于etcd中的对象永远都不打算直接编辑-因此请谨慎处理。

我们遇到这样的情况,我们的PV的策略为delete,而我不小心在k8s 1.11上运行了一个命令,删除了其中的大多数。由于storage-object-in-use的保护,它们并没有立即消失,而是以危险状态徘徊。绑定PVC的吊舱的任何删除或重新启动都将导致kubernetes.io/pvc-protection终结器被删除,从而删除基础卷(在我们的示例中为EBS)。当资源处于终止状态时,也不能添加新的终结器-从k8s设计的角度来看,这是必须的,以防止出现竞争状况。

下面是我遵循的步骤:

  • 备份您关心的存储卷。但这只是为了防止可能的删除-AWS,GCP,Azure都提供了执行此操作并创建新快照的机制。
  • 直接访问etcd-如果它作为静态容器运行,则可以将其ssh并检查http服务端口。默认情况下,该值为4001。如果您正在运行多个etcd节点,请使用任何一个。
  • 将端口4001从Pod转发到您的计算机。
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或基础存储。