【kubernetes】带你了解k8s中PV和PVC的由来

news2024/11/15 15:25:47

文章目录

      • 1 为什么需要卷(Volume)
      • 2 卷的挂载
        • 2.1 k8s集群中可以直接使用
        • 2.2 需要额外的存储组件
        • 2.3 公有云
      • 2 PV(Persistent Volume)
      • 3 SC(Storage Class) 和 PVC(Persistent Volume Claim)
      • 4 总结

1 为什么需要卷(Volume)

Pod是由一个或者多个容器组成的,在启动Pod中的容器之前,会先创建一个pause容器,再将其他容器加入到pause容器的网络命名空间,因此,多个容器的网络是共享的,pause容器就像是一个宿主机,多个容器就像是宿主机上面的多个进程,既然多个容器共享网络命名空间,那么多个容器肯定就不能监听同一个端口。多个容器由于都有自己的文件系统,因此,多个容器的文件系统肯定是相互隔离的,如果多个容器之间需要共享数据呢?Pod在重建时,Pod中的所有容器都会基于镜像重建,那么,原来的Pod中的容器中的数据都会丢失,但是很多场景下都需要对数据进行持久化保存,例如,mysql的Pod在重建时可不希望保存的数据没有了。

为了解决以上两个问题,k8s提供了数据卷的机制,可以将同一个数据卷挂载到Pod的多个容器,实现多个容器的数据共享;也可以将数据卷对接外部的存储,实现数据的持久化,使得Pod重建或者被删除后,数据不丢失。

2 卷的挂载

一个Pod可以在pod.spec.volumes中声明,使用命令kubectl explain pod.spec.volumes可以发现里面各种类型的卷,看这些卷的类型会发现,有些卷是可以直接在k8s集群中使用的,有些是需要安装额外组件的,还有一些是对接共有云的,因此,每种类型的卷中的参数是不一样的。

2.1 k8s集群中可以直接使用
卷的类型特点特性状态
configMap对接ConfigMap,可以将ConfigMap中的多个KV挂载为容器中的多个文件
downwardAPI对接DownwardAPI,可以将集群的信息挂载为容器中的文件
emptyDir用于多个容器之间的数据共享,相当于将一个空目录分别挂载到Pod的多个容器,它的生命周期与Pod相同,只要Pod在运行,卷就不会被删除
gitRepo从git上clone仓库代码,然后挂载到容器已废弃,建议在initContainer中在emptyDir下载代码
hostPath将宿主机的路径挂载到容器中,这种方式有安全风险,通常不建议使用
persistentVolumeClaim用于将PV挂载到容器中
projected投射卷,可以将多个卷同时挂载到容器中的一个目录,源卷只能是secret、downwardAPI、configMap、serviceAccountToken
sercet将Secret挂载为容器中的文件
2.2 需要额外的存储组件
卷的类型特点特性状态
cephfs对接CephFS1.28版本中废弃,建议使用Ceph CSI第三方存储驱动
cinder对接Openstack Cinder1.11版本中废弃,1.26版本中移除,1.27版本开始可以使用Openstack Cinder第三方驱动程序
fc对接FiberChannel
glusterfs对接GlusterFS1.25版本中废弃,1.26版本中移除
iscsi对接iSCSI
nfs对接NFS
portworxVolume对接Portworx1.25版本中废弃
rdb对接CephFS的rdb1.28版本中废弃
2.3 公有云
卷的类型特点特性状态
awsElasticBlockStore对接AWS EBS1.19版本中废弃,1.28版本中移除,1.28版本开始可以使用AWS EBS第三方存储驱动
azureDisk对接Azure Disk1.19版本中废弃,1.28版本中移除,1.28版本开始可以使用Azure Disk第三方存储驱动
azureFile对接Azure File1.21版本中废弃,1.26版本开始可以使用Azure File第三方存储驱动
gcePersistentDisk对接GCE PersistentDisk1.17版本中废弃
vsphereVolume对接VMWare vsphere VMDK1.28版本可以使用vSphere CSI第三方存储驱动

