PV/PVC(PersistentVolume/PersistentVolumeClaim)是生产中最常用的存储方式,其实底层使用的还是各类存储如文件系统/块等。PV通过不同的存储API去对接不同类型的存储,而PVC并不关心这些内容,我个人理解有点类似于存储池和lun的关系,只不过pv和pvc是一一对应的。
![[kubernetes] 持久化存储之静态PV/PVC_nginx](https://file.cfanz.cn/uploads/png/2022/03/31/23/2c840XcP75.png)
所谓的静态PV/PVC,指的是在使用之前需要手动创建PV/PVC,而动态的方式则是由StorageClass实现,我们只需要创建PVC,PV就会被自动创建。
PV是独立于pod的生命周期的,目前PV可以支持以下存储:
GCEPersistentDisk
AWSElasticBlockStore
AzureFile
AzureDisk
FC (Fibre Channel)
Flexvolume
Flocker
NFS
iSCSI
RBD (Ceph Block Device)
CephFS
Cinder (OpenStack block storage)
Glusterfs
VsphereVolume
Quobyte Volumes
HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
Portworx Volumes
ScaleIO Volumes
StorageOS
01 创建PV
本节实验使用nfs来作为底层存储,nfs的配置略过。
1)创建PV
cat pv-demo.yaml 
apiVersion: v1
kind: PersistentVolume  # PV
metadata:
  name: pv1
  labels: 
    name: pv1
spec: 
  nfs:   # 存储类型
    path: /data/nfs-volume/pv1  # nfs路径
    server: host200   # nfs主机
  accessModes: ["ReadWriteMany","ReadWriteOnce"]  # 访问模式
  capacity:   # 存储大小
    storage: 1Gi2)应用和查看PV -- PV是不区分namespace的
[root@host21 pv]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv1 created
[root@host21 pv]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWO,RWX        Retain           Available                                   3s3)字段详解
ACCESS MODES:访问模式,这个比较重要,PVC的权限不能设置比PV还大。
(RWO) ReadWriteOnce 可被一个节点读写挂载
(ROX) ReadOnlyMany 可被多个节点只读挂载
(RWX) ReadWriteMany 可被多个节点读写挂载
RECLAIM PLICY:回收策略,pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。默认是Retain
- 保留策略:允许人工处理保留的数据。
 - 删除策略:将删除pv和外部关联的存储资源,需要插件支持。
 - 回收策略:将执行清除操作,之后可以被新的pvc使用,需要插件支持。
STATUS:PV状态
Available – 资源尚未被claim使用
Bound – 卷已经被绑定到claim了
Released – claim被删除,卷处于释放状态,但未被集群回收。
Failed – 卷自动回收失败
CLAIM:绑定的PVC
STORAGECLASS:所属的SC
4)删除PV
[root@host21 pv]# kubectl delete -f pv-demo.yaml 
persistentvolume "pv1" deleted02 创建PVC
    创建PVC来消费PV,这里可以指定PV,也可以不指定PV,如果不指定的话会动态选择一个满足条件的PV。
 1)资源配置清单
cat pvc-demo.yaml 
apiVersion: v1
kind: PersistentVolumeClaim  # PVC
metadata:
  name: pvc1
spec:
  accessModes: ["ReadWriteMany"]  # 访问模式
  resources:
    requests:
      storage: 1Gi  # 大小
  selector:   # 指定pv
    matchLabels:
      name: pv12)应用和查看
[root@host21 pv]# kubectl apply -f pvc-demo.yaml 
[root@host21 pv]# kubectl get pvc
NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1   Bound    pv1      1Gi        RWO,RWX                       3m5s
[root@host21 pv]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   REASON   AGE
pv1    1Gi        RWO,RWX        Retain           Bound    default/pvc1                           7m36s 3)字段详解
 STATUS:PVC状态
 - Pending :未绑定到PV
 - Bound:已绑定到PV
 VOLUME:绑定的PV名称
 其余参数和PV一致,这里不进行说明。
 4)删除pvc -- 可以看到这时候pv就变为了Released状态
