本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
为 Kubernetes 引入容器存储接口(CSI)Alpha
Kubernetes 的一个关键区别因素是其强大的卷插件系统,该系统支持多种不同类型的存储系统来
- 在需要时自动创建存储。
- 在任何调度容器的地方提供存储。
- 在不再需要时自动删除存储。然而,为 Kubernetes 添加对新存储系统的支持一直是一个挑战。
Kubernetes 1.9 引入了容器存储接口(CSI)的 Alpha 版实现,使得安装新卷插件像部署一个 Pod 一样简单。它还允许第三方存储提供商开发解决方案,而无需添加到 Kubernetes 核心代码库。
由于该功能在 1.9 版本中处于 Alpha 阶段,因此必须明确启用。Alpha 功能不建议用于生产环境,但它们很好地表明了项目的发展方向(在本例中,是朝着更具可扩展性和基于标准的 Kubernetes 存储生态系统发展)。
为什么选择 Kubernetes CSI?
Kubernetes 卷插件目前是“in-tree”的,这意味着它们与 Kubernetes 核心二进制文件链接、编译、构建和一起发布。要为 Kubernetes 添加对新存储系统的支持(即卷插件),需要将代码提交到 Kubernetes 核心仓库。但与 Kubernetes 发布流程保持一致对许多插件开发者来说很痛苦。
现有的 Flex Volume 插件试图通过为外部卷插件公开基于 exec 的 API 来解决这一痛点。尽管它允许第三方存储供应商在树外编写驱动,但要部署第三方驱动文件,它需要访问节点和主机的根文件系统。
除了部署困难之外,Flex 还没有解决插件依赖性的痛点:卷插件往往有许多外部要求(例如,对挂载和文件系统工具的需求)。这些依赖项被假定在底层主机操作系统上可用,但情况往往并非如此(安装它们需要访问节点机器的根文件系统)。
CSI 通过允许存储插件在树外开发、容器化、通过标准 Kubernetes 原语部署,并通过用户熟悉和喜爱的 Kubernetes 存储原语(PersistentVolumeClaims、PersistentVolumes、StorageClasses)来使用,解决了所有这些问题。
什么是 CSI?
CSI 的目标是建立一个标准化机制,让容器编排系统(COs)能够向其容器化工作负载公开任意存储系统。CSI 规范是 Kubernetes、Mesos、Docker 和 Cloud Foundry 等各种容器编排系统(COs)社区成员合作的产物。该规范独立于 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 被标记为默认,则无需在 PersistentVolumeClaim 中包含 storageClassName,它将默认使用。
预先配置的卷
您始终可以通过手动创建 PersistentVolume 对象来表示现有卷,从而在 Kubernetes 中公开预先存在的卷。例如,以下 PersistentVolume 公开了一个名为“existingVolumeName”的卷,该卷属于名为“com.example.team/csi-driver”的 CSI 存储插件。
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 驱动程序的建议机制。存储提供商可以使用此机制来简化在 Kubernetes 上部署容器化 CSI 兼容卷驱动程序。
作为此推荐部署流程的一部分,Kubernetes 团队提供了以下边车(helper)容器:
- 监控 Kubernetes VolumeAttachment 对象并触发针对 CSI 端点的 ControllerPublish 和 ControllerUnpublish 操作的边车容器。
- 监控 Kubernetes PersistentVolumeClaim 对象并触发针对 CSI 端点的 CreateVolume 和 DeleteVolume 操作的边车容器。
- Sidecar 容器,用于向 kubelet 注册 CSI 驱动程序(将来),并将驱动程序的自定义 NodeId(通过对 CSI 端点执行 GetNodeID 调用获取)添加到 Kubernetes Node API 对象的注解中
存储供应商可以使用这些组件为其插件构建 Kubernetes 部署,同时使其 CSI 驱动程序完全不了解 Kubernetes。
在哪里可以找到 CSI 驱动程序?
CSI 驱动程序由第三方开发和维护。您可以在此处找到示例 CSI 驱动程序,但这些仅用于说明目的,不适用于生产工作负载。
Flex 怎么样?
Flex Volume 插件作为一种基于 exec 的机制,用于创建“out-of-tree”卷插件。尽管它有一些缺点(如上所述),但 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)。我们正在迅速发展,并始终欢迎新的贡献者。