菜单

本页使用了机器翻译。某些内容可能不完美。敬请提出宝贵意见和建议。

分享反馈

Kubernetes CSI:CSI 卷的基础知识以及如何构建 CSI 驱动程序

目录

分享该页面

Yifat Perry
Yifat Perry

什么是 Kubernetes CSI?

Kubernetes CSI 是特定于 Kubernetes 的容器存储接口(CSI)实现。CSI 规范提供了一个标准,支持存储系统和容器编排 (CO) 平台之间的连接。它是 Kubernetes 存储管理的基础。

CSI 标准确定了任意块和文件存储系统如何暴露于 Kubernetes 等容器化系统上的工作负载。第三方存储供应商可以使用 CSI 构建并部署插件,使 Kubernetes 能够与新的存储系统配合使用,而无需编辑 Kubernetes 的核心代码。

在本文中:

对 CSI 的需求

在容器存储接口之前,Kubernetes 仅支持使用树内 k8s 卷插件,这些插件必须使用核心 Kubernetes 二进制文件进行编写和部署。这意味着存储提供商必须签入其 k8s 插件的核心代码库,以支持新的存储系统。

Flex-volume 是一种基于插件的解决方案,它试图通过将基于可执行文件的 API 暴露给第三方插件来解决此问题。虽然这种解决方案在与 k8s 二进制文件分离方面与 CSI 的原理相似,但这种方法存在许多问题。首先,它需要对主节点和主机文件系统进行 root 访问,以实现驱动程序文件的部署。其次,它带来了操作系统依赖性和先决条件的巨大负担,这些都被认为可以从主机上获得。

CSI 通过使用容器化和利用 k8s 存储原语来解决这些问题。CSI 已成为启用树外存储插件的无处不在的解决方案。它允许存储提供商通过标准 k8s 原语(如存储类、PersistentVolumes (PVs) 和 PersistentVolumeClaims (PVCs))部署插件。

CSI 的主要目标是标准化在每个容器编排器中公开所有类型存储系统的机制。

相关内容:阅读我们的 Kubernetes Persistent Volumes 指南

如何使用 CSI 卷?

CSI 卷可用于配置 PersistentVolume 资源,这些资源可由 Kubernetes 工作负载使用。您可以动态配置 PersistentVolumes(当工作负载请求时)或手动配置。

动态配置

您可以创建引用 CSI 存储插件的 StorageClass。这使 Kubernetes 工作负载能够动态创建 PersistentVolumes。保存到这些 PersistentVolumes 的数据将保留到 CSI 插件中定义的存储设备。

例如,以下 StorageClass 允许使用名为 "csi-driver.example.com" 的 CSI 插件配置 "fast-storage" 类型的存储卷。(此示例以及下面的其他示例在 Kubernetes CSI 官方博客文章中分享)

csi 1

当 Kubernetes 实体创建一个请求此 StorageClass 的 PersistentVolumeClaim 对象时,属于该 StorageClass 的 PersistentVolume 会被动态配置。下图展示了一个引用 fast-storage StorageClass 的 PVC 示例。

csi 2

请注意,在上面的 StorageClass 定义中,有三个参数:type 和两个名为 mysecret 和 mynamespace 的 secret。当声明 PVC 时,幕后发生的事情如下:

  1. StorageClass 在 CSI 插件 (csi-driver.example.com) 上执行 CreateVolume 调用,传递参数,包括允许访问存储设备的 secrets。
  2. Kubernetes 会自动创建一个 PersistentVolume 对象,表示物理存储在 CSI 插件设备上的存储卷。
  3. Kubernetes 将 PersistentVolume (PV) 对象绑定到相关 PersistentVolumeClaim (PVC)。
  4. 从这一点开始,提出声明的 pod 或容器可以使用存储卷。

阅读我们的博客文章:Dynamic Kubernetes Persistent Volume Provisioning with NetApp Trident and Cloud Volumes ONTAP

手动配置

您可以在 Kubernetes 中手动调配卷,并在不使用 PVC 机制的情况下使其可用于工作负载。下图提供了一个 PV 对象的示例,该对象允许工作负载使用名为"existingVolumeName"的存储卷。如上所述,CSI 卷引用存储插件 csi-driver.example.com。

csi 3

连接和挂载卷

下图提供了一个示例,展示了 Kubernetes Pod 模板如何引用 PVC 来访问 CSI 卷。

当 Pod 模板中出现 PersistenVolumeClaim 时,每次调度 Pod 时,Kubernetes 都会在 CSI 插件上触发多个操作,包括 ControllerPublishVolume、NodeStageVolume 和 NodePublishVolume。这将创建一个存储卷,挂载它,并使其可供在 Pod 中运行的容器使用。

csi 4

为 Kubernetes 构建自己的 CSI 驱动程序

CSI 驱动程序组件

Kubernetes 中的 CSI 驱动程序通常部署有控制器和每个节点的组件。