[root@host21 pv]# kubectl delete -f pvc-demo.yaml 
persistentvolumeclaim "pvc1" deleted
[root@host21 pv]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM          STORAGECLASS   REASON   AGE
pv1    1Gi        RWO,RWX        Retain           Released   default/pvc1                           8m9s
[root@host21 pv]# kubectl get pvc
No resources found.5)PV和PVC操作状态变化图如下:
![[kubernetes] 持久化存储之静态PV/PVC_sed_02](https://file.cfanz.cn/uploads/png/2022/03/31/23/211890d28G.png)
03 PV/PVC简单应用
实验图:
![[kubernetes] 持久化存储之静态PV/PVC_nginx_03](https://file.cfanz.cn/uploads/png/2022/03/31/23/99YL005139.png)
1)创建资源配置清单
[root@host21 pv]# cat nginx-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-web
spec:
  volumes:   # volume name
    - name: nginx-html
      persistentVolumeClaim:
        claimName: nginx-html-pvc  # pvc name
  containers:
  - name: nginx-pvc
    image: harbor.od.com/public/nginx:v1.7.9
    volumeMounts:
    - name: nginx-html   # volume name name
      mountPath: /usr/share/nginx/html  # target dir name
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-html-pvc
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      name: nginx-html-pv  # pv name
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-html-pv
  labels: 
    name: nginx-html-pv
spec: 
  nfs: 
    path: /data/nfs-volume/pv3
    server: host200
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity: 
    storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    name: nginx-web2)应用和测试
