根据官方文档https://kubernetes.io/docs/tasks/administer-cluster/change-pv-reclaim-policy/使用“保留”策略可以手动恢复 PV。这实际上是什么意思,是否有一种工具可以让我从“保留”的 PV 中读取数据并将其写入另一个 PV,或者这是否意味着您可以挂载该卷手册以获得访问权限?
4 回答
手动恢复卷的过程如下。
删除 PVC 后,可以使用同一个 PV 和数据一起挂载到不同的 Pod(PV 必须存在,如果 storageclass 的 reclaim policy 为 Retain 则通常存在)
验证 PV 是否处于释放状态。(即目前没有 pvc 声称它)
➜ ~ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-eae6acda-59c7-11e9-ab12-06151ee9837e 16Gi RWO Retain Released default/dhanvi-test-pvc gp2 52m
编辑 PV ( kubectl edit pv pvc-eae6acda-59c7-11e9-ab12-06151ee9837e
) 并删除 spec.claimRef 部分。PV 声明将如下所示未设置。
➜ ~ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-eae6acda-59c7-11e9-ab12-06151ee9837e 16Gi RWO Retain Available gp2 57m
然后使用 PVC 声明 PV,如下所示。
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: dhanvi-test-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 16Gi
volumeName: "pvc-eae6acda-59c7-11e9-ab12-06151ee9837e"
可以在下面的 pod 中使用。
volumes:
- name: dhanvi-test-volume
persistentVolumeClaim:
claimName: dhanvi-test-pvc
更新:卷克隆可能会有所帮助 https://kubernetes.io/blog/2019/06/21/introducing-volume-cloning-alpha-for-kubernetes/
三个回收策略定义了删除绑定卷声明后持久卷发生的情况
- 保持
- 删除
- 回收
删除意味着永久卷以及外部基础架构中的关联存储资产被删除。
Recycle将清理卷 rm -rf /thevolume/* ,之后它将可用于新的持久卷声明。
Retain使持久卷处于释放状态,这不允许新的持久卷声明来回收它。整个回收过程是手动的。您需要自己删除持久卷。您可以备份存储资产中的数据,然后删除数据。然后,您可以删除存储资产或为此资产创建新的持久卷。
如果你想使用 Kubernetes 将数据写入另一个持久化卷,你可以使用 Job 来复制数据。
在这种情况下,请确保您使用持久卷访问模式 ROX - ReadOnlyMany 或 RWX - ReadWriteMany 并启动运行容器的作业,该容器声称要使用选择器备份持久卷并声明另一个目标备份卷。然后通过容器复制数据。
或者,您可以在 Kubernetes 之外进行备份。然后,您的方法确实取决于您使用的存储资产的类型。例如,如果您使用 NFS,您可以挂载源和目标并通过命令行复制数据。
我提出的两个选项或多或少都是手动备份策略。如果您的目标是为生产工作负载提供更复杂的备份策略,您可以查看Stash - Backup for your disks for your disks for production workloads in Kubernetes
就像 Tummala Dhanvi 在回答中所说的那样,spec.claimRef
必须解决该部分。如果您只有一个 PV,则删除整个PV 可能会很有用,但如果您有多个 PV 要“拯救” spec.claimRef
,这将证明是非常讨厌的。
第一步是在删除PVC之前确保 PV 具有Retain
回收策略。您可以编辑或修补 PV 以实现此目的
kubectl edit pv pvc-73e9252b-67ed-4350-bed0-7f27c92ce826
- 找到
spec.persistentVolumeReclaimPolicy
钥匙 - 输入
Retain
值 - 保存并退出
- 找到
- 或者,在一个命令中
kubectl patch pv pvc-73e9252b-67ed-4350-bed0-7f27c92ce826 -p "{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}"
现在您可以删除 PVC(通过使用helm
或其他方式),并且不会删除 PV。
要成功地将 PV 重新安装到所需的 pod,您必须再次编辑 PV 配置,这次是该spec.claimRef
部分。但不要删除整个部分。相反,只删除resourceVersion
和uid
键。结果部分看起来像这样
...
capacity:
storage: 16Gi
claimRef:
apiVersion: v1
kind: PersistentVolumeClaim
name: database
namespace: staging
nodeAffinity:
...
对所有 PV 重复此操作,它们在kubectl get pv
输出中的状态将在Available
之后。通过保持spec.claimRef.name
和spec.claimRef.namespace
键不变,我们确保具有相应spec
(staging/database
在我的情况下)的新 PVC 将绑定到它应该绑定的确切 PV。
此外,请确保您的新声明未指定比 PV 实际拥有的更大的存储容量(似乎新声明的容量可能小于现有 PV)。如果新的 PVC 要求更大的存储空间,则会创建一个新的 PV。最好保持不变。
题外话:如果storageClass
您使用的允许调整音量大小,您可以稍后调整它的大小;这里解释了如何:https ://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/
我在这方面的经历非常紧张。我有 6 个 PV,完全处于Retain
模式中。由于某种原因,新的部署部署卡住了,两个 pod 只是不想终止。最后,我最终删除了整个部署(使用helm
),重新启动集群节点,然后重新部署。这导致创建了 6 个新PV!
我找到了这个帖子,然后继续删除spec.claimRef
所有 PV。再次删除和部署安装会导致 PV 被重用,但它们没有安装在应有的位置,数据不存在。经过大量挖掘后,我发现该database
卷已安装到 RabbitMQ pod,mongodb
已安装到 ElasticSearch 等。
我花了大约十几次,才把这件事做好。幸运的是,对我来说,混合安装卷并没有破坏任何原始数据。pod 初始化并没有清理卷,只是在那里写了他们的东西。
希望这可以节省一些严重的头痛!
我发现这个问题的原因与现有答案地址略有不同,所以我会权衡一下。
在我的例子中,我有一个自我管理的 Microk8s 集群,用于开发和测试目的,具有 手动本地存储(其中一个节点上的安装路径),如下所示:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-1
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 50Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data-1"
还有一个 PVC 和一个使用这个 PV 的部署。然后我无意中破坏了这些资源所在的命名空间。
我想要实现的是重新创建整个命名空间并让它使用这个 PersistentVolume 以及仍然存在于服务器上的相同数据。
在我的本地手动存储的情况下,只需删除 PV 并再次创建它。删除 PV 不会删除服务器上的实际数据(至少使用Retain
策略)。使用 mount 将 PV 重新创建到数据已经存在的路径中也可以正常工作 - 数据只是被使用。