Please enable Javascript to view the contents

K8s网络CSI-面试速记

 ·  ☕ 5 分钟

存储相关概念PV、PVC、StorageClass?

PV: 描述持久化存储数据卷(存储类型、挂载目录、远程存储服务器地址等)
PVC: 描述Pod希望使用的持久化存储的属性(存储大小、读写权限等)
StorageClass: 创建PV的模板,包含两方面内容:PV的属性(存储类型、大小等);创建PV的存储插件信息(例如ceph)

PVCPV是如何进行绑定的?

  1. spec字段:PV的存储大小必须满足PVC的要求;
  2. StorageClass: PV与PVC的StorageClass字段必须一样;

VolumeController有哪些功能?

  1. PersistentVolumeController: 不断监听每个PVC,如果未绑定pv,则遍历所有可用PV与未绑定的PVC进行绑定(所谓绑定,就是将PV对象的名字填在PVC.spec.volumeName字段上)
  2. AttachDetachController: 不断检查每个Pod对应的PV,与Pod所在虚拟机的挂载情况,从而对PV执行Attach\Detach操作。
  3. VolumeManagerReconciler: 运行在每个节点,但独立于kubelet主循环外的Goroutine。

容器挂载持久化存储的两阶段处理

  1. 第一阶段:Attach。pod调度到节点上,当前节点的kubelet会根据Volume类型为pod创建Volume,如果是远程块存储,kubelet会调用存储接口创建远程磁盘并挂载到当前节点(/dev/sdb)。
  2. 第二阶段,Mount。kubelet格式化挂载的磁盘,并此磁盘挂载到宿主机的容器目录(/var/lib/kubelet/pods/<podID>/volumes)。

NFS较为简单,Attach的操作跳过(对于NFS来说,并无磁盘挂载虚拟机)

之后,kubelet将volume目录通过CRI中的Mounts参数传递给容器运行时(如,docker),就可以为Pod里的容器挂载持久化存储了。

删除PV时,需要执行什么操作?

  1. Unmount
  2. Detach

StorageClass存在的意义

手动创建维护PV的工作太庞杂,因此K8S提供了自动创建PV的机制Dynamic Provisioning机制。而StorageClass就是其工作机制的核心。

  1. 充当PV的模板,且只有StorageClass相同的PV与PVC才能绑定在一起;
  2. 指定PV的存储插件(Provisioner),当存储插件支持Dynamic Provisioning机制时,实现PV的自动创建。

pod-pvc-pv.png

LocalPath模式如何避免pv与pvc的绑定过程与Pod的调度过程冲突?

在StorageClass的定义时,声明属性volumeBindingMode=WaitForFirstConsumer(延迟绑定),即pv与pvc的绑定延迟到pod调度之后,这样就不会与pod的调度策略冲突。

延迟绑定为什么与Dynamic Provisioning机制冲突?

因为Dynamic Provisioning机制会调用pvc指定的sc中的provisioner自动创建pv,一旦pv创建则固定node

K8S存储方案的演进过程是?

  1. Volume Plugins:k8s早期版本中Volume Plugins是用于提供持久化存储的主要方式,由K8S核心团队维护。
    缺点:新的存储类型、功能很难被引入和部署。

  2. FlexVolume: K8S-v1.8引入的一种存储插件扩展方式。外部插件以二进制文件与配置,并实现一定接口(init\attach\detach\waitforattach\isattached\mountdevice\unmountdevice\mount\unmount),kubelet通过插件在宿主机上执行接口命令。(FlexVolume仅仅是两阶段的执行者,无法管理pv的生命周期)
    缺点:1. 不支持DynamicProvisioning; 2. FlexVolume每一次对插件可执行文件的调用是独立的,mount时的上下文无法在unmount时复用。
    K8S-VolumePlugin-arch.png

  3. CSI:设计思想,**把Dynamic Provision,以及 Kubernetes 里 的一部分存储管理功能,从主干代码里剥离出来,做成了几个单独的组件。**这些组件会监听API-Server与存储相关的变化,来执行具体的存储管理动作。这些管理动作(如arrach\mount阶段)实际是通过调用csi插件完成。
    K8S-CSI-arch.png

    • External Components(由K8S社区维护): K8S项目中剥离的存储管理功能;

      • Driver Register: 负责将插件注册到kubelet
      • External Provisioner: 监听PVC对象,当PVC创建时调用CSI Controller的CreateVolume方法创建PV(公有云则调用公有云的API,)完成Provision阶段
      • External Attacher: 监听VolumeAttechment对象,当其创建时调用CSI Controller的ControllerPublish方法,完成对应volume的Attach阶段;

      以上三个组件会作为sidecar的形式与CSI插件位于同一个Pod中

    • Custom Components(CSI插件):

      • CSI Identity:对外暴露插件本身的信息
      • CSI Controller(Master节点): 定义对 CSI Volume(对应 Kubernetes 里的 PV)的管理接口(Create\Delete\Attach\Detach\Snapshot等),调用它的服务是
      • CSI Node(Node节点):是由Kubelet的VolumeManagerReconciler 控制循环检测,并调用CSI Node的Mount完成磁盘格式化、挂载指定目录(Mount阶段)
FlexVolumeAttach(挂载虚拟机)、Mount(格式化、挂载至宿主机目录)
CSIProvision(创建磁盘)、Attach 和 Mount

Docker与K8S有哪几种存储类型?

Docker容器有:

  1. BindMount: 外部宿主机的磁盘存储到内部容器存储的映射关系。即存储位置局限在宿主机,存储介质只是物理磁盘,存储管理只有映射关系。

  2. VolumeMount:

K8S容器编排存储:

  1. 普通Volume: 只用来提供共享的存储资源,声明周期与Pod相同
  2. PV: 生命周期与pod无关

Kubelet主循环

kubelet 主控制循环(Kubelet Sync Loop)

设计原则:主控制循环绝对不可以被 block。

分享

Hex
作者
Hex
CloudNative Developer

目录