k8s环境参考: k8s-v1.20.10 二进制部署指导文档
PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿主系统上。 如下表所示,提供者(驱动)的能力不同,每个 PV 卷的访问模式都会设置为 对应卷所支持的模式值。 例如,NFS 可以支持多个读写客户,但是某个特定的 NFS PV 卷可能在服务器 上以只读的方式导出。每个 PV 卷都会获得自身的访问模式集合,描述的是 特定 PV 卷的能力
模式 | 作用 |
---|---|
ReadWriteOnce | 卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷 |
ReadOnlyMany | 卷可以被多个节点以只读方式挂载 |
ReadWriteMany | 卷可以被多个节点以读写方式挂载 |
ReadWriteOncePod | 卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本 |
在命令行接口(CLI)中,访问模式也使用以下缩写形式:
当用户不再使用其存储卷时,他们可以从 API 中将 PVC 对象删除,从而允许该资源被回收再利用
。PersistentVolume 对象的回收策略告诉集群,当其被从申领中释放时如何处理该数据卷。 目前,数据卷可以被 Retained(保留)、Recycled(回收)或 Deleted(删除)
保留(Retain)
回收策略 Retain
使得用户可以手动回收资源。当 PersistentVolumeClaim 对象 被删除时,PersistentVolume 卷仍然存在,对应的数据卷被视为"已释放(released)
"。 由于卷上仍然存在这前一申领人的数据,该卷还不能用于其他申领
。 管理员可以通过下面的步骤来手动回收该卷:
删除(Delete)
对于支持 Delete
回收策略的卷插件,删除动作会将 PersistentVolume 对象从 Kubernetes 中移除,同时也会从外部基础设施(如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)中移除所关联的存储资产。 动态供应的卷会继承其 StorageClass 中设置的回收策略,该策略默认 为 Delete
。 管理员需要根据用户的期望来配置 StorageClass;否则 PV 卷被创建之后必须要被 编辑或者修补。参阅更改 PV 卷的回收策略
回收(Recycle)
回收策略 Recycle
已被废弃。取而代之的建议方案是使用动态供应
如果下层的卷插件支持,回收策略 Recycle
会在卷上执行一些基本的 擦除(rm -rf /thevolume/*
)操作,之后允许该卷用于新的 PVC 申领
PersistentVolume(PV)是群集中的一块存储(类似一块磁盘)
,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像节点是集群资源一样。 PV是容量插件,如Volumes,但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息,包括NFS,iSCSI或特定于云提供程序的存储系统PersistentVolumeClaim(PVC)是一个持久化存储卷
,我们在创建pod时可以定义这个类型的存储卷。 它类似于一个pod。 Pod消耗节点资源,PVC消耗PV资源
。 Pod可以请求特定级别的资源(CPU和内存)。 pvc在申请pv的时候也可以请求特定的大小和访问模式(例如,可以一次读/写或多次只读)PV是集群类型资源,不需要定义Name Space
PVC 状态
使用NFS作为后端存储,这里使用k8s-node-1作为nfs服务器
# 在nfs中导出多个存储目录,在nfs服务器上操作
mkdir /data/k8s-nfs/volume{1,2,3} -p
cat /etc/exports
/data/k8s-nfs/volume1 192.168.0.0/24(rw,no_root_squash)
/data/k8s-nfs/volume2 192.168.0.0/24(rw,no_root_squash)
/data/k8s-nfs/volume3 192.168.0.0/24(rw,no_root_squash)
EOF
exportfs -arv # 使配置文件生效
systemctl start rpcbind && systemctl restart nfs
# 定义PV,pv是集群级别的资源,不需要定义namespace
[root@k8s-master-1 pv-pvc]# cat pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvc-volume-1
spec:
volumeMode: Filesystem
accessModes: ["ReadOnlyMany"]
persistentVolumeReclaimPolicy: Retain
capacity:
storage: 2Gi
nfs:
path: /data/k8s-nfs/volume1
server: 192.168.0.11
readOnly: false
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvc-volume-2
spec:
volumeMode: Filesystem
accessModes: ["ReadWriteMany","ReadWriteOnce"]
persistentVolumeReclaimPolicy: Retain
capacity:
storage: 3Gi
nfs:
path: /data/k8s-nfs/volume2
server: 192.168.0.11
readOnly: false
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvc-volume-3
spec:
volumeMode: Filesystem
accessModes: ["ReadWriteMany","ReadWriteOnce"]
persistentVolumeReclaimPolicy: Retain
capacity:
storage: 5Gi # 申请多大的PV,去PV中申请资源,如果没有2GI的,会去找最近大于一个2GI的
nfs:
path: /data/k8s-nfs/volume3
server: 192.168.0.11
readOnly: false
# 查看PV
[root@k8s-master-1 pv-pvc]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-volume-1 2Gi ROX Retain Available 58s
pvc-volume-2 3Gi RWO,RWX Retain Available 58s
pvc-volume-3 5Gi RWO,RWX Retain Available 58s
# 定义PVC
[root@k8s-master-1 pv-pvc]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes: ["ReadWriteMany"]
resources: #如果 Pod 运行所在的节点具有足够的可用资源,容器可能(且可以)使用超出对应资源 request 属性所设置的资源量。不过,容器不可以使用超出其资源 limit 属性所设置的资源量
requests:
storage: 3Gi
# 查看PVC
[root@k8s-master-1 pv-pvc]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Bound pvc-volume-2 3Gi RWO,RWX 3s
[root@k8s-master-1 pv-pvc]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-volume-1 2Gi ROX Retain Available 9m55s
pvc-volume-2 3Gi RWO,RWX Retain Bound default/my-pvc 9m55s
pvc-volume-3 5Gi RWO,RWX Retain Available
# 删除当前PVC,然后重新生成PVC,然后又删除PVC,会导致pvc-volume-2,pvc-volume-3都处于release状态
[root@k8s-master-1 pv-pvc]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-volume-1 2Gi ROX Retain Available 11m
pvc-volume-2 3Gi RWO,RWX Retain Released default/my-pvc 11m
pvc-volume-3 5Gi RWO,RWX Retain Released default/my-pvc
# 再生成PVC,可以发现,此时已经没有PV可供PVC去绑定了
[root@k8s-master-1 pv-pvc]# kubectl apply -f pvc.yaml
persistentvolumeclaim/my-pvc created
[root@k8s-master-1 pv-pvc]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-pvc Pending 3s
[root@k8s-master-1 pv-pvc]# kubectl describe pvc my-pvc
Name: my-pvc
Namespace: default
StorageClass:
Status: Pending
Volume:
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Used By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal FailedBinding 3s (x2 over 11s) persistentvolume-controller no persistent volumes available for this claim and no storage class is set
# 删除PVC
[root@k8s-master-1 pv-pvc]# kubectl delete pvc my-pvc
persistentvolumeclaim "my-pvc" deleted
# 方法一:修改PV,删除claimRef段落,保存后通过命令查看其状态会变更为Available,PV即可重新被使用
[root@k8s-master-1 pv-pvc]# kubectl get pv pvc-volume-3 -o yaml
apiVersion: v1
kind: PersistentVolume
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"pvc-volume-3"},"spec":{"accessModes":["ReadWriteMany","ReadWriteOnce"],"capacity":{"storage":"5Gi"},"nfs":{"path":"/data/k8s-nfs/volume3","readOnly":false,"server":"192.168.0.11"},"persistentVolumeReclaimPolicy":"Retain","volumeMode":"Filesystem"}}
pv.kubernetes.io/bound-by-controller: "yes"
creationTimestamp: "2021-10-17T09:25:12Z"
finalizers:
- kubernetes.io/pv-protection
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:spec:
f:accessModes: {}
f:capacity:
.: {}
f:storage: {}
f:nfs:
.: {}
f:path: {}
f:server: {}
f:persistentVolumeReclaimPolicy: {}
f:volumeMode: {}
manager: kubectl-client-side-apply
operation: Update
time: "2021-10-17T09:25:12Z"
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
f:pv.kubernetes.io/bound-by-controller: {}
f:spec:
f:claimRef:
.: {}
f:apiVersion: {}
f:kind: {}
f:name: {}
f:namespace: {}
f:resourceVersion: {}
f:uid: {}
f:status:
f:phase: {}
manager: kube-controller-manager
operation: Update
time: "2021-10-17T09:36:48Z"
name: pvc-volume-3
resourceVersion: "234559"
uid: 70a8315d-0414-412f-87c6-119ea2bcecf6
spec:
accessModes:
- ReadWriteMany
- ReadWriteOnce
capacity:
storage: 5Gi
claimRef: #将这里删除
apiVersion: v1
kind: PersistentVolumeClaim
name: my-pvc
namespace: default
resourceVersion: "234545"
uid: 5d2f61ab-d724-43e9-aae5-7c1e22f44d9e
nfs:
path: /data/k8s-nfs/volume3
server: 192.168.0.11
persistentVolumeReclaimPolicy: Retain
volumeMode: Filesystem
status:
phase: Released
# 方法二:将PV删除,然后重新创建PV
[root@k8s-master-1 pv-pvc]# kubectl delete -f pv.yaml
persistentvolume "pvc-volume-1" deleted
persistentvolume "pvc-volume-2" deleted
persistentvolume "pvc-volume-3" deleted
[root@k8s-master-1 pv-pvc]# kubectl apply -f pv.yaml
persistentvolume/pvc-volume-1 created
persistentvolume/pvc-volume-2 created
persistentvolume/pvc-volume-3 created
[root@k8s-master-1 pv-pvc]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-volume-1 2Gi ROX Retain Available 3s
pvc-volume-2 3Gi RWO,RWX Retain Available 3s
pvc-volume-3 5Gi RWO,RWX Retain Available 3s
[root@k8s-master-1 pv-pvc]# cat nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: my-pvc
readOnly: false
注意:
如果使用默认的回收策略retain,那么删除pvc之后,pv会处于released状态
,我们想要继续使用这个pv,需要手动删除pv,kubectl delete pv pv_name,删除pv,不会删除pv里的数据,当我们重新创建pvc时还会和这个最匹配的pv绑定,数据还是原来数据,不会丢失删除流程:POD->PVC->PV
参考文档
https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/