一文读懂K8S的PV和PVC以及实践攻略
CSDN 2024-10-18 14:37:01 阅读 58
博客主页:StevenZeng学堂
本文专栏: 一文读懂Kubernetes | 一文读懂Harbor | 云原生安全实战指南
❤️ 摘要:作为当今最火的开源云原生系统,Kubernetes 是拥有一系列创新的组件和概念,其中最重要的组件和概念之一是 Kubernetes存储卷。Volume 组件是实现了数据持久性和共享的功能核心。本篇文章将详细介绍 Kubernetes(K8S)中的存储卷(Volume)机制,包括 Persistent Volume (PV)、Persistent Volume Claim (PVC) 和后端存储的使用,为帮助大家更好地理解三者之间的关系。
目录
1 概念
1.1 什么是存储卷? 1.2 存储卷的类型与使用场景 1.3 存储类(Storage Class)1.4 PV(Persistent Volume)1.5 PVC (Persistent Volume Claim) 1.6 动态卷(Dynamic Volume Provisioning) 1.7 PV、PVC 与后端存储的关系 2 实战:PV 和 PVC 的部署攻略
2.1 实验准备2.2 部署NFS Server2.3 Master节点挂载测试2.4 创建 PV和PVC2.5 观察PV和PVC的状态2.6 Pod挂载不同PVC测试
2.6.1 创建Pod并挂载ReadWriteOnce的PV2.6.2 创建Pod并挂载ReadWriteOncePod的PV2.6.3 创建Pod并挂载ReadWriteMany的PV2.6.4 创建Pod并挂载ReadOnlyMany的PV 2.7 PV的回收策略测试
2.7.1 手动删除并回收卷 3 总结4 参考文献
1 概念
1.1 什么是存储卷?
在容器化环境中,因为容器的生命周期是临时的,所以伴随产生的数据默认也是临时的。当容器重启或崩溃后,其内部数据将丢失。因此,Kubernetes 引入了存储卷(Volume),为应用提实现数据持久化的能力。
1.2 存储卷的类型与使用场景
存储类型 | 描述 | 适用场景 |
---|---|---|
<code>emptyDir | Pod 生命周期内的临时存储 | 适合临时数据存储,如缓存、临时文件等。 |
hostPath | 将宿主机上的文件系统目录挂载到Pod中。 | 适用于需要访问宿主机文件系统的场景,但可能会带来宿主机与Pod间的紧耦合问题,影响Pod的调度灵活性。 |
NFS | 使用网络文件系统协议进行数据共享,适合多Pod之间共享数据。 | 多个 Pod 共享访问同一文件,适合数据共享、日志收集等。 |
块存储 | 直接使用云服务提供的块存储,支持动态创建和挂载。 | 适合在云上部署的生产环境,支持持久性和自动扩展。 |
分布式文件系统 | 这些分布式文件系统适合在高可用性和大规模集群中使用,提供更好的性能和冗余支持。 | 企业级应用、大数据处理等场景。 |
1.3 存储类(Storage Class)
在 Kubernetes 中,存储类是一个抽象,让用户无需提前准备 PV,而是根据需要由集群自动分配存储。StorageClass 决定了如何创建、配置和管理存储卷(如云盘、本地盘、NFS 等),实现按需动态分配。
简单来说,StorageClass就是一个存储策略模板,用户通过它告诉 Kubernetes:“我需要的存储资源符合这些规则,请帮我动态生成合适的存储卷。”
1.4 PV(Persistent Volume)
PV 是集群中的一个存储资源,可以由管理员创建或使用存储类动态创建,并定义了存储容量、访问模式、后端存储等规则。
以下是PV的特性:
生命周期独立于 Pod,不会因为 Pod 删除而消失。 PV 是集群级的资源,管理员负责创建。 支持多种存储类型,如本地磁盘、NFS、Cephfs等。 支持不同的访问模式,如 <code>ReadWriteOnce(一次只能一个 Pod 写入)和 ReadWriteMany
(多个 Pod 可同时写入)。
1.5 PVC (Persistent Volume Claim)
PVC 是用户对持久存储的请求声明,它规定了存储容量和访问权限等需求,并以一种抽象方法通知Kubernetes 集群,再由Kubernetes 自动匹配合适的 PV,并进行绑定。这样对用户屏蔽了后端存储,实现存储统一管理。
以下是PVC的特性:
PVC 解耦了应用与存储资源,使开发人员不需要直接处理具体的存储细节。 如果没有符合条件的 PV,PVC 会处于“待绑定”状态,直到管理员创建满足条件的 PV。 PVC类似于 Pod, Pod 消耗节点资源(CPU和内存),PVC 消耗 PV 资源,通常与PV是1对1的关系。
1.6 动态卷(Dynamic Volume Provisioning)
PV由管理员提前创建提供给用户使用,称为静态卷。
当用户在提交 PVC 时,K8S 根据 StorageClass 自动创建 PV,而不需要管理员提前准备好存储卷,称为动态卷。
当然,如果要实现动态卷, 必须设置存储类,否则Kubernetes无法创建PV,如果PVC设置<code>storageClassName字段为“”,也不会自动创建动态卷。
1.7 PV、PVC 与后端存储的关系
以“租房场景”来说明StorageClass、PV、PVC 与后端存储之间的关系。
后端存储: 物业公司(如 NFS、AWS EBS 等)是所有房源的真正提供者。它们负责实际存储资源的供应,例如:云存储、NFS、本地磁盘。StorageClass: 类似租房平台上的房型模板。它定义了不同租房规则,比如:标准单间(普通低成本存储)、豪华公寓(高性能大容量存储)、短租房(临时存储)。用户在提交租房申请(PVC)时,可以指定采用哪种房型模板(StorageClass)。根据这个模板,平台会自动生成实际的房源(PV)。PV: 类似已经发布到平台上的“具体房子”。每个 PV 是由后端存储提供的资源,例如:某间20平方的单人房(块存储),或某间共享公寓(文件存储)。PVC :租客提交的租房申请。它描述了租客希望租到的房屋类型和条件,例如:面积(容量)、入住规则(只允许一人入住,或带宠物共住)、房型要求(公寓、小区、城中村)。Kubernetes 会根据 PVC 提交的条件,自动匹配合适的 PV。如果没有符合条件的 PV,系统会根据 StorageClass 动态生成一个 PV,并绑定给 PVC。
2 实战:PV 和 PVC 的部署攻略
❔ 说明:以NFS作为后端存储,验证PV和PVC相关策略。
2.1 实验准备
nfs server系统: Ubuntu22.04Kubernetes环境: v1.29.7
2.2 部署NFS Server
安装nfs-server
<code>apt install -y nfs-kernel-server nfs-common
配置nfs, 把数据目录挂着到ssd磁盘
sudo mkdir -p /ssd/data
sudo chown nobody:nogroup /ssd/data
sudo chmod 777 /ssd/data
编辑/etc/exports文件
/ssd/data *(rw,sync)
❔ 参数说明:
/ssd/data
:指定服务器上的共享目录路径。*
:表示允许所有的客户端访问该共享。如果是业务环境要求访问限制,可以替换为特定的IP地址或子网,例如 Kubernetes集群的网段。rw
:read-write,表示客户端具有读写该共享目录的权限。如果设置为 ro
(read-only),则客户端只能读取数据,无法写入。sync
(同步写入):表示所有对该共享目录的写入操作都将同步地写入到磁盘上。客户端发起的写操作必须等到数据写入磁盘后才会被确认。如果配置为 async
,则写入操作会在数据实际写入磁盘之前就返回,这样会提高性能,但在系统崩溃时可能导致数据丢失。
重启nfs服务
systemctl enable nfs-server
systemctl restart nfs-server
查看nfs配置
exportfs -rv
输出如下:
exportfs: /etc/exports [1]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/ssd/data".
Assuming default behaviour ('no_subtree_check').
NOTE: this default has changed since nfs-utils version 1.0.x
exporting *:/ssd/data
证明配置成功
2.3 Master节点挂载测试
查看共享目录
showmount -e 192.168.3.20
输出如下:
Export list for 192.168.3.20:
/ssd/data *
创建共享目录 /mnt/share
mkdir /mnt/share
挂载nfs目录
mount -t nfs 192.168.3.200:/ssd/data /mnt/share
创建测试文件
echo “test” > /mnt/share/test.txt
创建成功,证明写入成功
卸载nfs共享目录
umount /mnt/share
2.4 创建 PV和PVC
接下来我们基于 NFS存储创建PV和PVC,验证不同的策略 :
第一个PV和PVC:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-rwo
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /ssd/data
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-rwo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
第二个PV和PVC:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-rwx
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /ssd/data
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-rwx
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
第三个PV和PVC:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-rox
spec:
capacity:
storage: 1Gi
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /ssd/data
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-rox
spec:
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 1Gi
❔ 参数说明:
PV和PVC的volumeMode保持一致:
Filesystem 模式:
当 volumeMode
设置为 Filesystem
(默认值)
时,存储卷会被挂载到Pod的一个目录中。如果存储卷是基于块设备且设备为空,Kubernetes 会在第一次挂载前自动在设备上创建一个文件系统。这种模式适合大多数应用场景,用户可以像使用普通文件系统一样访问存储卷。 Block 模式:
当 volumeMode
设置为 Block
时,存储卷会作为一个原始块设备提供给Pod,而不经过文件系统层。这意味着该卷在Pod中被暴露为一个块设备。这种模式适合需要直接访问块存储的应用,如数据库或需要最高I/O性能的应用,但应用程序必须能够处理原始块设备的数据管理。 PV和PVC的accessModes保持一致:
访问模式 | 缩写 | 描述 | 典型使用场景 |
---|---|---|---|
ReadWriteOnce | RWO | 该存储卷可以被一个节点上的Pod以读写方式挂载。当 Pod 在同一节点上运行时,ReadWriteOnce 访问模式仍然可以允许多个 Pod 访问该卷。 | 适用于单实例应用,如数据库(MySQL、PostgreSQL)。 |
ReadOnlyMany | ROX | 该存储卷可以被多个节点上的多个Pod以只读方式挂载。 | 适用于需要共享静态内容的场景,如配置文件或日志查看。 |
ReadWriteMany | RWX | 该存储卷可以被多个节点上的多个Pod以读写方式挂载。 | 适用于需要多节点并发读写的场景,如共享文件存储。 |
ReadWriteOncePod | RWOP | 该存储卷只能被一个Pod以读写方式挂载,即使在同一节点上也不能被其他Pod挂载。 1.22+ 版本后支持。 | 用于增强Pod间的独占资源访问,防止多个Pod竞争使用。 |
PV的ReclaimPolicy
回收策略 | 描述 | 适用场景 |
---|---|---|
Retain | 保留数据,即使PVC被删除,PV中的数据仍会被保留,需要手动清理或重新绑定PVC。 | 适用于需要数据持久保留的场景,如数据库或备份存储。 |
Delete | 删除PV和存储资源。当PVC被删除时,Kubernetes会自动删除PV及其对应的存储资源。 | 适用于临时数据或不需要保留的数据,如测试环境。 |
Recycle (已废弃) | 清空数据并将PV重置为Available状态,以便被新的PVC绑定。此功能在Kubernetes 1.11之后已废弃。 | 已不推荐使用,Kubernetes 1.11版本之前的旧集群可能仍支持。 |
创建三个PV和PVC
kubectl apply -f pv-rwo.yaml
kubectl apply -f pv-rwm.yaml
kubectl apply -f pv-rom.yaml
2.5 观察PV和PVC的状态
查看PV状态
kubectl get pv
输出如下:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-rox 1Gi ROX Retain Available <unset> 11s
pv-rwo 1Gi RWO Delete Available <unset> 106s
pv-rwx 1Gi RWX Retain Available <unset> 42s
查看PVC状态
kubectl get pvc
输出如下:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
pvc-rox Bound pvc-e32cf856-b00b-4012-a25a-74c82ba8f092 1Gi ROX nfs-class <unset> 2m9s
pvc-rwo Bound pvc-c864776b-5811-452f-9e98-f50466922be2 1Gi RWO nfs-class <unset> 3m44s
pvc-rwx Bound pvc-7bebb579-5f8a-4994-a7a8-02bde0d651c2 1Gi RWX nfs-class <unset> 2m41s
❔ 说明:PV和PVC的生命周期
PV的 生命周期状态表:
生命周期阶段 | 状态描述 |
---|---|
Available | PV已创建且未绑定到任何PVC,表示可供PVC使用。 |
Bound | PV已绑定到一个PVC,表示正在被使用。 |
Released | PVC被删除后,PV进入Released状态,表示PV已经释放,但资源尚未被重新使用,数据仍可能存在。 |
Failed | PV无法绑定到PVC,或回收过程中出现错误。通常需要管理员手动干预修复。 |
Reclaim | 根据persistentVolumeReclaimPolicy 配置,PV的回收策略可以是Retain、Recycle或Delete。 |
PVC的生命周期:
生命周期阶段 | 状态描述 |
---|---|
Pending | PVC已创建,但尚未找到合适的PV进行绑定。 |
Bound | PVC已成功绑定到一个PV,存储资源可以被Pod使用。 |
Lost | PV被删除或失效,PVC进入Lost状态,表示无法继续访问存储资源。通常需要管理员处理。 |
2.6 Pod挂载不同PVC测试
2.6.1 创建Pod并挂载ReadWriteOnce的PV
将PVC pvc-rwo
挂载到nginx1:
apiVersion: v1
kind: Pod
metadata:
name: nginx1
spec:
containers:
- name: nginx1
image: harbor.zx/hcie/nginx:1.27.1
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-config
volumes:
- name: my-configvim
persistentVolumeClaim:
claimName: pvc-rwo
创建pod
kubectl apply -f nginx1.yaml
尝试再创建一个Pod nginx2
,使用同一个PVC,观察PVC挂载情况。
apiVersion: v1
kind: Pod
metadata:
name: nginx2
spec:
containers:
- name: nginx2
image: harbor.zx/hcie/nginx:1.27.1
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-config
volumes:
- name: my-config
persistentVolumeClaim:
claimName: pvc-rwo
查看pod的状态
kubectl get pod -owide
输出如下:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx1 1/1 Running 0 66m 172.16.135.207 k8s-master3 <none> <none>
nginx2 1/1 Running 0 61m 172.16.126.55 k8s-worker2 <none> <none>
❓ 思考: 测试发现,无论nginx1与nginx2运行在同一工作节点或不同工作节点上都能正常读写。
这里推测,虽然Kubernetes的ReadWriteOnce
模式限制了跨节点的读写访问,但某些存储系统(如NFS)本身是支持多节点并发访问的。因此即使Kubernetes中的访问模式配置为ReadWriteOnce
,NFS协议也不强制执行这种访问限制。
2.6.2 创建Pod并挂载ReadWriteOncePod的PV
现在将nginx1、nginx2删除:
kubectl delete -f nginx1.yaml
kubectl delete -f nginx2.yaml
kubectl delete -f pv-rwo.yaml
将第一个PV和PVC的策略改为ReadWriteOncePod
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-rwo
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOncePod
persistentVolumeReclaimPolicy: Retain
nfs:
path: /ssd/data
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-rwo
spec:
accessModes:
- ReadWriteOncePod
resources:
requests:
storage: 1Gi
创建pv和pvc
kubectl apply -f pv-rwo.yaml
创建nginx1和nginx2
kubectl apply -f nginx1.yaml
kubectl apply -f nginx2.yaml
查看pod
kubectl get pod
输出如下:
NAME READY STATUS RESTARTS AGE
nginx1 1/1 Running 0 67s
nginx2 0/1 Pending 0 66s
这时nginx2状态是“Pending”
出现无法挂载的情况。
nginx2详细信息如下:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 12s default-scheduler 0/5 nodes are available: 1 node has pod using PersistentVolumeClaim with the same name and ReadWriteOncePod access mode, 4 node(s) didn't match Pod's node affinity/selector. preemption: 0/5 nodes are available: 1 No preemption victims found for incoming pod, 4 Preemption is not helpful for scheduling.
可以看到nginx2无法挂载是因为 ReadWriteOncePod
只允许一个Pod挂载。为了做好存储访问控制,可以考虑使用其他存储插件或者存储系统。另外,可以使用ReadWriteOncePod
(RWOP)访问模式来替代ReadWriteOnce
,该模式在Kubernetes 1.22及更高版本中可用,能够限制PV只能被一个Pod挂载,即使在同一节点上也不允许其他Pod使用。
2.6.3 创建Pod并挂载ReadWriteMany的PV
现在将nginx1、nginx2删除:
kubectl delete -f nginx1.yaml
kubectl delete -f nginx2.yaml
修改成pv-rwx的pvc
volumes:
- name: my-config
persistentVolumeClaim:
claimName: pvc-rwx
重新创建nginx1、nginx2
kubectl apply -f nginx1.yaml
kubectl apply -f nginx2.yaml
nginx1测试读写
[root@k8s-master1 ~]# kubectl exec -it nginx1 -- bash
root@nginx1:/# echo "nginx1" >>/usr/share/nginx/html/nginx1
root@nginx1:/# cat /usr/share/nginx/html/nginx1
nginx1
nginx2测试读写
[root@k8s-master1 ~]# kubectl exec -it nginx2 -- bash
root@nginx2:/# echo "nginx2" >>/usr/share/nginx/html/nginx2
root@nginx2:/# cat /usr/share/nginx/html/nginx2
nginx2
证明一个pv可以共享挂载给多个Pod。
2.6.4 创建Pod并挂载ReadOnlyMany的PV
现在将nginx1、nginx2删除:
kubectl delete -f nginx1.yaml
kubectl delete -f nginx2.yaml
Pod修改成pv-rox的pvc
containers:
- name: nginx1
image: harbor.zx/hcie/nginx:1.27.1
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: my-config
readOnly: true
volumes:
- name: my-config
persistentVolumeClaim:
claimName: pvc-rox
重新创建nginx1、nginx2
kubectl apply -f nginx1.yaml
kubectl apply -f nginx2.yaml
查看nginx1详细信息,执行以下命令:
kubectl describe pod nginx1
输出如下:
Containers:
nginx1:
Container ID: containerd://28659839ee65b3be6579dd5d519ebcd89fefbf05e9908feb21b504728c19527a
Image: harbor.zx/hcie/nginx:1.27.1
Image ID: harbor.zx/hcie/nginx@sha256:127262f8c4c716652d0e7863bba3b8c45bc9214a57d13786c854272102f7c945
Port: <none>
Host Port: <none>
State: Running
Started: Thu, 17 Oct 2024 10:16:53 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/usr/share/nginx/html from my-config (ro)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vcmlw (ro)
存储卷是以只读访问方式挂载。
nginx1测试写
[root@k8s-master1 ~]# kubectl exec -it nginx1 -- bash
root@nginx1:/# echo "nginx1" >>/usr/share/nginx/html/nginx1
输出如下:
bash: /usr/share/nginx/html/nginx1: Read-only file system
证明该存储卷是只读。
nginx2测试读
[root@k8s-master1 ~]# kubectl exec -it nginx2 -- bash
root@nginx2:/# cat /usr/share/nginx/html/nginx2
nginx2
root@nginx2:/# cat /usr/share/nginx/html/nginx1
nginx1
证明一个pv可以“只读”方式共享给多个Pod
2.7 PV的回收策略测试
❔ 说明: 因为
Recycle
策略已经被丢弃了, 所以只验证Retain
和Delete
两种策略类型。
登录nfs-server,创建卷目录
mkdir /ssd/data/{ retain,delete}
编写Retain卷文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-retain
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /ssd/data/retain
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-retain
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ""
编写Delete卷文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-delete
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
nfs:
path: /ssd/data/delete
server: 192.168.3.20
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-delete
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ""
创建存储卷
kubectl apply -f pv-retain.yaml
kubectl apply -f pv-delete.yaml
创建pod测试
apiVersion: v1
kind: Pod
metadata:
name: pod-retain
spec:
containers:
- name: busybox
image: harbor.zx/library/busybox:1.29-2
command: ["sh", "-c", "echo 'Hello from Retain' > /mnt/data/test.txt; sleep 3600"]
volumeMounts:
- mountPath: /mnt/data
name: volume
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc-retain
---
apiVersion: v1
kind: Pod
metadata:
name: pod-delete
spec:
containers:
- name: busybox
image: harbor.zx/library/busybox:1.29-2
command: ["sh", "-c", "echo 'Hello from Delete' > /mnt/data/test.txt; sleep 3600"]
volumeMounts:
- mountPath: /mnt/data
name: volume
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc-delete
执行以下命令创建两个Pod:
kubectl apply -f pv-test.yaml
删除pod
、pvc-retain
和pvc-delete
,观察PV的状态变化。
kubectl delete pod pod-retain
kubectl delete pod pod-delete
kubectl delete pvc pvc-retain
kubectl delete pvc pvc-delete
观察pv的回收状态,执行以下命令:
kubectl get pv -w
输出如下:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
3m33s
pv-retain 1Gi RWO Retain Bound default/pvc-reta in <unset> 3m34s
...
pv-retain 1Gi RWO Retain Released default/pvc-reta in <unset>
---
pv-delete 1Gi RWO Delete Bound default/pvc-dele te <unset> 4m42s
...
pv-delete 1Gi RWO Delete Released default/pvc-dele te <unset> 4m41s
pv-delete 1Gi RWO Delete Failed default/pvc-dele te <unset> 4m41s
pv状态从Bound到Released, 但是Delete策略回收nfs的存储卷失败。
查看nfs底层数据
root@ub22:/ssd/data# ls -l delete/
total 4
-rw-r--r-- 1 nobody nogroup 18 10月 17 11:27 test.txt
root@ub22:/ssd/data# ls -l retain/
total 4
-rw-r--r-- 1 nobody nogroup 18 10月 17 11:27 test.txt
底层的数据没有被删除。
2.7.1 手动删除并回收卷
查看pv-delete详细信息
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning VolumeFailedDelete 6m2s persistentvolume-controller error getting deleter volume plugin for volume "pv-delete": no deletable volume plugin matched
因为我并没有使用nfs的provider进行管理导致,所以不支持nfs存储卷删除操作。
登录NFS服务器,手动删除PV对应的目录。例如:
# 登录到NFS服务器,手动删除目录
rm -rf /ssd/data/delete
然后删除PV资源:
kubectl delete pv pv-delete
或者,使用Finalizer强制删除PV
如果PV已经标记为Failed
,可以尝试移除PV的finalizer
以强制删除:
kubectl patch pv pv-delete -p '{"metadata":{"finalizers":null}}'
3 总结
Kubernetes 通过PV和PVC的方式提供了后端存储统一管理和灵活存储的解决方案,在实际生产环境中,您可以根据业务需求选择合适的存储类型,并制定完善的数据备份方案,是确保系统稳定运行的关键。
4 参考文献
Kubernetes 官方文档 NFS 存储配置
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。