十、k8s入门系列----PV、PVC、StorageClass

更新时间:2023-07-13 22:10:44 阅读: 评论:0

⼗、k8s⼊门系列----PV、PVC、StorageClass
  容器的设计理念就是⼀次性,也就是容器销毁后容器⾥的所有数据都会销毁,所以需要将容器⾥⾯需要保留的数据挂载到持久性存储中,这⾥就涉及到三个概念:PV、PVC、StorageClass 。
  HostPath
  当使⽤docker创建container的时候,⼀般都是加参数 -v 挂载宿主机的⽬录到container⾥⾯,k8s 也可以实现该功能,先讲解⼀下挂载到宿主机⽬录的⽅法。
  创建⼀个deployment资源配置⽂件,挂载到宿主机⽬录:
[root@ylrver10686071 ~]# l
apiVersion: apps/v1
kind: Deployment我在学外语
metadata:
name: volumes001
namespace: prod
spec:
replicas: 1
lector:
matchLabels:
k8s-app: volumes001
template:
metadata:
labels:
k8s-app: volumes001
spec:
containers:
- name: nginx
image: nginx:1.21
淘宝网网页版volumeMounts:
- mountPath: /usr/share/nginx/html/
name: html
volumes:
- name: html
hostPath:
path: /data/nginx/html/
type: DirectoryOrCreate
volumeMounts 挂载到container 指定⽬录的相关配置,根据name来匹配volumes对象的下的name,据此来找到挂载对象
volumes              声明挂载对象
hostPath            存储类型
type: DirectoryOrCreate  如果宿主机路径不存在则创造该路径,当值为Directory 是,宿主机必须有该⽬录,否则会导致pod创建失败
  创建deployment资源,查看pod在哪台Node上运⾏:
[root@ylrver10686071 ~]# kubectl apply -l
deployment.apps/volumes001 created
[root@ylrver10686071 ~]# kubectl get pods -n prod -o wide
NAME                          READY  STATUS    RESTARTS  AGE  IP            NODE              NOMINATED NODE  READINESS GATES
volumes001-66767f866f-rc5qk  1/1    Running  0          21s  10.233.72.59  ylrver10686073  <none>          <none>
[root@ylrver10686071 ~]#
  在ylrver10686071 Node上查看⽬录是否创建,然后到Pod运⾏的节点上查看⽬录是否创建:
[root@ylrver10686071 ~]# ll /data/nginx/html/
ls: cannot access /data/nginx/html/: No such file or directory
[root@ylrver10686071 ~]#
[root@ylrver10686073 ~]# ll /data/nginx/html/
total 0
[root@ylrver10686073 ~]#
  给挂载⽬录创建⽂件,验证是否挂载到Pod⾥⾯:
[root@ylrver10686073 ~]# echo "Hello K8S" > /data/nginx/html/index.html
[root@ylrver10686073 ~]# curl 10.233.72.59/index.html
Hello K8S
[root@ylrver10686073 ~]#
  PV
  上⾯的实验中宿主机挂载的⽬录只有在 Pod 运⾏的 Node 上才会创建,换⾔之,Pod要挂载的⽬录必须跟Node做绑定,这会增加运维的难度,也失去
k8s的故障转移特性。
  针对这个问题,可以使⽤存储券解决,这⾥就要引⼊⼀个概念:PV。
  PV全称叫做Persistent Volume,持久化存储卷。它是⽤来描述或者说⽤来定义⼀个存储卷的,这个通常都是有运维或者数据存储⼯程师来定义。本节使⽤NFS来作为存储端,NFS搭建这⾥不做讲解。
  先创建⼀个PV资源配置⽂件:
[root@ylrver10686071 ~]# l
apiVersion: v1
kind: PersistentVolume  ###PV资源不属于任何命名空间,属于集群级别的
###kubectl api-resources --namespaced=true 命令可以查看哪些资源属于命名空间             
metadata:
name: pv001
labels:   ###Label可以不定义       
name: pv001
storetype: nfs
spec:    ###定义PV资源规格
storageClassName: normal
文明委
accessModes:  ###设置访问模型
-
ReadWriteMany
- ReadWriteOnce
- ReadOnlyMany
capacity:  ###设置存储空间⼤⼩
storage: 500Mi
persistentVolumeReclaimPolicy: Retain  ###回收策略
nfs:
path: /data/nfs/k8s/
rver: 10.68.60.193
[root@ylrver10686071 ~]#
  accessModes 有3种属性值:
ReadWriteMany    多路读写,卷能被集群多个节点挂载并读写
ReadWriteOnce    单路读写,卷只能被单⼀集群节点挂载读写
ReadOnlyMany      多路只读,卷能被多个集群节点挂载且只能读
  persistentVolumeReclaimPolicy 回收策略也有3种属性值:
Retain
  当删除与之绑定的PVC时候,这个PV被标记为relead(PVC与PV解绑但还没有执⾏回收策略)且之前的数据依然保存在该PV上,但是该PV不可⽤,需要⼿动来处理这些数据并删除该PV
   这种⽅式是最常⽤的,可以避免误删pvc或者pv⽽造成数据的丢失
Delete      删除存储资源,AWS EBS, GCE PD, Azure Disk, and Cinder volumes⽀持这种⽅式
Recycle    这个在1.14版本中以及被废弃,取⽽代之的是推荐使⽤动态存储供给策略,它的功能是当删除与该PV关联的PVC时,⾃动删除该PV中的所有数据
  创建完PV后,PV会有⼏种状态:
滕红Available(可⽤)块空闲资源还没有被任何声明绑定
Bound(已绑定)卷已经被声明绑定
Relead(已释放)声明被删除,但是资源还未被集群重新声明
Failed(失败)该卷的⾃动回收失败
  创建PV资源,并查看PV信息:
[root@ylrver10686071 ~]# kubectl apply -l
persistentvolume/pv001 created
[root@ylrver10686071 ~]# kubectl get pv
NAME    CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS      CLAIM  STORAGECLASS  REASON  AGE
pv001  500Mi      RWO,ROX,RWX    Retain          Available          normal                  6s
  PVC
  PV只是定义了⼀个存储卷实体,还需要⼀层抽象的接⼝使其与POD关联,这层抽象的接⼝就是PVC,全称 Persistent Volume Claim,也就是持久化存储声明。开发⼈员使⽤这个来描述该容器需要⼀个什么存储。
  创建⼀个PVC资源配置⽂件:
[root@ylrver10686071 ~]# l
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc001
namespace: prod  ###PVC资源属于命名空间级别
labels:       ###Label可以不定义
name: pvc001
storetype: nfs
capacity: 500Mi
spec:
storageClassName: normal
accessModes:    ###PVC也需要定义访问模式,不过它的模式⼀定是和现有PV相同或者是它的⼦集,否则匹配不到PV
- ReadWriteMany
resources:  ###定义资源要求PV满⾜这个PVC的要求才会被匹配到
requests:
storage: 500Mi  # 定义要求有多⼤空间
  创建PVC资源,查看PVC资源和PV资源绑定情况,可以看到PV和PVC已经实现绑定:
[root@ylrver10686071 ~]# kubectl apply -l
persistentvolumeclaim/pvc001 created
[root@ylrver10686071 ~]# kubectl get pvc -n prod
NAME    STATUS  VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
pvc001  Bound    pv001    500Mi      RWO,ROX,RWX    normal        15s
[root@ylrver10686071 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 500Mi RWO,ROX,RWX Retain Bound prod/pvc001 normal 62m
[root@ylrver10686071 ~]#
  PVC是如何跟PVC绑定的呢,有以下⼏个原则:
PV和PVC中的spec关键字段要匹配,⽐如存储(storage)⼤⼩
PVC的访问模式⼀定是和现有PV相同或者是它的⼦集,否则匹配不到PV
PV和PVC中的 StorageClass  Name字段必须⼀致,StorageClass后⾯会讲到
Label 标签在这⾥只做描述作⽤,跟 PV 和 PVC 的绑定没有任何关系
  看到这⾥,回想总结⼀下就会发现 k8s ⾥⾯会通过定义⼀层抽象概念来管理实体或者连接实体,类似于 Pod 和 Container , PVC 和 PV ;对象和对象的匹配设计原理也是⼀直,例如 deployment匹配replicat通过matchLabels ,PV 和 PVC通过 StorageClass  Name以及 resources等,即对象与对象之间通过匹配关系进⾏绑定。
  更新上⾯的deployment资源配置⽂件,使其使⽤创建好的PVC资源:
[root@ylrver10686071 ~]# l
apiVersion: apps/v1
kind: Deployment
metadata:
name: volumes001
namespace: prod  ###要和指定的PVC同⼀个命名空间
spec:
replicas: 1
lector:
matchLabels:
k8s-app: volumes001
template:
metadata:
labels:
k8s-app: volumes001
spec:
containers:
- name: nginx
image: nginx:1.21
volumeMounts:  ###container的挂载声明没有改变
- mountPath: /usr/share/nginx/html/
name: html
volumes:    ###依然使⽤volumes声明挂载卷
- name: html
persistentVolumeClaim:  ###指定PVC
claimName: pvc001
  更新资源deployment资源配置⽂件,查看pod关于volumes相关信息:
[root@ylrver10686071 ~]# kubectl apply -l
deployment.apps/volumes001 configured
[root@ylrver10686071 ~]# kubectl describe pod volumes001 -n prod|grep -5 Volumes
Type              Status
Initialized      True
Ready            True
ContainersReady  True
PodScheduled      True
Volumes:
html:
Type:      PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName:  pvc001
ReadOnly:  fal
default-token-lx75g:
[root@ylrver10686071 ~]#
  写⼀个⽂件到NFS挂载⽬录中,测试⼀下效果:
[root@ylrver106860193 ~]# echo "K8S PV" > /data/nfs/k8s/index.html
[root@ylrver10686071 ~]# kubectl get pods -n prod -o wide
NAME                          READY  STATUS    RESTARTS  AGE  IP            NODE              NOMINATED NODE  READINESS GATES
volumes001-55f5bb9585-nx9xd  1/1    Running  0          11m  10.233.72.60  ylrver10686073  <none>          <none>
[root@ylrver10686071 ~]# curl 10.233.72.60
K8S PV
[root@ylrver10686071 ~]#
  给原来的Node打上Taint,重启deployment资源,查看Pod在其他Node上运⾏时,原来的挂载⽂件是否还存在:
[root@ylrver10686071 ~]# kubectl taint node ylrver10686073 web=nginx:NoSchedule
node/ylrver10686073 tainted
[root@ylrver10686071 ~]# kubectl rollout restart deployment volumes001 -n prod
deployment.apps/volumes001 restarted
[root@ylrver10686071 ~]# kubectl get pods -n prod -o wide
NAME                          READY  STATUS    RESTARTS  AGE  IP            NODE              NOMINATED NODE  READINESS GATES
volumes001-7fcd68c5b8-hcwcf  1/1    Running  0          30s  10.233.67.54  ylrver10686072  <none
>          <none>
[root@ylrver10686071 ~]#
  验证⼀下,可以看到挂载的⽂件依然存在:
[root@ylrver10686071 ~]# curl 10.233.67.54
K8S PV
[root@ylrver10686071 ~]#
  PV回收时需要删除PVC,删除PVC需要先删除关联的Pod,验证⼀下:
[root@ylrver10686071 ~]# kubectl delete deployments volumes001  -n prod
deployment.apps "volumes001" deleted
[root@ylrver10686071 ~]# kubectl delete pvc pvc001 -n prod
persistentvolumeclaim "pvc001" deleted
[root@ylrver10686071 ~]# kubectl get pv
NAME    CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS    CLAIM        STORAGECLASS  REASON  AGE
pv001  500Mi      RWO,ROX,RWX    Retain          Relead  prod/pvc001  normal                  18m
[root@ylrver10686071 ~]#
  可以看到删除pvc后,pv处于Relead状态,此时pv只能删除重新创建才能继续使⽤,验证⼀下:
[root@ylrver10686071 ~]# kubectl apply -l
persistentvolumeclaim/pvc001 created
[root@ylrver10686071 ~]# kubectl get pvc -n prod
NAME    STATUS    VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
pvc001  Pending                                      normal        17s
[root@ylrver10686071 ~]# kubectl get pv
NAME    CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS    CLAIM        STORAGECLASS  REASON  AGE
pv001  500Mi      RWO,ROX,RWX    Retain          Relead  prod/pvc001  normal                  19m
  删除PV,因为回收策略是Retain,所以NFS端的数据依然存在,验证⼀下:
[root@ylrver10686071 ~]# kubectl delete pv pv001
persistentvolume "pv001" deleted
[root@ylrver106860193 ~]# cat /data/nfs/k8s/index.html
K8S PV
[root@ylrver106860193 ~]#
  重新创建PV,PVC就可以继续绑定:
[root@ylrver10686071 ~]# kubectl apply -l
persistentvolume/pv001 created
[root@ylrver10686071 ~]# kubectl get pv
NAME    CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM        STORAGECLASS  REASON  AGE
pv001  500Mi      RWO,ROX,RWX    Retain          Bound    prod/pvc001  normal                  18s
[root@ylrver10686071 ~]# kubectl get pvc -n prod
NAME    STATUS  VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
pvc001  Bound    pv001    500Mi      RWO,ROX,RWX    normal        4m11s
[root@ylrver10686071 ~]#
  StorageClass
  PV是运维⼈员创建的,开发操作PVC,⼀个PV只能被⼀个PVC绑定,如果这些PV都需要运维⼿动来处理将会是⼀件⼗分繁琐的事情,所以就有了动态供给概念,也就是Dynamic Provisioning。⽽我们上⾯的创建的PV都是静态供给⽅式,也就是Static Provisioning。⽽动态供给的关键就是StorageClass,它的作⽤就是创建PV模板。
  创建StorageClass⾥⾯需要定义PV属性⽐如存储类型、⼤⼩等;另外创建这种PV需要⽤到存储插件。最终效果是,⽤户提交PVC,⾥⾯指定存储类型,如果符合我们定义的StorageClass,则会为其⾃动创建PV并进⾏绑定。横加
  Kubernetes本⾝⽀持的动态PV创建不包括nfs,所以需要使⽤额外插件实现。
  下载⽂件后,解压到 /opt ⽬录下:
tar -zxvf   -C /opt/
  使⽤helm部署 nfs-client插件:
[root@ylrver10686071 ~]# cd /opt/nfs-subdir-external-provisioner/
[root@ylrver10686071 nfs-subdir-external-provisioner]# helm install nfs-subdir-external-provisioner --namespace  kube-system .  --t nfs.rver=10.68.60.193 --t nfs.path=/data/nfs/k8s/ NAME: nfs-subdir-external-provisioner
LAST DEPLOYED: Fri Jul 30 20:36:05 2021
NAMESPACE: prod
轮胎充氮气STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@ylrver10686071 nfs-subdir-external-provisioner]#
  查看已经创建的 StorageClass,StorageClass属于集群级别:
[root@ylrver10686071 nfs-subdir-external-provisioner]# kubectl get storageclass
NAME        PROVISIONER                                    RECLAIMPOLICY  VOLUMEBINDINGMODE  ALLOWVOLUMEEXPANSION  AGE
nfs-client  cluster.local/nfs-subdir-external-provisioner  Delete          Immediate          true                  48s
[root@ylrver10686071 nfs-subdir-external-provisioner]#
  创建PVC资源配置⽂件,使⽤nfs-client StorageClass:
[root@ylrver10686071 ~]# l
apiVersion: v1
kind: PersistentVolumeClaim
硫磺的作用与功效metadata:
name: pvc002
namespace: default
labels:
name: pvc002
storetype: nfs
capacity: 300Mi
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 300Mi
[root@ylrver10686071 ~]#
  创建PVC资源,可以看到PV已经⾃动创建:
[root@ylrver10686071 ~]# kubectl apply -f  l
persistentvolumeclaim/pvc002 created
[root@ylrver10686071 ~]# kubectl get pvc
NAME    STATUS  VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
pvc002  Bound    pvc-13f05a23-0fce-429f-9803-db4ec3dd6465  300Mi      RWX            nfs-client    5m
[root@ylrver10686071 ~]# kubectl get pv
NAME                                      CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM            STORAGECLASS  REASON  AGE
pvc-13f05a23-0fce-429f-9803-db4ec3dd6465  300Mi      RWX            Delete          Bound    default/pvc002  nfs-client              5m3s
[root@ylrver10686071 ~]#
  NFS服务端可以看到创建的PV对应存储⽬录:
[root@ylrver106860193 ~]# ll /data/nfs/k8s/
total 4
drwxrwxrwx 2 root root 6 Jul 31 03:17 default-pvc002-pvc-13f05a23-0fce-429f-9803-db4ec3dd6465
-rw-r--r-- 1 root root 7 Jul 30 03:32 index.html
[root@ylrver106860193 ~]#
  现在往PV对应的⽬录写⼊⽂件,然后删除PVC,看NFS端PV对应的存储⽬录是否存储:
tolstoy
[root@ylrver106860193 ~]# echo "StorageClass" > /data/nfs/k8s/default-pvc002-pvc-13f05a23-0fce-429f-9803-db4ec3dd6465/index.html
[root@ylrver106860193 ~]#
  开始删除PVC,PV也会⾃动删除
[root@ylrver10686071 ~]# kubectl delete pvc pvc002
persistentvolumeclaim "pvc002" deleted
[root@ylrver10686071 ~]# kubectl get pvc
No resources found in default namespace.
[root@ylrver10686071 ~]# kubectl get pv
No resources found
[root@ylrver10686071 ~]#
  查看NFS服务端⽬录,可以看到⽂件依然保留,⽬录在原有名称上添加了archived-:
[root@ylrver106860193 ~]# cat  /data/nfs/k8s/archived-default-pvc002-pvc-13f05a23-0fce-429f-9803-db4ec3dd6465/index.html
StorageClass
[root@ylrver106860193 ~]#
  其实跟StorageClass回收策略,涉及两个参数,⽂件 /opt/nfs-subdir-external-provisioner/values.yaml⾥可以修改,然后helm update 即可:archiveOnDelete: true
reclaimPolicy: Delete
archiveOnDelete    当设置为 true 时,在删除PVC后,会对 PV 对应的存储⽬录进⾏备份
reclaimPolicy          回收策略,上⾯有讲解过,Delete策略就是删除PVC时⾃动删除绑定的PV
  StatefulSet StorageClass
  当使⽤ StatefulSet 控制器创建Pod的时候,可以在 StatefulSet 配置⽂件⾥⾯直接声明 PV的创建,创建⼀个StatefulSet  资源配置⽂件:[root@ylrver10686071 ~]# l
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: volumes002
namespace: prod
spec:
rviceName: volumes002-svc
lector:
matchLabels:
k8s-app: volumes002
replicas: 3
template:
metadata:
labels:
k8s-app: volumes002
spec:
containers:

本文发布于:2023-07-13 22:10:44,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1080382.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:创建   需要   挂载   资源   删除   查看   绑定
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图