一、存储容量
Kubernetes 存储容量通常是有限的,并且在集群中的不同节点上可能存在差异,主要取决于存储供应器和集群的配置。对于网络存储,可能并非所有节点都能够直接访问它,取决于存储供应商的设置和网络拓扑。某些存储可能只在特定的节点上提供服务,而其他节点则无法访问该存储。因此,在使用网络存储时,需要确保Pod调度到能够访问所需存储的节点上。
Kubernetes提供了一种机制来跟踪存储容量,并确保将Pod调度到具有足够存储容量的节点上,可以避免在没有足够容量的节点上重复进行调度尝试。如果没有足够存储容量的PV可用,调度程序将暂时阻塞Pod的调度,并定期重新尝试调度,直到有足够的存储容量为止。这样可以确保Pod只被调度到具有所需存储容量的节点上,避免不必要的调度失败。
二、前提条件
Kubernetes v1.28引入了集群级API对存储容量跟踪的支持。要使用这个功能,您还需要使用支持容量跟踪的CSI(Container Storage Interface)驱动程序。CSI是一种标准化的接口,允许存储供应商为Kubernetes提供持久化存储解决方案。CSI驱动程序通过实现CSI规范,与Kubernetes集成,并提供存储功能,包括容量跟踪。
三、API
这个特性有两个 API 扩展接口:
1、CSIStorageCapacity 对象:这些对象由 CSI 驱动程序在安装驱动程序的命名空间中产生。 每个对象都包含一个存储类的容量信息,并定义哪些节点可以访问该存储。
2、CSIDriverSpec.StorageCapacity 字段: 设置为 true 时,Kubernetes 调度程序将考虑使用 CSI 驱动程序的卷的存储容量。
四、调度
如果有以下情况,存储容量信息将会被 Kubernetes 调度程序使用:
1、Pod 使用的卷还没有被创建。
2、卷使用引用了 CSI 驱动的 StorageClass, 并且使用了 WaitForFirstConsumer 卷绑定模式。
3、驱动程序的 CSIDriver 对象的 StorageCapacity 被设置为 true。
当调度程序尝试将Pod调度到节点上时,它会检查该节点是否拥有足够的存储容量来挂载Pod所需的PV。这个检测非常简单,只需要将PV的大小与CSIStorageCapacity对象中列出的容量进行比较,并使用包含该节点的拓扑。
- 对于具有 Immediate 卷绑定模式的卷,存储驱动程序将决定在何处创建该卷,而不取决于将使用该卷的 Pod。 然后,调度程序将 Pod 调度到创建卷后可使用该卷的节点上。
- 对于CSI临时卷,调度总是不考虑存储容量的情况下进行。这是因为CSI临时卷通常由节点本地的特殊CSI驱动程序使用,并且不需要大量的存储资源。
五、重新调度
当为带有WaitForFirstConsumer的卷的Pod选择节点时,这个决定是暂定的。在这种情况下,调度程序会选择一个节点,并要求CSI存储驱动程序在该节点上创建卷,并将卷标记为待使用状态。
由于Kubernetes可能会根据过时的存储容量信息选择节点,这可能导致卷无法真正创建。如果发生这种情况,Kubernetes调度器会重置节点选择,并再次尝试为Pod查找可用的节点。
六、限制
存储容量跟踪确实可以增加调度器第一次尝试即成功的机会。但是,它并不能保证这一点,因为调度器必须根据可能过期的信息来进行决策。因此,与没有任何存储容量信息的调度相同的重试机制可以处理调度失败。
当Pod使用多个卷时,调度可能会永久失败。例如,如果一个卷已经在拓扑段中创建,而该卷又没有足够的容量来创建另一个卷,则调度器将无法成功调度Pod。在这种情况下,需要手动干预以恢复调度过程。可能的解决方案包括增加存储容量或删除已经创建的卷,以便为Pod提供足够的可用空间。