[root@host21 pv]# kubectl apply -f nginx-demo.yaml 
pod/nginx-web created
persistentvolumeclaim/nginx-html-pvc created
persistentvolume/nginx-html-pv created
service/nginx-svc created
[root@host21 pv]# kubectl get all | grep nginx
pod/nginx-web   1/1     Running   0          2m4s
service/nginx-svc      ClusterIP   10.254.58.245   <none>        80/TCP    2m4s
# 测试
[root@host21 pv]# curl 10.254.58.245
pv33)删除资源
[root@host21 pv]# kubectl delete -f nginx-demo.yaml 
pod "nginx-web" deleted
persistentvolumeclaim "nginx-html-pvc" deleted
persistentvolume "nginx-html-pv" deleted
service "nginx-svc" deleted04 实践出真知
1)PVC的容量是否可以比PV大? -- 不可以
# pv 为1Gi
[root@host21 pv]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv1    1Gi        RWO,RWX        Retain           Available                                   13m
# 创建pvc为1.2Gi
[root@host21 pv]# cat pvc-demo.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 1.2Gi
# 应用
[root@host21 pv]# kubectl apply -f pvc-demo.yaml 
persistentvolumeclaim/pvc1 created
[root@host21 pv]# kubectl get pvc
NAME   STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc1   Pending                                                     12s
# 可以看到pvc一直处于Pending状态
# kubect describe pvc pvc1![[kubernetes] 持久化存储之静态PV/PVC_sed_04](https://file.cfanz.cn/uploads/png/2022/03/31/23/S75ZcdfcP8.png)
可见没有符合条件的PV。
2)PVC设置的权限可以比PV设置的大吗? -- 不可以
# PV访问模式诶ROX
[root@host21 pv]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM          STORAGECLASS   REASON   AGE
pv1    1Gi        ROX            Retain           Available                                          97s
# PVC访问模式为RWX
[root@host21 pv]# cat pvc-demo.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      name: pv1
# pvc一直处于pending状态,没有符合的pv![[kubernetes] 持久化存储之静态PV/PVC_nginx_05](https://file.cfanz.cn/uploads/png/2022/03/31/23/U306b72bfH.png)
3)PV可以先于PVC删除吗?- 不可以,删除任务会一直卡在Terminating状态。
![[kubernetes] 持久化存储之静态PV/PVC_nginx_06](https://file.cfanz.cn/uploads/png/2022/03/31/23/3c9K8c56Fc.png)
删除了pvc后,卡在terminating会继续执行删除任务。
![[kubernetes] 持久化存储之静态PV/PVC_html_07](https://file.cfanz.cn/uploads/png/2022/03/31/23/J790600768.png)
4)被pod使用了的pvc可以先于pod删除吗? -- 不可以,原因和3一样,删除是有顺序的,删除资源时需要从上往下删。
5)删除了pvc后,pv处于Released,这时候该pv就不能被pvc关联了,也就意味着这个pv的数据无法再使用,怎么解决这个问题?-- 通过修改pv的yaml文件,将pv记录的pvc内容删除掉即可再次给新pv使用。
# 使用nginx-demo.yaml进行测试
[root@host21 pv]# kubectl get pv,pvc,pod,svc
NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
persistentvolume/nginx-html-pv   1Gi        RWO,RWX        Retain           Bound    default/nginx-html-pvc                           16s
NAME                                   STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nginx-html-pvc   Bound    nginx-html-pv   1Gi        RWO,RWX                       16s
NAME            READY   STATUS              RESTARTS   AGE
pod/nginx-web   0/1     ContainerCreating   0          16s
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/nginx-svc    ClusterIP   10.254.233.79   <none>        80/TCP    16s
# 测试文件
[root@host21 pv]# curl 10.254.233.79
pv3
# 删除pod
[root@host21 pv]# kubectl delete pod/nginx-web
[root@host21 pv]# kubectl get pod
No resources found.
# 删除pvc,这时候pv处于Released状态
[root@host21 pv]# kubectl delete pvc nginx-html-pvc
persistentvolumeclaim "nginx-html-pvc" deleted
[root@host21 pv]# kubectl get pvc
No resources found.
[root@host21 pv]# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                    STORAGECLASS   REASON   AGE
nginx-html-pv   1Gi        RWO,RWX        Retain           Released   default/nginx-html-pvc                           2m17s
# 重新生成pvc,看看是否能绑定pv
[root@host21 pv]# kubectl apply -f nginx-demo.yaml 
pod/nginx-web created
persistentvolumeclaim/nginx-html-pvc created
persistentvolume/nginx-html-pv unchanged
service/nginx-svc unchanged
# 查看pvc和pod状态  - 可以看到pvc一直处于pending状态,导致pod也无法启动
[root@host21 pv]# kubectl get pvc
NAME             STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nginx-html-pvc   Pending                                                     28s
[root@host21 pv]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-web   0/1     Pending   0          31s
[root@host21 pv]# 
# 修改pv的配置文件,将红色框住的部分删除,并保存退出
[root@host21 pv]# kubectl edit pv nginx-html-pvc![[kubernetes] 持久化存储之静态PV/PVC_html_08](https://file.cfanz.cn/uploads/png/2022/03/31/23/602B1aF8XD.png)
# 可以看到pv处于Bound状态了,如果没有pvc绑定,就处于Available状态。
[root@host21 pv]# kubectl edit pv nginx-html-pv
persistentvolume/nginx-html-pv edited
[root@host21 pv]# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS   REASON   AGE
nginx-html-pv   1Gi        RWO,RWX        Retain           Bound    default/nginx-html-pvc                           8m27s
# 查看pvc和pod,并测试内容
[root@host21 pv]# kubectl get pvc,pod
NAME                                   STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nginx-html-pvc   Bound    nginx-html-pv   1Gi        RWO,RWX                       4m13s
NAME            READY   STATUS    RESTARTS   AGE
pod/nginx-web   1/1     Running   0          4m13s
[root@host21 pv]# curl 10.254.233.79
pv3![[kubernetes] 持久化存储之静态PV/PVC_html_09](https://file.cfanz.cn/uploads/jpeg/2022/03/30/8/O21Z92Off4.jpeg)