当在pod.spec.volumes配置使用的卷后,就可以在pod.spec.containers.volumeMounts将卷挂载到容器中,以下以configMap类型的卷为例,将app-config这个ConfigMap挂载到nginx容器的/opt目录:

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: my-config
      mountPath: /opt/
  volumes:
  - name: my-config 
    configMap:
      name: app-config

2 PV(Persistent Volume)

将pod.spec.volumes中配置的卷挂载到容器中,这时候volume是附属于Pod的,volume和Pod就构成了一种静态绑定关系,这对于hostPath、configMap、secret等类型的volume来说是可以的,因为hostPath是对本地目录的挂载,configMap和secret是对ConfigMap和Secret的挂载,这时候ConfigMap/Secret和Pod是同一个人创建的。

当开发人员用这种方式将NFS挂载到容器中:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com
      path: /my-nfs-volume
      readOnly: true

此处将my-nfs-server.example.com的/my-nfs-volume目录挂载到test-container容器的/my-nfs-data路径,这里的问题是:当运维部门的同事部署完NFS后,难道还需要将NFS的域名/IP和路径告诉开发人员?但是开发人员实际上并不关心这些,那有没有一种方式可以让开发人员只是使用NFS而不需要关心NFS的具体配置?这就需要使用到PV(持久卷)。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-nfs
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /tmp
    server: 172.17.0.2

上述yaml会创建一个my-nfs的PV,需要注意的是:PV是集群级别的资源。这里用的pv.spec.nfs字段跟pod.spec.volumes.nfs相同,只是多了外层的capacity和accessModes,它们分别表示PV的容量和访问模式。当运维人员部署完成NFS文件系统,就可以直接创建好PV,然后开发人员就可以直接引用该PV。

这样虽然可以解决volume创建和volume使用的问题,如果集群中只有少量的PV时是没有问题的,运维人员是可以手动创建的。如果PV的数量很多呢?当运维人员创建了很多PV后,开发人员难道需要自己从中挑选PV使用吗?那管理的复杂度会非常大,因此,k8s提供了SC和PVC。

3 SC(Storage Class) 和 PVC(Persistent Volume Claim)

独立的PV资源分离了卷的创建和使用,而PVC资源则进一步将卷的使用分为卷的申请和绑定:当用户创建一个PVC,表明要申请一个持久卷,控制器就会去找到合适的PV,然后将PVC的pvc.spec.volumeName设置为PV的名称,同时将PVC的信息写入PV的pv.spec.claimRef,将PV和PVC进行双向关联,这成为动态绑定

那什么才是合适的PV呢?或者说PV满足哪些条件才能被某个PVC进行绑定呢?

在这里插入图片描述

  • 容量:在PVC中是request,表明需要多大容量的PV,在PV中是capacity,表明当前PV的容量
  • 访问模式:accessModes,不同的存储系统有不同的访问特点,有的卷可以被多个Pod同时读写,有的只能以只读方式挂载
  • 存储类:storageClassName,创建PV的存储类型

当根据PVC去查找PV时,就会根据上述三个条件去找到对应的PV完成绑定操作。PVC使得用户选择不用自己去选择PV,而是让控制器帮我们选择合适的PV。

还剩下最后一个问题:PV应该是谁创建的?肯定有一个类似控制器的组件负责创建PV,该控制器能够接收创建PV的请求,根据请求中的参数创建对应规格的持久卷。

k8s可以对接许多不同的外部存储系统,为了区分这些存储系统,k8s提供了StorageClass资源,每个StorageClass代表一个存储系统,为了支持这个存储系统,在k8s中还会有一个provisoner的组件,它通过CSI接口与外部存储系统进行通信,负责PV的管理。

在这里插入图片描述

下面数理下整体的工作流程:

  • 用户创建PVC,说明要申请一个PV,此时的PVC的状态是Pending
  • provisioner监听到PVC的创建时,会根据PVC的参数调用CSI接口创建PV,此时PV的状态是Available,表明未被绑定
  • 控制器监听到PV的创建,并发现未被绑定的PVC,就会将二者进行绑定
  • 将PV挂载到容器中使用

下面的PVC申请2G大小的nfs存储卷:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  storageClassName: nfs

