k8s

CSI总结

背景

下面我将以这个思维导图来总结一下CSI。
file

简介

早期的 Docker 采用 Device Mapper 作为容器运行时存储驱动,因为 OverlayFS 尚未合并进kernel。

目前 Docker 和 containerd 都默认以OverlayFS 作为运行时存储驱动;

OverlayFS 目前已经有非常好的性能,与DeviceMapper 相比优20%,与操作主机文件性能几乎一致。

存储插件管理

  • in-tree 插件:Kubernetes 社区已不再接受新的 in-tree 存储插件,新的存储必须通过 out-of-tree 插件进行支持。
  • out-of-tree FlexVolume插件:FlexVolume 是指 Kubernetes通过调用计算节点的本地可执行文件与存储插件进行交互。FlexVolume 插件需要宿主机用 root 权限来安装插件驱动。FlexVolume 存储驱动需要宿主机安装 attach、 mount等工具,也需要具有 root 访问权限。
  • out-of-tree CSI插件:
    CSI 通过 RPC 与存储驱动进行交互。
    在设计CSI 的时候,Kubernetes 对CSI 存储驱动的打包和部署要求很少,主要定义了 Kubernetes 的两个相关模块:

    • kube-controller-manager:
      • kube-controller-manager 模块用于感知CS!驱动存在。
        Kubernetes 的主控模块通过 Unix domain socket(而不是 CSI 驱动)或者其他方式进行直接地交互。
      • Kubernetes 的主控模块只与 Kubernetes 相关的 API 进行交互。
      • 因此 CSI 驱动若有依赖于 Kubernetes API 的操作,例如卷的创建、卷的 attach、卷的快照等,需要在CSI 驱动里面通过 Kubernetes 的 APl,来触发相关的CSI操作。
    • kubelet:
      • kubelet 模块用于与 CSI 驱动进行交互。
      • kubelet 通过 Unix domain socket 向 CSI 驱动发起 CSI 调用(如 NodeStageVolume、NodePublishVolume 等),再发起 mount 卷和 umount 卷。
      • kubelet 通过插件注册机制发现 CSI 驱动及用于和 CS1 驱动交互的 Unix Domain Socket。
      • 所有部署在 Kubernetes 集群中的 CSI 驱动都要通过 kubelet 的插件注册机制来注册自己。

CSI驱动

CSI 的驱动一般包含 external-attacher、 external-provisioner、 external-resizer、 external-snapshotter、 node-driver-register、 CSI driver 等模块,可以根据实际的存储类型和需求进行不同方式的部署。

file

临时存储

常见的临时存储主要就是 emptyDir 卷。

emptyDir 很常用,就是空卷。当 Pod 从节点上删除时,
emptyDir 卷中的数据也会被永久删除。但当 Pod 的容器因为某些原因退出再重启时,emptyDir 卷内的数据并不会丢失。

默认情况下,emptyDir 卷可以存储在本地磁盘或网络存储。

emptyDir 也可以通过将 emptyDir.medium 字段设置“Memory〞来通知 Kubernetes 为容器安装tmpfs,此时数据被存储在内存中,速度相对于本地存储和网络存储快很多。但是在节点重启的时候,内存数据会被清除。另外,使用 tmpfs 的内存也会计入
容器的使用内存总量中,受系统的 Cgroup 限制。

emptyDir 设计的初衷主要是给应用充当缓存空间,或者存储中间数据, 用于快速恢复。然而,这并不是说满足以上需求的用户都被推荐使用 emptyDir,我们要根据用户业务的实际特点来判断是否使用emptyDir。

因为 emptyDir 的空间位于系统根盘,被所有容器共享,所以在磁盘的使用率较高时会触发 Pod 的 eviction 操作,从而影响业务的稳定。

半持久化存储

常见的半持久化存储主要是 hostPath 卷。hostPath 卷能将主机节点文件系统上的文件或目录挂载到指定 Pod 中。对普通用户而言一般不需要这样的卷,但是对很多需要获取节点系统信息的 Pod 而言,却是非常必要的。一般是管理员使用。

例如,hostPath 的用法举例如下:

  • 某个 Pod 需要获取节点上所有 Pod 的 log,可以通过 hostPath 访问所有 Pod 的 stdout 输出存储目录,例如 /var/log/pods 路径。
  • 某个 Pod 需要统计系统相关的信息,可以通过 hostPath 访问系统的 /proc 目录。

使用 hostPath 的时候,除设置必需的 path 属性外,用户还可以有选择性地为 hostPath 卷指定类型,支持类型包含目录、字符设备、块设备等。

hostPath 卷注意事项

  • 使用同一个目录的 Pod 可能会由于调度到不同的节点,导致目录中的内容混乱。
  • Kubernetes 在调度时无法顾及由 hostPath 使用的资源。
  • Pod 被删除后,如果没有特别处理,那么 hostPath 上写的数据会遗留到节点上,占用磁盘空间。

持久化存储

支持持久化的存储是所有分布式系统所必备的特性。针对持久化存储,Kubernetes 引入了Storageclass、 Volume、 PVC (Persistent Volume claim)、 PV (Persitent Volume)的概念,将存储独立于 Pod 的生命周期来进行管理。

Kuberntes 目前支持的持久化存储包含各种主流的块存储和文件存储,例如 awsElasticBlockStore、azureDisk、 cinder、 NFS、 cephfs、 iscsi 等,在大类上可以将其分为网络存储和本地存储两种类型。

Storageclass

Storageclass 用于指示存储的类型,不同的存储类型可以通过不同的 Storageclass 来为用户提供服务。

Storageclass 主要包含存储插件provisioner、卷的创建和 mount参数等字段。

k get sc -o yaml

file

PVC

由用户创建,代表用户对存储需求的声明,主要包含需要的存储大小、存储卷的访问模式、Stroageclass 等类型,其中存储卷的访问模式必须与存储的类型一致。

file

k get pvc -o yaml

file

PV

由集群管理员提前创建,或者根据 PVC 的申请需求动态地创建,它代表系统后端的真实的存储空间,可以称之为卷空间。

k get pv 

file

存储对象关系

用户通过创建 PVC 来申请存储。控制器通过 PVC 的Storageclass 和请求的大小声明来存储后端创建卷,进而创建 PV,Pod 通过指定 PVC来引用存储。
file

分类: k8s
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x