k8s的存储(Persistent Volumes 持久卷卷使用)

官网参考:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#

1、介绍
管理存储是与管理计算实例不同的问题。PersistentVolume子系统为用户和管理员提供了一个API,该API从存储的使用方式中抽象出存储是如何提供的细节。为此,我们引入了两个新的API资源:persistenvolume和persistenvolumeclaim。
1)PersistentVolume(PV)是由管理员设置的存储,它是集群中的资源,就像节点是集群资源一样。PV是类似于卷的卷插件,但它的生命周期独立于使用PV的任何单个Pod。此API对象捕获存储实现的详细信息,包括NFS、iSCSI或特定于云提供商的存储系统。
2)PersistentVolumeClaim(PVC)是用户对存储的请求。pod消耗节点资源,pvc消耗PV资源。Pods可以请求特定级别的资源(CPU和内存)。声明可以请求特定的大小和访问模式(例如,它们可以一次读/写或多次只读)。
虽然PersistentVolumeClaims允许用户使用抽象存储资源,但用户通常需要具有不同属性(如性能)的PersistentVolumes来解决不同的问题。群集管理员需要能够提供多种持久卷,这些持久卷的差异不仅仅在于大小和访问模式,而不需要向用户公开这些卷是如何实现的细节。对于这些需求,有一个StorageClass资源

2、持久卷的类型
PersistentVolume类型作为插件实现。Kubernetes目前支持以下插件:
GCEPersistentDisk、AWSElasticBlockStore、AzureFile、AzureDisk、CSI、FC (Fibre Channel)、FlexVolume、Flocker、NFS、iSCSI、RBD (Ceph Block Device)、CephFS、Cinder、Glusterfs、VsphereVolume、Quobyte Volumes、HostPath、Portworx Volumes、ScaleIO Volumes、StorageOS

3、访问模式
在资源提供者支持的任何方式的主机上都可以安装一个持续卷。当在表格下面显示时,供应商将具有不同的能力,并且每个PV的存取模式被设置到由该特定卷支持的特定模式上。例如,NFS可以支持多个读取/写入客户端,但一个特定NFS PV可以作为只读光盘导出到服务器上。每个PV都有自己的存取模式集描述特异PV的能力。
访问模式如下:
RWO-readwriteonce:被单个节点装入读写
ROX-Readonlymany:被许多节点装入阅读
RWX-readwritemany:被许多节点装入阅读书写

k8s的存储(Persistent Volumes 持久卷卷使用)_第1张图片

4、生命周期
pv是集群中的资源。pvc是对这些资源的请求,也充当对资源的索赔检查,pv有两种配置方式:静态配置或动态配置。
1)静态的
群集管理器创建多个pv。它们携带真实存储的详细信息,可供集群用户使用。它们存在于Kubernetes API中,可供使用。

2)动态的
当管理员创建的静态pv与用户的PersistentVolumeClaim不匹配时,集群可能会尝试动态地为PVC提供卷。此设置基于StorageClasses:PVC必须请求一个存储类,管理员必须已创建并配置该类才能进行动态设置。请求类“”的声明有效地为自己禁用动态设置。要基于存储类启用动态存储资源调配,群集管理员需要在API服务器上启用DefaultStorageClass许可控制器。例如,可以通过确保DefaultStorageClass位于API服务器组件的--enable acceptment plugins标志的逗号分隔的、有序的值列表中来实现。有关API服务器命令行标志的更多信息,请查看kube API server文档