而在SC中:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"   ## 是否设置为默认的storageclass
provisioner: nfs.csi.k8s.io
parameters:
  archiveOnDelete: "true"                                  ## 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions: 
  - hard                                                   ## 指定为硬挂载方式
  - nfsvers=4 

上面的PVC指定storageClassName为nfs,表明要向nfs申请卷,下面的SC由于有is-default-class的annotations,它就是默认的SC,当PVC未指定storageClassName时,就会向nfs申请卷。SC中有个参数是provisioner,是provisioner的标识字符串,通常是csidriver驱动程序的名称,可以通过kubectl get csidrivers命令查询。

4 总结

本文介绍了k8s中的PV、PVC、SC等资源以及它们的出现分别解决了什么问题,并对资源的yaml文件的一些字段进行了解释。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1074614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++11(下)

目录 一、类的新功能1.1 默认成员函数1.2 类成员变量初始化1.3 强制生成默认函数的关键字default1.4 禁止生成默认函数的关键字delete1.5 继承和多态中的final与override关键字 二、可变参数模板三、lambda表达式3.1 C98中的一个例子3.2 lambda表达式3.3 lambda表达式语法3.4 函…

CUDA----window更新升级cuda版本

在安装库的过程中发现cuda版本不匹配。我torch安装的是11.7,但是我电脑上安装的是11.2故想升级。 但是我用nvidia-smi命令查询cuda是12.2,这让我费解,后来发现是得使用nvcc -V来查询安装的cuda版本。 详细的升级过程可以看这篇博客&#xff…

Android约束布局ConstraintLayout的Guideline,CardView

Android约束布局ConstraintLayout的Guideline&#xff0c;CardView <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:a…

C++ 类和对象篇(八) const成员函数和取地址运算符重载

目录 一、const成员函数 1. const成员函数是什么&#xff1f; 2. 为什么有const成员函数&#xff1f; 3. 什么时候需要使用const修饰成员函数&#xff1f; 二、取地址运算符重载 1. 为什么需要重载取地址运算符&#xff1f; 2. 默认取地址运算符重载函数 3. 默认const取地址运…

016-第三代软件硬件及系统选型

第三代软件硬件及系统选型 文章目录 第三代软件硬件及系统选型项目介绍硬件选型软件系统选型总结 关键字&#xff1a; Qt、 Qml、 研华、 ubuntu、 x86 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Language&…

java基础 日期工具类

目录结构&#xff1a; DateUtils.java package dateStudy; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class DateUtils {private static final String FORMAT_1"yyyy-MM-dd HH:mm:ss";//私有方法&#xf…

国家开放大学 模拟试题 训练

试卷代号&#xff1a;2136 管理会计 参考 试题 一、单项选择题&#xff08;每小题1分&#xff0c;共20分&#xff09; 1.管理会计依靠各种功能来助力企业战略&#xff0c;下列哪项是管理会计的核心功能( )。 A.评价功能 B.预测功能 C.决策功能…

计算机算法分析与设计(8)---图像压缩动态规划算法(含C++)代码

文章目录 一、知识概述1.1 问题描述1.2 算法思想1.3 算法设计1.4 例题分析 二、代码 一、知识概述 1.1 问题描述 1. 一幅图像的由很多个像素点构成&#xff0c;像素点越多分辨率越高&#xff0c;像素的灰度值范围为0~255&#xff0c;也就是需要8bit来存储一个像素的灰度值信息…

某果的一个小参数分析

分析链接:aHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbS9hY2NvdW50 分析目标&#xff1a;X-Apple-I-Fd-Client-Info 1.在浏览器搜索关键词&#xff0c;打下断点 我们再里面进行搜索&#xff0c;定位到这个位置&#xff0c;可以看到X-Apple-I-FD-Client-Info这个参数等于e&#xff0c;…

Netty深入浅出(无处不在的IO)

为什么要有Netty Netty是为了解决网络编程的复杂性和提供易于使用、高性能和可扩展的框架而开发的。它通过提供一组可重用的组件来处理网络通信的低级细节&#xff0c;例如套接字管理、线程和缓冲&#xff0c;简化了开发网络应用程序的过程。这使开发人员可以专注于应用程序逻…

