文章目录
- 一、PV、PVC持久化存储理论
 - 1、PV、PVC是什么?
 - 2、PV的供应方式
 - 3、PV、PVC的回收策略
 
- 二、案例:PV、PVC持久化存储案例演示
 - 1、搭建NFS服务端
 - 2、创建PV,并使用NFS共享存储
 - 3、创建PVC,并和PV绑定
 - 4、创建Pod,并挂载PVC卷
 - 5、删除PVC正确步骤
 
一、PV、PVC持久化存储理论
官方中文参考文档:
1、PV、PVC是什么?
- PersistentVolume(PV)是群集中的一块存储,可以是NFS、iSCSI、本地存储等,由管理员配置或使用存储类动态配置。 PV定义了存储的容量、访问模式、持久化存储的类型等属性。PV的生命周期是独立于Pod的,即使Pod被删除,PV仍然存在,可以被其他Pod继续使用。
 - PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建pod时可以定义PVC类型的存储卷,PVC可以用来访问各种类型的持久化存储,如本地存储、网络存储、云存储等,而不必关心这些资源的实际位置和类型,PVC的使用可以使应用程序更加灵活和可移植,同时也可以提高存储资源的利用率。
 - PVC和PV它们是一一对应的关系,PV如果被PVC绑定了,就不能被其他PVC使用了。
 
2、PV的供应方式
两种分别为静态、动态:
- 静态供应:管理员手动创建PV对象,并将其绑定到一个具体的存储后端上,然后Pod可以通过PVC(Persistent Volume Claim)请求绑定到该PV上。
 - 动态供应:管理员通过StorageClass定义一组存储后端,然后Pod可以通过PVC请求绑定到该StorageClass上,K8s会自动创建一个PV对象并将其绑定到一个可用的存储后端上。
 
3、PV、PVC的回收策略
当我们创建pod时如果使用pvc做为存储卷,那么它会和pv绑定,当删除pod,pvc和pv绑定就会解除,解除之后和pvc绑定的pv卷里的数据需要怎么处理 有以下几种:
Kubernetes中有三种PV回收策略:
- Retain:保留PV,但不删除底层存储资源。这意味着PV中的数据仍然存在,但需要手动清理。
 - Delete:删除PV和底层存储资源。这意味着PV中的数据将被永久删除。
 - Recycle:删除PV中的数据,但不删除底层存储资源。这意味着PV中的数据将被清除,但底层存储资源可以重新使用。(不推荐,1.15可能被移除)
 
Kubernetes中有两种PVC回收策略:
- Retain:保留PVC,但不删除底层存储资源。这意味着PVC中的数据仍然存在,但需要手动清理。
 - Delete:删除PVC和底层存储资源。这意味着PVC中的数据将被永久删除。
 
需要注意的是,PVC的回收策略必须与其所绑定的PV的回收策略相匹配。例如,如果PV的回收策略为Retain,则PVC的回收策略也必须为Retain。否则,可能会导致数据丢失或存储资源泄漏。
二、案例:PV、PVC持久化存储案例演示
1、搭建NFS服务端
PV使用NFS做为存储。
注意:K8S集群所有节点都需要安装 nfs-utils
yum install nfs-utils -y
mkdir /data/volumes/v{1..3} -p
vim /etc/exports
/data/volumes/v1 *(rw,no_root_squash)
/data/volumes/v2 *(rw,no_root_squash)
/data/volumes/v3 *(rw,no_root_squash)
 
加载配置生效 && 启动NFS服务
exportfs -arv
systemctl enable nfs --now
 