绑定
用户创建了一个PersistentVolumeClaim,或者在动态资源调配的情况下,已经创建了一个PersistentVolumeClaim,该PersistentVolumeClaim具有请求的特定存储量和特定的访问模式。主控中的控制循环监视新的pvc,找到匹配的PV(如果可能),并将它们绑定在一起。如果一个PV是为一个新的PVC动态配置的,那么循环将始终将该PV绑定到PVC。否则,用户将始终至少得到他们要求的内容,但容量可能超过所要求的内容。一旦绑定,PersistentVolumeClaim绑定是独占的,不管它们是如何绑定的。PVC到PV绑定是一对一映射,使用ClaimRef,ClaimRef是persistenvolume和persistenvolumeclaim之间的双向绑定。
如果不存在匹配的卷,则声明将无限期保持未绑定状态。当匹配的卷可用时,将绑定声明。例如,配置了许多50Gi pv的集群与请求100Gi的PVC不匹配。当一个100Gi的PV添加到集群时,PVC可以被绑定。

持久化声明的保护
目的是确保由pod正在使用的持久卷pvc不会从系统中删除,因为这可能会导致数据丢失。如果用户删除Pod正在使用的PVC,则不会立即删除该PVC。PVC将会去除被推迟,直到PVC不再被任何pod使用。此外,如果管理员删除绑定到PVC的PV,则不会立即删除该PV。PV移除被推迟,直到PV不再与PVC绑定。

