[Kubernetes]PV,PVC,StorageClass之间的关系详解

时间:2021-02-09 02:00:23

在Kubernetes中,容器化一个应用比较麻烦的地方莫过于对其"状态"的管理,而最常见的"状态",莫过于存储状态.

[Kubernetes]深入理解StatefulSet这篇文章中,稍微提了一下PV(Persistent Volume)和PVC(Persistent Volume Claim),这篇文章详细说一说.

大概了解

我先大体说一下整个过程,有一个小小的认识,然后我再详细展开说.

用户提交请求创建Pod时,Kubernetes发现这个Pod声明使用了PVC,这时就需要PersistentVolumeController帮它找一个PV来进行配对.如果有的话呢,就直接进行绑定.但是如果没有呢?就去找对应的StorageClass,帮它新创建一个PV,然后再和PVC进行绑定.但是请注意,此时新创建的PV,只是一个API对象,还需要经过"两阶段"处理变成宿主机上的"持久化Volume"才算是真正有用.这个时候,Pod就可以正常启动,并将相关文档挂载到容器内指定的路径.

我知道你对上面的过程肯定有些懵了,别急,咱们慢慢把这个过程剖析一下.

持久化Volume

比较难理解的应该就是需要经过"两阶段"处理变成宿主机上的"持久化Volume"这部分内容了.

所谓"持久化Volume",指的就是这个宿主机上的目录,具备"持久性",也就是说:这个目录里面的内容,既不会因为容器的删除而被清理掉,也不会和当前的宿主机进行绑定.这样,当容器被重启或者在其他节点上重建出来之后,仍然能够通过挂载这个Volume来访问到目录里面的内容.

这里面主要有两个关键点:一,不会因为容器的删除而清理掉里面的内容,二,不会和当前的宿主机进行绑定.Kubernetes需要做的工作就是达到这两个目的,从而使得目录具备"持久性".

Kubernetes在这个准备"持久化"宿主机目录的过程中,我们可以形象的称为"两阶段处理":

第一阶段:为虚拟机挂载磁盘,把这个阶段称为"Attach".

第二阶段:挂载磁盘之后,如果想要使用,还需要将挂载的磁盘进行格式化处理,并挂载到Volume宿主机目录上,这个阶段称为"Mount",而这个挂载点,正是Volume的宿主机目录.所以,Mount阶段的操作,可以这样来表示:

# 通过 lsblk 命令获取磁盘设备 ID
$ sudo lsblk
# 格式化成 ext4 格式
$ sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/< 磁盘设备 ID>
# 挂载到挂载点
$ sudo mkdir -p /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 类型 >/<Volume 名字 >
#如果kubelet需要作为client,将远端NFS服务器的目录挂载到Volume的宿主机目录上,则需要执行以下命令:
$ mount -t nfs <NFS 服务器地址 >:/ /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 类型 >/<Volume 名字 >

以上两个阶段完成之后,我们在这个目录里写入的所有文件,就都会被保存起来,从而实现了对这个Volume宿主机目录的"持久化".(如果给虚拟机扩充过磁盘的话,对这一部分内容应该是比较容易理解的)

但是对于Kubernetes来说,它是如何定义和区分这两个阶段的呢?