前端学习| 第二章

CSS学习|第一章 前言一、概述1. 语法规定2. 代码风格 二、选择器1. 基础选择器标签选择器类选择器id选择器通配符选择器 2. 复合选择器后代选择器子元素选择器并集选择器伪类选择器链接伪类选择器focus 伪类选择器 三、引入方式四、显示模式1. 块元素2. 行内元素3. 行内块元素4…

FreeRTOS自我救赎3之USB虚拟串口

任何项目的功能都从需求出发&#xff0c;在这里我用的是斥侯蜂的一块STM32F407ZGT6 在开发一个项目的过程中&#xff0c;免不了串口调试&#xff0c;而这块板子板载的mircousb不是直接连的引脚而是一个OTGUSB

Qt实战 数据统计柱状图显示

前段时间有朋友找我做个问卷调查的软件&#xff0c;我说现在很多在线文档都有这功能&#xff0c;为啥还要使用Qt撸一个&#xff0c;他说要申请软著&#xff0c;我说&#xff0c;欧了。 我们先看看WPS在线问卷的统计中&#xff0c;柱状图统计的效果吧 我认为主要有以下几个关键…

集成显卡安装Pytorch

1、安装pytorch的第一步需要先安装Anaconda&#xff0c;安装步骤可看我这篇教程【Anaconda的下载与安装】 2、安装完Anaconda之后&#xff0c;第二步查看自己电脑的显卡类型&#xff0c;是集成显卡还是独立显卡&#xff0c;我的电脑是集成显卡&#xff0c;若你的是独立显卡&am…

磁盘满了对日志打印(Logback)的影响

背景 我们生产环境有一个服务半夜报警&#xff1a;磁盘剩余空间不足10%&#xff0c;请及时处理。排查后发现是新上线的一个功能&#xff0c;日志打太多导致的&#xff0c;解决方法有很多&#xff0c;就不赘述了。领导担心报警不及时、或者报警遗漏&#xff0c;担心磁盘满了对线…

OSPF的7大状态和5大报文详讲

- Down OSPF的初始状态 - Init 初始化——我刚刚给别人发Hello报文 我们可以将OSPF邻居建立的过程理解为&#xff1a;我和你打招呼&#xff0c;你和我打招呼&#xff0c;然后咱俩成了邻居 比如&#xff1a; R1和R2要建立OSPF邻居 R1给R2发送了Hello报文&#xff0c;但是R1此时…

如何提升和扩展 PostgreSQL — 从共享缓冲区到内存数据网格

利用共享缓存和操作系统缓存利用 RAM Postgres 是一个基于磁盘的数据库&#xff0c;即使您的整个架构是围绕磁盘访问设计的&#xff0c;利用 RAM 也很重要。如果按照人类规模的延迟来判断&#xff0c;这可以将延迟从几天缩短到几分钟&#xff08;图 1&#xff09;。只需看一下…

【SV中的多线程fork...join/join_any/join_none】

SV中fork_join/fork_join_any/fork_join_none 1 一目了然1.1 fork...join1.2 fork...join_any1.3 fork...join_none 2 总结 SV中fork_join和fork_join_any和fork_join_none; Note: fork_join在Verilog中也有&#xff0c;只有其他的两个是SV中独有的&#xff1b; 1 一目了然 1.…

CCF CSP认证 历年题目自练Day26

题目一 试题编号&#xff1a; 202012-1 试题名称&#xff1a; 期末预测之安全指数 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 题目分析&#xff08;个人理解&#xff09; 还是先看输出&#xff0c;此题简单的离谱&#xff0c;第一行输入小菜有几个测评依据…

1.3 第一个JAVA程序

1.3 第一个JAVA程序 **1.3 第一个Java程序** **前言:** 在1.2节中&#xff0c;我们学习了如何搭建Java开发环境。本节将带你编写并执行你的第一个Java程序。 **1. 编写Java源文件** - 在JDK的bin文件夹下新建文本文档&#xff0c;并重命名为HelloWorld.java。 - 使用记…