k8s 中 pv/pvc 与 volume 的关系是什么?
pv/pvc 如何与 pod 产生关系的?(pv 对象如何转换为持久化的 volume 的呢?)

PersistentVolume (PV) 是对持久化存储数据卷的描述,代表了外部存储系统中的一块存储空间,属于集群级别的资源,不属于任何名称空间,由管理员创建和维护。PV 是具有持久性的 Volume,生命周期独立于 Pod。

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。

PV 支持 Static Provision 和 Dynamical Provision。
前者的使用流程是:提前创建 PV -> 声明 PVC -> Pod 的 volume 引用 PVC
后者是通过 StorageClass 实现的,StorageClass 是创建 PV 的模板,该对象会定义 pv 的属性以及创建 pv 需要用到的存储插件。(StorageClass 除了用于 Dynamical Provision,还在 pvc 与 pv 绑定时用于名字匹配)

持久化宿主机目录

PV 只是代表了一块外部存储,当已经有了 PV 之后,PV 如何与宿主机的目录产生联系的呢?(只有产生联系之后,pod 才能真正感知并使用)
需要进行两部分处理:

  1. Attach:为虚拟机挂载远程磁盘

    由 Volume Controller 负责维护的,这个控制循环的名字叫作:AttachDetachController。它会不断地检查每一个 Pod 对应的 PV,和这个 Pod 所在宿主机之间挂载情况。从而决定,是否需要对这个 PV 进行 Attach(或者 Dettach)操作。这段逻辑运行在 k8s Master 节点上的。

    k8s 提供的可用参数是 nodeName,即宿主机的名字。

  2. Mount:将磁盘设备格式化并挂载到 Volume 宿主机目录的操作

    当一个 Pod 调度到一个节点上之后,kubelet 就要负责为这个 Pod 创建它的 Volume 目录。默认情况下 kubelet 为 Volume 创建的目录是一个宿主机上的路径,比如 /var/lib/kubelet/pods//volumes/kubernetes.io~/,这个宿主机目录会作为远程存储磁盘的挂载点。

    控制循环的名字是 VolumeManagerReconciler,是 kubelet 组件的一部分,以独立于 kubelet 主循环的 Goroutine 方式运行在 Pod 对应的宿主机上。

    k8s 提供的可用参数是 dir,即 Volume 的宿主机目录。