当前位置: 首页 > news >正文

Kubernetes中的PersistentVolume卷

华子目录

  • `PersistentVolume`持久卷
    • 静态持久卷`pv`与静态持久卷声明`pvc`
      • `PersistentVolume`(持久卷,简称`pv`)
      • `PersistentVolumeClaim`(持久卷声明,简称`pvc`)
      • 卷的访问模式
      • 卷的回收策略
      • 注意
      • 卷状态说明
      • 使用`PersistentVolume`卷的步骤
      • `pv`和`pvc`的`绑定机制`
  • 示例

PersistentVolume持久卷

接上一篇博客https://blog.csdn.net/huaz_md/article/details/143464661?spm=1001.2014.3001.5501中写的emptyDir,hostPath,nfsvolume卷都是静态卷,接下来我们进入静态持久卷介绍

静态持久卷pv与静态持久卷声明pvc

PersistentVolume(持久卷,简称pv

  • pv集群内由管理员提供的网络存储的一部分
  • pv也是集群中的一种资源。是一种volume插件
  • 但是pv生命周期却是和使用它的Pod相互独立
  • pv这个API对象,捕获了诸如NFS、ISCSI、或其他云存储系统的实现细节
  • pv两种提供方式:静态和动态
    • 静态pv:集群管理员创建多个pv,它们携带着真实存储详细信息,它们存在于KubernetesAPI中,并可用于存储使用
    • 动态pv:当管理员创建的静态pv不匹配用户的pvc时,集群可能会尝试专门地供给volumePVC。这种供给基于StorageClass

PersistentVolumeClaim(持久卷声明,简称pvc

  • pvc用户请求存储资源一种方式,它允许用户指定存储的大小访问模式等,而不必关心具体的存储后端是如何实现的
  • 它和Pod类似,Pod消耗Node资源,而pvc消耗pv资源
  • Pod能够请求特定的资源(如CPU内存)。pvc能够请求指定的大小和访问的模式持久卷配置
  • pvcpv绑定一对一映射pvc没找到匹配的pv,那么pvc无限期得处于unbound未绑定状态

卷的访问模式

  • ReadWriteOnce — 该volume卷只能被单个节点读写的方式映射
  • ReadOnlyMany — 该volume卷可以被多个节点只读方式映射
  • ReadWriteMany — 该volume卷可以被多个节点读写的方式映射
  • 命令行中,卷的访问模式可以简写为:
    • RWOReadWriteOnce
    • ROXReadOnlyMany
    • RWXReadWriteMany

卷的回收策略

  • Retain保留,需要管理员手动回收
  • Recycle回收自动删除卷数据(在当前版本中已经废弃
  • Delete删除,相关联的存储资产,如AWS EBSGCE PDAzure Diskor OpenStack Cinder卷都会被删除

注意

  • 只有nfshostPath支持回收利用
  • AWS EBSGCE PDAzure Diskor OpenStack Cinder卷支持删除操作

卷状态说明

  • Available表示是一个空闲资源,尚未绑定任何申领
  • Bound表示已经绑定某申领
  • Released表示所绑定申领已被删除,但是关联存储资源未被集群回收
  • Failed表示自动回收操作失败

使用PersistentVolume卷的步骤

  • 1.声明pv
  • 2.声明pvc(声明pvc后,pvpvc就实现了一一绑定
  • 3.创建pod使用pvc

pvpvc绑定机制

  • pv:描述的是持久化Volume实体概念,其生命周期Pod的创建销毁无关。pv可以预先准备好,也可以根据需要动态创建
  • pvc:是对pv请求,声明Pod所希望使用的持久化存储的属性,如容量、读写权限等。

pvc不直接指定使用哪个pv,而是通过描述所需的存储资源特征(如存储大小、访问模式等)来请求存储资源Kubernetes调度系统会尝试自动将该pvc与一个满足要求pv进行绑定

示例

因为我们会用到nfs卷,所以这里先搭建nfs环境
这里,我就在harbor主机上部署nfs服务器

  • 部署nfs服务端
[root@harbor ~]# yum install nfs-utils -y
  • 部署nfs客户端
[root@k8s-master ~]# yum install nfs-utils -y
[root@k8s-node1 ~]# yum install nfs-utils -y
[root@k8s-node2 ~]# yum install nfs-utils -y
  • 启动服务端
[root@harbor ~]# systemctl enable --now nfs-server
  • 服务端创建nfs共享目录
[root@harbor ~]# mkdir /nfsdata
  • 编辑服务端/etc/exports文件
[root@harbor ~]# vim /etc/exports
[root@harbor ~]# cat /etc/exports
/nfsdata  *(rw,sync,no_root_squash)
[root@harbor ~]# exportfs -rv
exporting *:/nfsdata
  • 客户端连接服务端
#172.25.254.250是nfs服务端的ip
[root@k8s-master ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
[root@k8s-node1 ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
[root@k8s-node2 ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *

至此,nfs环境已经搭建好了

#在/nfsdata共享目录中创建pv1,pv2,pv3目录
[root@harbor nfsdata]# mkdir pv{1..3}
[root@harbor nfsdata]# ls
pv1  pv2  pv3
  • master上创建pvyml文件,pv集群资源,不在任何namespace
#在master上创建pv的yml文件,pv是集群资源,不在任何namespace中
[root@k8s-master volume]# vim pv.yml
[root@k8s-master volume]# cat pv.yml
apiVersion: v1   #指明了Kubernetes API的版本,对于PersistentVolume资源来说,它通常是v1
kind: PersistentVolume   #资源的类型为PersistentVolume
metadata:   #资源的元数据labels:   run: pv1   #PersistentVolume资源的标签name: pv1  #PersistentVolume资源的名字
spec:   #PersistentVolume的规格capacity:   #声明存储的容量storage: 5Gi   #容量为5GiBvolumeMode: Filesystem   #卷的模式,此处为Filesystem,表示它将作为文件系统被挂载accessModes:   #卷的访问模式- ReadWriteOnce    #ReadWriteOnce,意味着它可以被单个节点以读写模式挂载一次persistentVolumeReclaimPolicy: Retain  #卷的回收策略,Retain,表示手动回收,即管理员需要手动删除存储资产storageClassName: nfs  #存储类的名称,nfs。它必须与相应的StorageClass资源中的name字段相匹配,该资源定义了动态分配存储卷时的策略和参数nfs:path: /nfsdata/pv1   #nfs上的共享路径server: 172.25.254.250---
apiVersion: v1   #指明了Kubernetes API的版本,对于PersistentVolume资源来说,它通常是v1
kind: PersistentVolume   #资源的类型为PersistentVolume
metadata:   #资源的元数据labels:run: pv2  #PersistentVolume资源的标签name: pv2   #PersistentVolume资源的名字
spec:   #PersistentVolume的规格capacity:   #声明存储的容量storage: 15Gi   #容量为15GiBvolumeMode: Filesystem   #卷的模式,此处为Filesystem,表示它将作为文件系统被挂载accessModes:   #卷的访问模式- ReadWriteMany   #多点读写persistentVolumeReclaimPolicy: Retain   #卷的回收策略,Retain,表示手动回收,即管理员需要手动删除存储资产storageClassName: nfs   #存储类的名称,nfs。它必须与相应的StorageClass资源中的name字段相匹配,该资源定义了动态分配存储卷时的策略和参数nfs:path: /nfsdata/pv2    #nfs上的共享路径server: 172.25.254.250---
apiVersion: v1   #指明了Kubernetes API的版本,对于PersistentVolume资源来说,它通常是v1
kind: PersistentVolume   #资源的类型为PersistentVolume
metadata:   #资源的元数据labels:run: pv3   #PersistentVolume资源的标签name: pv3    #PersistentVolume资源的名字
spec:    #PersistentVolume的规格capacity:   #声明存储的容量storage: 25Gi   #容量为25GiBvolumeMode: Filesystem    #卷的模式,此处为Filesystem,表示它将作为文件系统被挂载accessModes:   #卷的访问模式- ReadOnlyMany   #多点只读persistentVolumeReclaimPolicy: Retain   #存储类的名称,nfs。它必须与相应的StorageClass资源中的name字段相匹配,该资源定义了动态分配存储卷时的策略和参数storageClassName: nfsnfs:path: /nfsdata/pv3   #nfs上的共享路径server: 172.25.254.250
[root@k8s-master volume]# kubectl apply -f pv.yml
persistentvolume/pv1 created
persistentvolume/pv2 created
persistentvolume/pv3 created
[root@k8s-master volume]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv1    5Gi        RWO            Retain           Available           nfs            <unset>                          30s
pv2    15Gi       RWX            Retain           Available           nfs            <unset>                          30s
pv3    25Gi       ROX            Retain           Available           nfs            <unset>                          30s
#我们发现pv没有命名空间,说明pv不属于任何命名空间
[root@k8s-master volume]# kubectl describe pv pv1
Name:            pv1
Labels:          run=pv1
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    nfs   #这个PV属于nfs存储类
Status:          Available   #PV的状态是Available,意味着它当前没有被任何PVC绑定,是空闲的
Claim:                   #Claim为空,表示没有PVC与这个PV绑定
Reclaim Policy:  Retain   #回收策略是Retain,表示当PV不再被需要时,管理员需要手动处理这些资源
Access Modes:    RWO   #访问模式是RWO(ReadWriteOnce),意味着这个卷可以被单个节点以读写模式挂载
VolumeMode:      Filesystem   #卷模式是Filesystem,表示这个卷是以文件系统的形式挂载的
Capacity:        5Gi   #PV的存储容量是5GB
Node Affinity:   <none>  #为none表示没有为这个PV设置节点亲和性(Node Affinity),意味着它可以被任何节点上的Pod使用
Message:               #没有与这个PV相关的额外消息
Source:Type:      NFS (an NFS mount that lasts the lifetime of a pod)Server:    172.25.254.250Path:      /nfsdata/pv1ReadOnly:  false    #这个PV不是以只读模式挂载的
Events:        <none>
#建立pvc,pvc是pv使用的申请,需要保证和pod在一个namesapce中
[root@k8s-master volume]# vim pvc.yml
[root@k8s-master volume]# cat pvc.yml
apiVersion: v1     #Kubernetes API版本是v1
kind: PersistentVolumeClaim   #持久卷声明(PVC),PVC是用户请求存储资源的一种方式,它允许用户指定存储的大小、访问模式等,而不必关心具体的存储后端是如何实现的
metadata:   #PVC的元数据labels:   run: pvc1   #pvc标签name: pvc1   #pvc的名字
spec:    #pvc的规格storageClassName: nfs   #指定了这个PVC应该使用名为nfs的存储类(StorageClass)accessModes:   #PVC的访问模式- ReadWriteOnce    #这个卷可以被单个节点以读写模式挂载resources:   #PVC请求的资源requests:   #请求的资源类型和数量storage: 1Gi   #请求1GiB---
apiVersion: v1   #Kubernetes API版本是v1
kind: PersistentVolumeClaim   #持久卷声明(PVC),PVC是用户请求存储资源的一种方式,它允许用户指定存储的大小、访问模式等,而不必关心具体的存储后端是如何实现的
metadata:   #PVC的元数据labels:run: pvc2   #pvc标签name: pvc2  #pvc的名字
spec:   #pvc的规格storageClassName: nfs   #指定了这个PVC应该使用名为nfs的存储类(StorageClass) accessModes:    #PVC的访问模式- ReadWriteMany   #多点读写resources:   #PVC请求的资源requests:   #请求的资源类型和数量 storage: 10Gi   #请求10GiB---
apiVersion: v1   #Kubernetes API版本是v1
kind: PersistentVolumeClaim   #持久卷声明(PVC),PVC是用户请求存储资源的一种方式,它允许用户指定存储的大小、访问模式等,而不必关心具体的存储后端是如何实现的
metadata:   #PVC的元数据labels:run: pvc3    #pvc标签name: pvc3   #pvc的名字
spec:   #pvc的规格storageClassName: nfs   #指定了这个PVC应该使用名为nfs的存储类(StorageClass) accessModes:   #PVC的访问模式- ReadOnlyMany   #多点只读 resources:   #PVC请求的资源requests:   #请求的资源类型和数量 storage: 15Gi   #请求15GiB
[root@k8s-master volume]# kubectl apply -f pvc.yml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
[root@k8s-master volume]# kubectl get pvc
NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
pvc1   Bound    pv1      5Gi        RWO            nfs            <unset>                 12m
pvc2   Bound    pv2      15Gi       RWX            nfs            <unset>                 12m
pvc3   Bound    pv3      25Gi       ROX            nfs            <unset>                 12m#我们发现pvc是有命名空间的
[root@k8s-master volume]# kubectl describe pvc pvc1
Name:          pvc1   
Namespace:     default
StorageClass:  nfs
Status:        Bound   #PVC的状态是Bound,意味着它已经与一个PersistentVolume(PV)绑定,这里的PV是pv1
Volume:        pv1  #我们发现,pvc1申请到了pv1
Labels:        run=pvc1
Annotations:   pv.kubernetes.io/bind-completed: yes    #表示PVC与PV的绑定操作已经完成pv.kubernetes.io/bound-by-controller: yes   #表示这个绑定操作是由Kubernetes的控制器完成的
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi   #PVC请求的存储容量是5GB
Access Modes:  RWO   #单个节点以读写模式挂载
VolumeMode:    Filesystem   #这个卷是以文件系统的形式挂载的
Used By:       <none>
Events:        <none>

当我们运行pvc.yml后,再次观察发现:pv状态变成了Bound已绑定状态

[root@k8s-master volume]# kubectl describe pv pv1
Name:            pv1
Labels:          run=pv1
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    nfs
Status:          Bound
Claim:           default/pvc1
Reclaim Policy:  Retain
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:
Source:Type:      NFS (an NFS mount that lasts the lifetime of a pod)Server:    172.25.254.250Path:      /nfsdata/pv1ReadOnly:  false
Events:        <none>
  • pod中使用pvc
[root@k8s-master volume]# vim pod4.yml
[root@k8s-master volume]# cat pod4.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:containers:- image: nginxname: nginxvolumeMounts:- name: vol1   #将名为vol1的卷,挂载到容器中的/usr/share/nginx/html位置,这个名字要和volumes中声明的名字一致mountPath: /usr/share/nginx/htmlvolumes:   #定义Pod中所有需要挂载的卷- name: vol1   #名为vol1的卷persistentVolumeClaim:   #这个卷是通过PersistentVolumeClaim(PVC)来获取的claimName: pvc1   #指定了要使用的PVC的名称是pvc1
[root@k8s-master volume]# kubectl apply -f pod4.yml
pod/testpod created
[root@k8s-master volume]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
testpod   1/1     Running   0          21s   10.244.2.36   k8s-node2.org   <none>           <none>
[root@k8s-master volume]# kubectl describe pods testpod

在这里插入图片描述

#第一次访问结果是403,是因为nginx中没有index.html文件
[root@k8s-master volume]# curl 10.244.2.36
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
#在nfs服务器中的/nfsdata/pv1共享目录中写入index.html文件
[root@harbor nfsdata]# cd pv1
[root@harbor pv1]# echo hello world > index.html
#再次访问,就看到效果了
[root@k8s-master volume]# curl 10.244.2.36
hello world

http://www.mrgr.cn/news/65315.html

相关文章:

  • Redis系列---数据管理
  • 基于matlab的图像形状与分类的方法比较
  • 如何选择最适合的消息队列?详解 Kafka、RocketMQ、RabbitMQ 的使用场景
  • Redis 的使⽤和原理
  • 高中数学:统计-随机抽样
  • 3分钟认识API是什么
  • C++初阶教程——C++内存管理
  • 在Python中最小化预测函数的参数
  • 总结---20个工作中一定会用到的python实用小脚本
  • 怀旧,这些曾盛极一时的国产经典软件,用过5个你是老网民
  • 【双目视觉标定】——1原理与实践
  • mysql死锁或锁表分析
  • TypeScript实用笔记(二):类与接口详解
  • Spectrum 绘制调色板:实现与应用指南
  • 构建本地RAG知识库(上): langchain+ollama构建本地大模型应用
  • gRPC-4种通信模式
  • ChatGPT:真如吹的那般神乎其神吗?
  • pdf 添加页眉页脚,获取前五页
  • SpringBoot新闻稿件管理系统:架构与实现
  • 编程模拟生产者和消费者问题(java)
  • Qt6 CMake 中引入 Qt Linguist 翻译功能
  • LeetCode每日一题633---平方数之和
  • runner,hook介绍
  • 在Java中如何创建一个类和对象?
  • Chromium127编译指南 Mac篇(一)- 环境准备详解
  • [实战-11] FlinkSql 设置时区对TIMESTAMP和TIMESTAMP_LTZ的影响