这篇文章已超过一年。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已不正确。
介绍 Kubernetes 的容器存储接口 (CSI) Alpha 功能
Kubernetes 的关键差异化特性之一是强大的卷插件系统,它使得许多不同类型的存储系统能够
- 在需要时自动创建存储。
- 将存储提供给无论调度到何处的容器。
- 不再需要时自动删除存储。然而,向 Kubernetes 添加对新存储系统的支持一直具有挑战性。
Kubernetes 1.9 引入了容器存储接口 (CSI) 的 Alpha 实现,这使得安装新的卷插件就像部署一个 Pod 一样简单。它还使得第三方存储提供商能够开发解决方案,而无需修改 Kubernetes 核心代码库。
由于此功能在 1.9 版本中处于 Alpha 阶段,必须显式启用。不建议在生产环境中使用 Alpha 功能,但它们很好地指示了项目未来的方向(在本例中,朝着更具可扩展性和基于标准的 Kubernetes 存储生态系统发展)。
为什么选择 Kubernetes CSI?
Kubernetes 卷插件目前是“树内”的,这意味着它们与 Kubernetes 核心二进制文件链接、编译、构建和打包在一起。向 Kubernetes 添加对新存储系统 (卷插件) 的支持需要将代码提交到 Kubernetes 核心仓库。但是,与 Kubernetes 发布流程保持一致对于许多插件开发者来说非常痛苦。
现有的Flex Volume 插件试图通过为外部卷插件暴露一个基于 exec 的 API 来解决这一痛点。虽然它使得第三方存储供应商能够编写树外驱动程序,但要部署第三方驱动程序文件,它需要访问节点和主节点的根文件系统。
除了部署困难之外,Flex 并未解决插件依赖的痛点:卷插件通常有很多外部依赖(例如对挂载和文件系统工具的依赖)。这些依赖项被假定在底层主机操作系统上可用,但情况往往并非如此(并且安装它们需要访问节点机器的根文件系统)。
CSI 解决了所有这些问题,它使得存储插件可以在树外开发、容器化、通过标准 Kubernetes 原语部署,并可通过用户熟悉和喜爱的 Kubernetes 存储原语(PersistentVolumeClaims、PersistentVolumes、StorageClasses)使用。
什么是 CSI?
CSI 的目标是为容器编排系统 (CO) 建立一种标准化机制,以便将任意存储系统暴露给其容器化工作负载。CSI 规范是在各种容器编排系统 (CO) 的社区成员合作下诞生的,包括 Kubernetes、Mesos、Docker 和 Cloud Foundry。该规范独立于 Kubernetes 开发,并维护在https://github.com/container-storage-interface/spec/blob/master/spec.md。
Kubernetes v1.9 暴露了 CSI 规范的 Alpha 实现,使得 CSI 兼容的卷驱动程序可以部署在 Kubernetes 上并由 Kubernetes 工作负载使用。
如何在 Kubernetes 集群上部署 CSI 驱动程序?
CSI 插件作者将提供他们自己的关于在 Kubernetes 上部署插件的说明。
如何使用 CSI 卷?
假设您的集群上已经部署了 CSI 存储插件,您可以通过熟悉的 Kubernetes 存储原语使用它:PersistentVolumeClaims、PersistentVolumes 和 StorageClasses。
CSI 是 Kubernetes v1.9 中的 Alpha 功能。要启用它,请设置以下标志
CSI is an alpha feature in Kubernetes v1.9. To enable it, set the following flags:
API server binary:
--feature-gates=CSIPersistentVolume=true
--runtime-config=storage.k8s.io/v1alpha1=true
API server binary and kubelet binaries:
--feature-gates=MountPropagation=true
--allow-privileged=true
动态供应
您可以通过创建一个指向 CSI 插件的 StorageClass,为支持动态供应的 CSI 存储插件启用卷的自动创建/删除。
例如,以下 StorageClass 使得名为“com.example.team/csi-driver”的 CSI 卷插件能够动态创建“fast-storage”卷。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: fast-storage
provisioner: com.example.team/csi-driver
parameters:
type: pd-ssd
要触发动态供应,请创建一个 PersistentVolumeClaim 对象。例如,以下 PersistentVolumeClaim 使用上述 StorageClass 触发动态供应。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-request-for-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: fast-storage
当调用卷供应时,参数“type: pd-ssd”通过“CreateVolume”调用传递给 CSI 插件“com.example.team/csi-driver”。作为响应,外部卷插件供应一个新卷,然后自动创建一个 PersistentVolume 对象来表示新卷。Kubernetes 随后将新的 PersistentVolume 对象绑定到 PersistentVolumeClaim,使其可供使用。
如果“fast-storage” StorageClass 被标记为 default,则无需在 PersistentVolumeClaim 中包含 storageClassName,它将默认使用。
预供应卷
您始终可以通过手动创建一个 PersistentVolume 对象来表示现有卷,从而在 Kubernetes 中暴露一个预先存在的卷。例如,以下 PersistentVolume 暴露了一个属于名为“com.example.team/csi-driver”的 CSI 存储插件的卷,其名称为“existingVolumeName”。
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-manually-created-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
csi:
driver: com.example.team/csi-driver
volumeHandle: existingVolumeName
readOnly: false
附加和挂载
您可以在任何 Pod 或 Pod 模板中引用绑定到 CSI 卷的 PersistentVolumeClaim。
kind: Pod
apiVersion: v1
metadata:
name: my-pod
spec:
containers:
- name: my-frontend
image: dockerfile/nginx
volumeMounts:
- mountPath: "/var/www/html"
name: my-csi-volume
volumes:
- name: my-csi-volume
persistentVolumeClaim:
claimName: my-request-for-storage
当引用 CSI 卷的 Pod 被调度时,Kubernetes 将针对外部 CSI 插件触发相应的操作(ControllerPublishVolume、NodePublishVolume 等),以确保指定的卷被附加、挂载,并可供 Pod 中的容器使用。
如何创建 CSI 驱动程序?
Kubernetes 对 CSI 卷驱动程序的打包和部署尽可能地少做强制规定。在 Kubernetes 上部署 CSI 卷驱动程序的最低要求记录在此处。
最低要求文档还包含一个章节,概述了在 Kubernetes 上部署任意容器化 CSI 驱动程序的建议机制。存储提供商可以使用此机制来简化容器化 CSI 兼容卷驱动程序在 Kubernetes 上的部署。
作为此推荐部署流程的一部分,Kubernetes 团队提供了以下 Sidecar(辅助)容器:
- 监控 Kubernetes VolumeAttachment 对象并触发针对 CSI 端点的 ControllerPublish 和 ControllerUnpublish 操作的 Sidecar 容器。
- 监控 Kubernetes PersistentVolumeClaim 对象并触发针对 CSI 端点的 CreateVolume 和 DeleteVolume 操作的 Sidecar 容器。
- 将 CSI 驱动程序注册到 kubelet(未来),并将驱动程序的自定义 NodeId(通过对 CSI 端点的 GetNodeID 调用获取)添加到 Kubernetes Node API 对象上的注解中的 Sidecar 容器。
存储供应商可以使用这些组件为其插件构建 Kubernetes 部署,同时让他们的 CSI 驱动程序完全无需感知 Kubernetes。
在哪里可以找到 CSI 驱动程序?
CSI 驱动程序由第三方开发和维护。您可以在此处找到示例 CSI 驱动程序,但这些仅用于说明目的,不应用于生产工作负载。
Flex 怎么样了?
海参Flex Volume 插件作为一种基于 exec 的机制存在,用于创建“树外”卷插件。尽管它有一些缺点(如上所述),但 Flex 卷插件与新的 CSI 卷插件共存。SIG Storage 将继续维护 Flex API,以便现有第三方 Flex 驱动程序(已部署在生产集群中)能够继续工作。未来,新的卷功能将仅添加到 CSI,而不是 Flex。
树内卷插件会怎么样?
一旦 CSI 达到稳定状态,我们计划将大多数树内卷插件迁移到 CSI。随着 Kubernetes CSI 实现趋于稳定,请继续关注更多详情。
Alpha 版本的限制有哪些?
CSI 的 Alpha 实现有以下限制:
- 不支持 CreateVolume、NodePublishVolume 和 ControllerPublishVolume 调用中的凭证字段。
- 不支持块存储卷;仅支持文件存储。
- 不支持指定文件系统,默认为 ext4。
- CSI 驱动程序必须与提供的“external-attacher”一起部署,即使它们没有实现“ControllerPublishVolume”。
- Kubernetes 调度器对 CSI 卷的拓扑感知尚不支持:简而言之,即共享关于卷供应位置(区域、地域等)的信息,以允许 k8s 调度器做出更智能的调度决策。
下一步是什么?
根据反馈和采用情况,Kubernetes 团队计划在 1.10 或 1.11 版本中将 CSI 实现推进到 Beta 阶段。
如何参与其中?
像所有 Kubernetes 项目一样,这个项目是众多来自不同背景的贡献者共同努力的成果。非常感谢 Vladimir Vivien (vladimirvivien)、Jan Šafránek (jsafrane)、Chakravarthy Nelluri (chakri-nelluri)、Bradley Childs (childsb)、Luis Pabón (lpabon) 和 Saad Ali (saad-ali) 在将 CSI 引入 Kubernetes 中付出的不懈努力。
如果您有兴趣参与 CSI 或 Kubernetes 存储系统的任何部分的设计和开发,请加入Kubernetes 存储特别兴趣小组 (SIG)。我们正在快速发展,随时欢迎新的贡献者。