回收策略
当用户使用完他们的卷时,他们可以从允许资源回收的API中删除PVC对象。
Retain保留:允许手动回收资源。删除PersistentVolumeClaim时,PersistentVolume仍然存在,并且该卷被视为“已释放”。
Delete删除:对于支持Delete reclaim策略的卷插件,deletion将从Kubernetes中删除PersistentVolume对象,以及外部基础结构(如AWS EBS、GCE PD、Azure磁盘或煤渣卷)中的关联存储资产。
Recycle回收:基本擦除(rm-rf/the volume/*)

警告:回收策略已弃用。相反,推荐的方法是使用动态资源调配。

状态
卷可以处于以下的某种状态:
Available(可用):块空闲资源还没有被任何声明绑定
Bound(已绑定):卷已经被声明绑定
Released(已释放):声明被删除,但是资源还未被集群重新声明
Failed(失败):该卷的自动回收失败

5、实际操作
[root@k8smaster pp]# more pv.yaml  #创建PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    path: /sharedir
    server: 192.168.23.100
[root@k8smaster pp]# kubectl create -f pv.yaml 
persistentvolume/mypv1 created
[root@k8smaster pp]# kubectl get pv #STATUS 为 Available
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           nfs                     36s
[root@k8smaster pp]#

capacity 指定PV的容量为1G。

accessModes 指定访问模式为ReadWriteOnce,支持的访问模式有:
ReadWriteOnce – PV能以read-write模式mount到单个节点。
ReadOnlyMany – PV能以read-only模式 mount到多个节点。
ReadWriteMany – PV能以read-write模式 mount 到多个节点。

persistentVolumeReclaimPolicy 指定当 PV 的回收策略为 Recycle,支持的策略有:
Retain – 需要管理员手工回收。
Recycle – 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*。
Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

storageClassName 指定PV的class为 nfs。相当于为PV设置了一个分类,PVC可以指定class申请相应class的 PV。
指定 PV 在 NFS 服务器上对应的目录。


[root@k8smaster pp]# more pvc.yaml  #只需要指定 PV 的容量,访问模式和 class
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
[root@k8smaster pp]# kubectl create -f pvc.yaml 
persistentvolumeclaim/mypvc1 created
[root@k8smaster pp]# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            9s
[root@k8smaster pp]# kubectl get pv #已经 Bound 到 mypv1,申请成功
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Bound    default/mypvc1   nfs                     12m
[root@k8smaster pp]# 
[root@k8smaster pp]# more pv-pod.yaml  #使用普通Volume的格式类似,在volumes中通过persistentVolumeClaim指定使用mypvc1申请的 Volume
apiVersion: v1
kind: Pod
metadata:
  name: pv-pod
spec:
  containers:
  - name: pv-pod-ctn
    image: 192.168.23.100:5000/tomcat:v2
    volumeMounts:
    - name: pv-volume
      mountPath: /tmp/config
  volumes:
    - name: pv-volume
      persistentVolumeClaim:
        claimName: mypvc1
  restartPolicy: Never
[root@k8smaster pp]# kubectl create -f pv-pod.yaml 
pod/pv-pod created
[root@k8smaster pp]# kubectl get pod
NAME     READY   STATUS    RESTARTS   AGE
pv-pod   1/1     Running   0          13s
[root@k8smaster pp]# kubectl exec -it pv-pod /bin/bash
root@pv-pod:/usr/local/tomcat# cd /tmp/config/
root@pv-pod:/tmp/config# ls -lrt
total 8
-rw-r--r-- 1 nobody nogroup 7 Feb 19 14:19 node01.log
-rw-r--r-- 1 nobody nogroup 7 Feb 19 14:19 node02.log
root@pv-pod:/tmp/config# echo "pv-pod" >pv-pod.log #在pod中创建文件
root@pv-pod:/tmp/config# ls -lrt
total 12
-rw-r--r-- 1 nobody nogroup 7 Feb 19 14:19 node01.log
-rw-r--r-- 1 nobody nogroup 7 Feb 19 14:19 node02.log
-rw-r--r-- 1 nobody nogroup 7 Feb 19  2020 pv-pod.log


[root@k8snode01 sharedir]# pwd #在nfs客户端查看生成的文件
/sharedir
[root@k8snode01 sharedir]# ls -lrt
total 12
-rw-r--r-- 1 nfsnobody nfsnobody 7 Feb 19 22:19 node01.log
-rw-r--r-- 1 nfsnobody nfsnobody 7 Feb 19 22:19 node02.log
-rw-r--r-- 1 nfsnobody nfsnobody 7 Feb 20  2020 pv-pod.log
[root@k8snode01 sharedir]# more pv-pod.log 
pv-pod
[root@k8snode01 sharedir]# 
[root@k8smaster pp]# kubectl delete pod pv-pod #退出pod
pod "pv-pod" deleted
[root@k8smaster pp]# kubectl delete pvc mypvc1 #删除pvc进行回收资源
[root@k8smaster pp]# kubectl get pod  #当PVC mypvc1被删除后,发现Kubernetes启动了一个新Pod,这个Pod的作用就是清除PV mypv1的数据,需要busybox:1.27镜像
NAME                 READY   STATUS             RESTARTS   AGE
recycler-for-mypv1   0/1     ImagePullBackOff   0          29s
[root@k8smaster pp]# 

链接:https://pan.baidu.com/s/13d-i8FWF0miLx2XYNchffw  #busybox:1.27镜像下载
提取码:zekc 


Events:
  Type     Reason     Age                    From                Message
  ----     ------     ----                   ----                -------
  Warning  Failed     4m39s                  kubelet, k8snode02  Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
  Warning  Failed     4m13s                  kubelet, k8snode02  Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
  Normal   Scheduled  3m32s                  default-scheduler   Successfully assigned default/recycler-for-mypv1 to k8snode02
  Warning  Failed     3m30s                  kubelet, k8snode02  Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
  Normal   Pulling    2m46s (x4 over 4m55s)  kubelet, k8snode02  Pulling image "busybox:1.27"
  Warning  Failed     2m7s (x4 over 4m39s)   kubelet, k8snode02  Error: ErrImagePull
  Warning  Failed     2m7s                   kubelet, k8snode02  Failed to pull image "busybox:1.27": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/library/busybox/manifests/1.27: net/http: TLS handshake timeout
  Normal   BackOff    103s (x6 over 4m39s)   kubelet, k8snode02  Back-off pulling image "busybox:1.27"
  Warning  Failed     89s (x7 over 4m39s)    kubelet, k8snode02  Error: ImagePullBackOff
[root@k8smaster pp]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           nfs                     3h10m

  [root@k8snode01 sharedir]# ls -lrt #删除pvc后,磁盘文件被清理删除
total 0
[root@k8snode01 sharedir]# 
  

你可能感兴趣的:(k8s)