17

不小心尝试删除集群中的所有 PV,但幸运的是它们仍然有绑定到它们的 PVC,因此所有 PV 都卡在 Status: Terminating。

如何使 PV 脱离“终止”状态并恢复到“绑定”到 pvc 并完全正常工作的健康状态?

这里的关键是我不想丢失任何数据,并且我想确保卷功能正常,并且如果索赔消失,不会有被终止的风险。

kubectl describe以下是PV上的一些细节。

$ 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
4

5 回答 5

15

事实上,可以从您的PersistentVolumewith中保存数据Status: Terminating并将RetainPolicy其设置为默认值(删除)。我们已经在 GKE 上这样做了,不确定 AWS 或 Azure,但我猜它们是相似的

我们遇到了同样的问题,我会在这里发布我们的解决方案,以防其他人遇到这样的问题。

在有 pod、部署或更具体的说 -使用它之前,您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
于 2018-09-14T19:05:10.513 回答
12

编辑:这仅适用于删除 PVC 而不是 PV 的情况。如果您删除了 PV 本身,请不要按照这些说明操作,否则磁盘可能会被删除!

由于一个粗心的错误,我发现自己处于同样的境地。它在 Google Cloud/GKE 上有一个 statefulset。我的 PVC 说终止,因为引用它的 pod 仍在运行,并且 PV 配置了已删除的保留策略。我最终找到了一种更简单的方法来理顺所有内容,同时保留了所有额外的 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 的状态现在是否为 Retain。
  2. 关闭您的 pod/statefulset(并且不允许它重新启动)。完成后,您的 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 并将其自身绑定到它。在我的例子中,我用我的 statefulset 将 PVC 定义为 volumeClaimTemplate,所以我所要做的就是“kubectl apply”我的 statefulset。
于 2020-01-05T20:20:56.190 回答
2

你可以查看这个工具,它会将TerminatingPV 在 etcd 中的状态更新回Bound.

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

请务必先备份您的 PV。

于 2020-08-25T02:50:19.587 回答
1

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

还有另一种相当老套的方法来取消删除 PV。直接编辑 etcd 中的对象。请注意,仅当您可以控制 etcd 时,以下步骤才有效 - 在某些云提供商或托管产品上可能并非如此。另请注意,您很容易把事情搞砸;因为 etcd 中的对象从不打算直接编辑 - 所以请谨慎处理。

在 k8s 1.11 上,我们的 PV 有一个策略,delete我不小心运行了一个删除其中大部分的命令。多亏了在用存储物的保护,它们并没有立即消失,而是以危险的状态四处游荡。任何删除或重新启动绑定 PVC 的 pod 都会导致kubernetes.io/pvc-protection终结器被删除,从而删除底层卷(在我们的例子中是 EBS)。当资源处于终止状态时,也无法添加新的终结器 - 从 k8s 设计的角度来看,这是防止竞争条件所必需的。

以下是我遵循的步骤:

  • 备份您关心的存储卷。这只是为了保护自己免受可能的删除 - AWS、GCP、Azure 都提供了执行此操作并创建新快照的机制。
  • 直接访问 etcd - 如果它作为静态 pod 运行,您可以 ssh 进入它并检查 http 服务端口。默认情况下,这是 4001。如果您正在运行多个 etcd 节点,请使用任何一个。
  • 从 pod 将 4001 端口转发到您的机器。
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 或底层存储。

于 2019-01-14T21:36:46.423 回答
0

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

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

于 2018-07-30T15:23:55.043 回答