其实很简单,在具体的Volume插件的实现接口上,Kubernetes分别给这两个阶段提供了两种不同的参数列表:

  • 对于"Attach":Kubernetes提供的可用参数是nodeName,即宿主机名字.
  • 对于"Mount",Kubernetes提供的可用参数是dir,即Volume的宿主机目录.
  • 所以,在具体使用时,只需要根据自己的需求进行选择和实现就可以达到目的了.
    这就是Kubernetes的Volume处理机制的相关说明了.
    接下来说说另外一个重要的概念:StorageClass

    StorageClass

    PV这个对象的创建,是由运维人员来完成的,但是在大规模的生产环境中,这其实是一个非常麻烦的操作.因为在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败.这在自动化中,肯定是不能被允许的.

    所以,Kubernetes提供了一套可以自动创建PV的机制,即:Dynamic Provisioning.而这个机制的核心在于:StorageClass这个API对象.

  • StorageClass对象会定义下面两部分内容:
    • 1,PV的属性.比如,存储类型,Volume的大小等.
    • 2,创建这种PV需要用到的存储插件
  • 有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV.

    但是其实使用起来是一件很简单的事情,你只需要根据自己的需求,编写YAML文件即可,然后使用kubectl create命令执行即可.

    最后小结

    到这里,讲的就差不多了.

    综上所述呢,PVC描述的是Pod想要使用的持久化存储的属性,比如存储的大小,读写权限等.而PV则是一个具体的Volume属性,比如Volume的类型,挂载目录等.而StorageClass的作用,则是充当PV的模板,从而可以动态创建需要的PV.

    最后,放一张图片,描述一下概念之间的关系:

    [Kubernetes]PV,PVC,StorageClass之间的关系详解

    些许的碎碎念

    最后的最后,写点儿碎碎念.如果看的进去的话,就看看,看不进去,就算了.

    今天早上打开手机,收到了一条消息:

    [Kubernetes]PV,PVC,StorageClass之间的关系详解

    在上面介绍StorageClass的时候,我说了,如果想要使用的话,其实是一件很简单的事情,只需要写一下YAML文件即可.但是背后的原理如果不去深究,不去学习的话,遇到问题的时候,还是无从下手的.

    还记得当时倒腾k8s,一个月的时间就倒腾的差不多了,项目上线的时候,也是有惊无险的撑了下来.所以呢,如果只是达到会用的层次的话,一个月的时间就差不多了.

    但是如果想要有所提高,想要在遇到问题时,能够准确定位,还是需要再回来补充理论.

    做技术,前期的实践固然是不可少,但是后期的理论也要做.绝对不能仅仅停留在会用的层次上面,如果有时间,有精力,最好还是能够再深入理解一下背后的原理知识.

    这也是我一直坚持的学习方法:基于实践,补充理论.

    以上内容来自我学习<深入剖析Kubernetes>专栏文章之后的一些见解,有偏颇之处,还望指出.

    感谢您的阅读~

    [Kubernetes]PV,PVC,StorageClass之间的关系详解的更多相关文章

    1. MySQL表与表之间的关系详解

      外键 说到表与表之间的关系就不得不说到一个关键词:外键 MySQ中的外键是什么,和表与表之间有什么关联? 外键(foreign key)又叫外连接, 在数据库中发挥着重要的作用 尤其是对于表和表之间的 ...

    2. Kubernetes Pv &amp&semi; Pvc

      Kubernetes PV & pvc 介绍 PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的两种API资源,用于抽象存储细节.管理 ...

    3. 【转】UML类图与类的关系详解

      UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(D ...

    4. UML类图与类的关系详解

      摘自:http://www.uml.org.cn/oobject/201104212.asp UML类图与类的关系详解 2011-04-21 来源:网络 在画类图的时候,理清类和类之间的关系是重点.类 ...

    5. slf4j log4j logback关系详解和相关用法

      slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...

    6. Hibernate中的多对多关系详解&lpar;3&rpar;&ZeroWidthSpace;

      前面两节我们讲到了一对一的关系,一对多,多对一的关系,相对来说,是比较简单的,但有时,我们也会遇到多对多的关系,比如说:角色与权限的关系,就是典型的多对多的关系,因此,我有必要对这种关系详解,以便大家 ...

    7. Android 应用程序之间内容分享详解(二)

      转载请注明出处:http://blog.csdn.net/xiaanming/article/details/9428613 Android 应用程序之间内容分享详解(一) 之前给大家分享了你开发的应 ...

    8. slf4j log4j logback log4j2关系详解和相关用法

      来源:slf4j log4j logback关系详解和相关用法https://www.cnblogs.com/Sinte-Beuve/p/5758971.html The Simple Logging ...

    9. main&period;js index&period;html与app&period;vue三者关系详解

      main.js index.html与app.vue三者关系详解 2019年01月23日 11:12:15 Pecodo 阅读数 186   main.js与index.html是nodejs的项目启 ...

    随机推荐

    1. WinForm中MouseEnter和MouseLeave混乱的问题

      MouseEnter+MouseLeave不行,我用了MouseMove+MouseLeave,效果一样 最近做个聊天的系统,仿照qq的界面设计,像qq聊天界面中字体.表情.截图等图片,鼠标放上去显示 ...

    2. python之类的属性

      class type(object) With one argument, return the type of an object. The return value is a type objec ...

    3. CRM 2013 移动终端 介绍和PAD下载地址

      IPHONE 浏览器界同 Pad 端 APP  (目前不支持中文,大家可以用美国账号下载,谁有分享一下) https://itunes.apple.com/en/app/microsoft-dynam ...

    4. ios开发--tcp&sol;ip

      简介 该篇文章主要回顾--TCP/IP协议族中的TCP/UDP.HTTP:还有Socket.(--该文很干,酝酿了许久!你能耐心看完吗?) 我在这个文章中,列举了常见的TCP/IP族中的协议,今天主角 ...

    5. Referenced file contains errors &lpar;http&colon;&sol;&sol;www&period;springframework&period;org&sol;schema&period;&period;&period;错误--转载

      Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-3.0.xsd). ...

    6. Masonry等比缩放

      第一种: CGFloat width = CGRectGetWidth([[UIScreen mainScreen] bounds]);         CGFloat aspectRatio = 1 ...

    7. JXL 读取 Excel java中jxl导出数据到excel的例子 上传文件

      2010-10-14 19:17:06 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info 信息: Entferne Dat ...

    8. MAC OS 常用软件及开发工具

      1.各个版本的 Mac OS 链接: http://pan.baidu.com/s/1mgDtCi0 密码: 4y3u 2.Xcode xcode_4.6.3 链接: http://pan.baidu ...

    9. OC-UICollectionView实现瀑布流

      UICollectionView实现瀑布流 在iOS中可以实现瀑布流的目前已知的有2种方案: 使用UIScrollView自己封装一套,这种方案是应用于iOS6之前的,因为iOS6才出来UIColle ...

    10. R学习笔记 第五篇:数据变换和清理

      在使用R的分组操作之前,首先要了解R语言包,包实质上是实现特定功能的,预先写好的代码库(library),R拥有大量的软件包,许多包都是由某一领域的专家编写的,但并不是所有的包都有很高的质量的,在使用 ...