存储容量
存储容量是有限的,并且会因为运行 pod 的节点不同而变化:网络存储可能并非所有节点都能够访问,或者对于某个节点存储是本地的。
FEATURE STATE: Kubernetes v1.19 [alpha]
本页面描述了 Kubernetes 如何跟踪存储容量以及调度程序如何为了余下的尚未挂载的卷使用该信息将 Pod 调度到能够访问到足够存储容量的节点上。 如果没有跟踪存储容量,调度程序可能会选择一个没有足够容量来提供卷的节点,并且需要多次调度重试。
容器存储接口(CSI)驱动程序支持跟踪存储容量, 并且在安装 CSI 驱动程序时需要启用该功能。
API
这个特性有两个 API 扩展接口:
- CSIStorageCapacity 对象:这些对象由 CSI 驱动程序在安装驱动程序的命名空间中产生。每个对象都包含一个存储类的容量信息,并定义哪些节点可以访问该存储。
CSIDriverSpec.StorageCapacity
字段: 设置为 true 时,Kubernetes 调度程序将考虑使用 CSI 驱动程序的卷的存储容量。
调度
如果有以下情况,存储容量信息将会被 Kubernetes 调度程序使用:
CSIStorageCapacity
特性门控被设置为 true,- Pod 使用的卷还没有被创建,
- 卷使用引用了 CSI 驱动的 StorageClass, 并且使用了
WaitForFirstConsumer
卷绑定模式, - 驱动程序的
CSIDriver
对象的StorageCapacity
被设置为 true。
在这种情况下,调度程序仅考虑将 Pod 调度到有足够存储容量的节点上。这个检测非常简单, 仅将卷的大小与 CSIStorageCapacity
对象中列出的容量进行比较,并使用包含该节点的拓扑。
对于具有 Immediate
卷绑定模式的卷,存储驱动程序将决定在何处创建该卷,而不取决于将使用该卷的 Pod。 然后,调度程序将 Pod 调度到创建卷后可使用该卷的节点上。
对于 CSI 临时卷,调度总是在不考虑存储容量的情况下进行。 这是基于这样的假设:该卷类型仅由节点本地的特殊 CSI 驱动程序使用,并且不需要大量资源。
重新调度
当为带有 WaitForFirstConsumer
的卷的 Pod 来选择节点时,该决定仍然是暂定的。 下一步是要求 CSI 存储驱动程序创建卷,并提示该卷在被选择的节点上可用。
因为 Kubernetes 可能会根据已经过时的存储容量信息来选择一个节点,因此可能无法真正创建卷。 然后就会重置节点选择,Kubernetes 调度器会再次尝试为 Pod 查找节点。
限制
存储容量跟踪增加了调度器第一次尝试即成功的机会,但是并不能保证这一点,因为调度器必须根据可能过期的信息来进行决策。 通常,与没有任何存储容量信息的调度相同的重试机制可以处理调度失败。
当 Pod 使用多个卷时,调度可能会永久失败:一个卷可能已经在拓扑段中创建,而该卷又没有足够的容量来创建另一个卷, 要想从中恢复,必须要进行手动干预,比如通过增加存储容量或者删除已经创建的卷。 需要进一步工作来自动处理此问题。
开启存储容量跟踪
存储容量跟踪是一个 alpha 特性,只有当 CSIStorageCapacity
特性门控 和 storage.k8s.io/v1alpha1
API 组启用时才能启用。 更多详细信息,可以查看--feature-gates
和 --runtime-config
kube-apiserver 参数。
快速检查 Kubernetes 集群是否支持这个特性,可以通过下面命令列出 CSIStorageCapacity 对象:
kubectl get csistoragecapacities --all-namespaces
如果集群支持 CSIStorageCapacity,就会返回 CSIStorageCapacity 的对象列表或者:
No resources found
如果不支持,下面这个错误就会被打印出来:
error: the server doesn't have a resource type "csistoragecapacities"
除了在集群中启用该功能外,CSI 驱动程序还必须支持它。有关详细信息,请参阅驱动程序的文档。
接下来
- 想要获得更多该设计的信息,查看 Storage Capacity Constraints for Pod Scheduling KEP。
- 有关此功能的进一步开发信息,查看enhancement tracking issue #1472。
- 学习 Kubernetes 调度器。