控制器组件
控制器插件部署为 Deployment 或 StatefulSet,可以安装在集群内的任何节点上。它包括实现 CSI Controller 服务的 CSI 驱动程序以及 sidecar 容器(或多个容器)。控制器 sidecar 容器通常与 Kubernetes 对象交互,并调用 CSI Controller 服务。

控制器不需要直接访问主机 - 它可以通过外部控制平面服务和 Kubernetes API 执行所有操作。可以部署控制器组件的多个副本以实现高可用性 (HA),但应实施领导者选择,以确保在任何给定时间只有一个控制器处于活动状态。

控制器侧车包括 external-provisioner、external-attacher、external-snapshotter 和 external-resizer。在部署中包含某些侧车可以是可选的,具体取决于侧车页面中详细说明的规格。

控制器与负责管理 Kubernetes 事件的 sidecar 容器进行通信。控制器然后向 CSI 驱动程序发送相关调用。通过 emptyDir 卷共享 UNIX 域套接字,从而实现 sidecar 和驱动程序之间的调用。

控制器侧车使用基于角色的访问控制 (RBAC) 规则来管理它们与 Kubernetes 对象的交互。侧车存储库提供了可以合并到 RBAC 策略中的 RBAC 配置示例。

每节点组件
应通过 DaemonSet 在集群中的所有节点上部署节点插件。它包括实现 CSI 节点服务的 CSI 驱动程序和充当节点驱动程序注册器的 sidecar 容器。

节点组件与 kubelet 进行通信,kubelet 在所有节点上运行,并处理 CSI 节点服务的调用。调用可以从存储系统挂载或卸载存储卷,并使它们可供 pod 使用。kubelet 使用通过主机上的 HostPath 卷共享的 UNIX 域套接字来调用 CSI 驱动程序。node-driver-registrar 使用额外的 UNIX 域套接字将驱动程序注册到 kubelet。

节点插件需要直接访问主机以装载驱动程序卷。为了使文件系统挂载和块设备可用于 kubelet,CSI 驱动程序需要使用一个双向挂载点,使 kubelet 能够看到驱动程序容器创建的挂载。

部署

container-storage-interface_diagram1

Kubernetes 不确定 CSI 卷驱动程序的打包,但它确实提供了在 Kubernetes 上简化容器化 CSI 驱动程序部署的建议。

建议存储供应商在部署容器化 CSI 卷驱动程序时采取以下步骤:

  • 创建一个容器以实现卷插件的行为,并通过 UNIX 域套接字公开 gRPC 接口。容器应标记为"CSI 卷驱动程序",并根据 CSI 规范进行配置(具有控制器、节点和身份服务)。
  • 使用 Kubernetes 团队提供的其他容器对卷驱动程序容器进行分组,例如 external-attacher、external-provisioner、cluster-driver-registrar、node-driver-registrar、external-resizer、external-snapshotter 和 livenessprobe。这些容器促进了驱动程序容器与 Kubernetes 的交互。
  • 指导集群管理员部署相关的 DaemonSet 和 StatefulSet,并在 Kubernetes 集群中添加对供应商存储系统的支持。

另一种可能更简单的部署选择是将所有组件放在一个 DaemonSet 中,包括 external-provisioner 和 external-attacher。但是,此策略消耗更多资源,并且需要为 external-attacher 和 external-provisioner 组件使用领导者选举协议(例如 https://git.k8s.io/contrib/election)。

启用特权 Pod

Kubernetes 集群必须启用特权 pod 才能允许使用 CSI 驱动程序。例如,您需要将 kubelet 和 API 服务器的 --allow-privileged 标志设置为 true—在某些环境中,例如 kubeadm、GCE 和 GKE,这是默认值。

必须使用以下特权标志启动 API 服务器:

$ ./kube-apiserver ...--allow-privileged=true ...$ ./kubelet ...--allow-privileged=true ...

 

启用挂载传播

容器存储接口需要装载传播功能,该功能使装载的卷能够在同一节点或 Pod 内的容器之间共享。集群的 Docker 守护进程需要允许挂载共享以启用挂载传播。

基于 NetApp Cloud Volumes ONTAP 的 Kubernetes CSI

NetApp Cloud Volumes ONTAP,领先的企业级存储管理解决方案,在 AWS、Azure 和 Google Cloud 上提供安全、经过验证的存储管理服务。Cloud Volumes ONTAP 容量可以扩展到数 PB,它支持各种用例,如文件服务、数据库、DevOps 或任何其他企业工作负载,具有强大的功能,包括高可用性、数据保护、存储效率、Kubernetes 集成等。

特别是,Cloud Volumes ONTAP 支持Kubernetes 持久卷配置和管理容器化工作负载的要求。

详细了解 Kubernetes NFS Provisioning File Services with Cloud Volumes ONTAP 和 Trident

详细了解 Cloud Volumes ONTAP 如何帮助解决这些 Kubernetes 工作负载与 Cloud Volumes ONTAP 案例研究中容器化应用程序的挑战。

Drift chat loading