本篇是《深入剖析 Kubernetes》 的读书笔记,作者为张磊老师。

# PersistentVolumeClaim & PersistentVolume

Pod 一章讲过了这两个概念,这里再复制一遍。

Pod -> PVC -> PV

PVC 是定义接口(大小、AccessModes 等),PV 是实现(实际存储位置、认证信息等)。而 Pod 只需要在配置里面把 PVC 挂载到指定路径就行。

# Kubernetes 处理 PV 的流程

  1. Attach(将存储块连接到 k8s)操作,其控制循环的名字为 AttachDetachController,由位于 Master 结点的 Volume Controller 负责。
  2. Mount(将存储块挂载到容器)操作,其控制循环的名字为 VolumeManagerReconciler,由位于 Node 结点的 kubelet 负责。

在删除 PV 时,反序执行这两个操作,即 Unmount 然后 Detach 即可。

# StorageClass

StorageClass 是一个资源,用来定义 PV 的属性(比如存储类型、存储大小、存储位置等)。StorageClass 也可以定义 Provisioner(提供者),用来动态创建 PV。

# 自定义存储插件

K8s 开发存储插件的方式有两种:FlexVolumeCSI。前者更轻量级、编写简单,后者更强大、支持更多功能。

# FlexVolume

编写一个 FlexVolume 插件,只需要提供一个可执行文件(shell 或者二进制文件均可)。这个可执行文件需要支持几条命令:/path/to/binary mount <mount_dir> <json_params>,以及对应的 unmountattachdetach 等命令即可。Kubernetes 在创建/删除 PV 时,会按照 Attach、Mount / Unmount、Detach 的顺序调用这些命令。

FlexVolume 的缺点也很明显:不支持动态创建 PV、快照、克隆等功能;Attach、Mount、Unmount、Detach 的操作也是独立的,换句话说,无法将 Mount 时产生的上下文存储起来,供 Unmount 时使用。

# CSI Volume

而 CSI 则是一个更复杂的规范,需要实现一堆接口,Attach、Detach、Mount、Unmount 等步骤都得自己造轮子。不过造轮子的好处就是有更大的自定义空间;除此之外,CSI 还支持更多的功能,比如动态创建 PV、快照、克隆等。

以及,CSI(容器存储接口)的定义和实现是通用的、独立于 K8s 的。这意味着 CSI 的实现会和 K8s 资源的实现(控制循环等)不太一样,CSI API 里也不会使用 Kubernetes 里的 PV 概念,而是用自己定义的 CSI Volume 概念。

K8s CSI Framework

K8s 使用 CSI 的架构下,涉及到更多的组件。

有三个外部组件:Driver Registrar、External Provisioner、External Attacher,对应从 K8s 那层剥离出来负责 Amount、Detach 的功能。外部组件是相较于 K8s 核心组件而言的,它们仍然由 K8s 团队维护,这三个组件的作用就是让 K8s 能够对接、调用 CSI 插件的接口。

右边三个组件:CSI Identity、CSI Controller、CSI Node,就是纯 CSI 实现的代码,是 CSI 插件开发者需要实现的部分。可以参考 csi-driver-nfs (opens new window) 的源码。

组件 部署位置 作用
Driver Registrar Master 节点 负责注册 CSI 插件
External Provisioner Master 节点 负责从 kube-apiserver 监听 PVC 对象,然后调用 CSI Controller 动态创建 CSI Volume
External Attacher Master 节点 负责从 kube-apiserver 监听 VolumeAttachment 对象,然后调用 CSI Controller Attach/Detach
kubelet (on Worker Node) Worker 节点 负责 Mount/Unmount CSI Volume
- - -
CSI Identity Master & Worker 节点 负责暴露插件的元信息
CSI Controller Master 节点 负责动态创建 CSI Volume、快照、克隆、Attach/Detach CSI Volume 等
CSI Node Worker 节点 负责 Mount/Unmount CSI Volume

书里也讲解了 DigitalOcean 的 CSI 插件的实现,可以参考 digitalocean/csi-digitalocean (opens new window) 的源码。