在其他Node节点上面测试 NFS 是否可以正常挂载:
yum install nfs-utils -y
mkdir /test
mount 16.32.15.200:/data/volumes/v1 /test
df -hT /test/
 
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ekJ4U0X0-1686473061750)(D:\MD归档文档\IMG\image-20230611135004109.png)]](https://img-blog.csdnimg.cn/d2b17c8ceeb54fa1917dea8a20a38ca2.png)
OK,如上图NFS可以正常挂载,表示到此,NFS 配置无问题。
2、创建PV,并使用NFS共享存储
创建三个PV,分别使用不通目录,不通访问模块,YAML如下:
cat pv.yaml 
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1
  labels:
    app: pv-1
spec:
  nfs:
    path: /data/volumes/v1   # PV使用NFS路径
    server: 16.32.15.200     # NFS 服务端IP地址
  accessModes: ["ReadWriteOnce"]  # 访问模式: ReadWriteOnce,卷可以被一个节点以读写方式挂载
  capacity:
    storage: 1Gi                  # 存储大小
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-2
  labels:
    app: pv-2
spec:
  nfs:
    path: /data/volumes/v2
    server: 16.32.15.200
  accessModes: ["ReadOnlyMany"] # 访问模式: ReadOnlyMany,可以被多个节点只读方式挂载
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-3
  labels:
    app: pv-3
spec:
  nfs:
    path: /data/volumes/v3
    server: 16.32.15.200
  accessModes: ["ReadWriteMany"] # 访问模式: ReadWriteMany,可以被多个节点读写方式挂载
  capacity:
    storage: 3Gi
...
 
访问模式解释:
- ReadWriteOnce:被一个节点,已读写方式挂载(官方解释,但是无法体现出来,应该是BUG)。
 - ReadOnlyMany:被多个节点,已只读方式挂载。
 - ReadWriteMany:被多个节点,已读写方式挂载。
 
执行YAML 文件:
kubectl apply -f pv.yaml
 
查看创建出来的PV资源:
kubectl get pv
 
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qIdR6GdY-1686473061751)(D:\MD归档文档\IMG\image-20230611140856919.png)]](https://img-blog.csdnimg.cn/8bff937bd43f418bb47c8e0142179b9b.png)
3、创建PVC,并和PV绑定
创建三个PVC和,上面三个PV进行绑定 YAML 如下:
cat pvc.yaml 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-1
  labels:
    app: pvc-1
spec:
  accessModes: ["ReadWriteOnce"]   # PVC访问模式,必须和PV访问模式一致
  selector:
    matchLabels:
      app: pv-1                   # 标签选择器,选择具有 app=pv-1 PV绑定
  resources: 
    requests: 
      storage: 1Gi                # 容量,必须和PV容量保持一致
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-2
  labels:
    app: pvc-2
spec:
  accessModes: ["ReadOnlyMany"]
  selector:
    matchLabels:
      app: pv-2
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-3
  labels:
    app: pvc-3
spec:
  accessModes: ["ReadWriteMany"]
  selector:
    matchLabels:
      app: pv-3
  resources:
    requests:
      storage: 3Gi
...
 
执行 YAML 清单文件:
kubectl apply -f pvc.yaml
 
查看PVC 是否与 PV 相关联:
kubectl get pvc
 
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TQTsbz18-1686473061752)(D:\MD归档文档\IMG\image-20230611151351851.png)]](https://img-blog.csdnimg.cn/8153a58d8e8a48c29cbf8deeeed7105b.png)
4、创建Pod,并挂载PVC卷
cat pod-pvc.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pvc-test
  labels:
    app: pvc-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: pvc-test
  template:
    metadata:
      labels:
        app: pvc-test
    spec:
      volumes:
      - persistentVolumeClaim:     # 使用PVC类型
          claimName: pvc-2         # 指定使用PVC名字
        name: web-html-path        # 卷名称
      containers:
      - name: pvc-test
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: web-html-path      # 使用卷名称,和上面卷名称对应上
          mountPath: /usr/share/nginx/html  # 容器内挂载目录
 
执行YAML 文件:
kubectl apply -f pod-pvc.yaml 
 
我们使用的是只读权限的 pvc-2,对应目录是 /data/volumes/v2/,在目录中添加 index.html 文件
echo "PVC-DEMO" > /data/volumes/v2/index.html
 
访问Pod 网站:
kubectl get pods -o wide
 
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NZN6DVxq-1686473061752)(D:\MD归档文档\IMG\image-20230611161521242.png)]](https://img-blog.csdnimg.cn/046cd8a178cd4d9e86f1e593c3750285.png)
我们进入容器里面创建文件试试:
kubectl exec -it pvc-test-d65964fd4-jmkmg -- /bin/bash
 
如下图,我是用的是只读的 PVC,容器里面应当没有创建文件权限,但是容器里面确实可以创建文件,我咨询了云原生领域大佬,这应该是K8S PVC bug,我当前K8S版本是:v1.27.0
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbyw4p4M-1686473061752)(D:\MD归档文档\IMG\image-20230611161652570.png)]](https://img-blog.csdnimg.cn/8e0b01463a3340e39c47eeace6f5341d.png)
5、删除PVC正确步骤
-  
pvc和pv绑定,如果使用默认的回收策略retain,那么删除pvc之后,pv会处于released状态,我们想要继续使用这个pv,需要手动删除pv,kubectl delete pv pv_name,删除pv,不会删除pv里的数据,当我们重新创建pvc时还会和这个最匹配的pv绑定,数据还是原来数据,不会丢失。
 -  
经过测试,如果回收策略是Delete,删除pv,pv后端存储的数据也不会被删除。
 -  
回收策略字段:
pv.spec.persistentVolumeReclaimPolicy字段 
第一步:首先删除使用 PVC 的 Pod
第二步:删除PVC
第三步:删除PV



















