本篇是《深入剖析 Kubernetes》 的读书笔记,作者为张磊老师。
# PersistentVolumeClaim & PersistentVolume
Pod 一章讲过了这两个概念,这里再复制一遍。
Pod -> PVC -> PV
PVC 是定义接口(大小、AccessModes 等),PV 是实现(实际存储位置、认证信息等)。而 Pod 只需要在配置里面把 PVC 挂载到指定路径就行。
# Kubernetes 处理 PV 的流程
- Attach(将存储块连接到 k8s)操作,其控制循环的名字为 AttachDetachController,由位于 Master 结点的 Volume Controller 负责。
- Mount(将存储块挂载到容器)操作,其控制循环的名字为 VolumeManagerReconciler,由位于 Node 结点的 kubelet 负责。
在删除 PV 时,反序执行这两个操作,即 Unmount 然后 Detach 即可。
# StorageClass
StorageClass 是一个资源,用来定义 PV 的属性(比如存储类型、存储大小、存储位置等)。StorageClass 也可以定义 Provisioner(提供者),用来动态创建 PV。
# 自定义存储插件
K8s 开发存储插件的方式有两种:FlexVolume 和 CSI。前者更轻量级、编写简单,后者更强大、支持更多功能。
# FlexVolume
编写一个 FlexVolume 插件,只需要提供一个可执行文件(shell 或者二进制文件均可)。这个可执行文件需要支持几条命令:/path/to/binary mount <mount_dir> <json_params>
,以及对应的 unmount
、attach
、detach
等命令即可。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 的架构下,涉及到更多的组件。
有三个外部组件: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) 的源码。