Volume Scheduling
概述
DirectPV 为提供存储的 Pod 配置驱动器PersistentVolumeClaim对于 DirectPV 存储类。
DirectPV包含一个名为directpv-min-iowith卷绑定模式 WaitForFirstConsumer此模式延迟卷绑定和预配,直到PersistentVolume直到创建了一个Pod使用PersistentVolumeClaimDirectPV 随后选择或配置与 Pod 调度约束中指定的拓扑相匹配的 PersistentVolumes。
体积约束
Pod 可能包含对持久卷声明的额外约束。 DirectPV 会选择并配置符合 Pod 调度约束所指定拓扑结构的持久卷。
一些调度限制的例子包括:
- 资源需求,例如容量
- 节点选择器
- pod 亲和性与反亲和性
- 污点和容忍度
驱动器选择
以下序列和流程图展示了DirectPV CSI控制器如何选择合适的驱动器进行CreateVolumerequest.
-
验证请求中的文件系统类型是
xfsDirectPV 仅支持xfs文件系统。 -
验证请求中的任何访问层级。
-
检查请求的卷是否存在
DirectPVDriveCRD 对象。 如果存在,DirectPV 将调度包含该卷的第一个驱动器。 -
如果没有
DirectPVDriveCRD对象具有请求的卷容量,DirectPV通过以下方式检查每个驱动器:- 请求容量
- access-tier(如果请求了)
- 拓扑约束(如果请求)
-
如果此过程选择了多个驱动器,DirectPV会选择可用容量最大的驱动器。
-
如果多个驱动器具有相同的最大可用容量,DirectPV 会随机选择其中一个驱动器进行调度。
-
根据请求的卷信息更新计划驱动器。
请注意以下行为:
- 如果没有匹配的驱动器,DirectPV 将返回错误。
- 如果发生错误,Kubernetes 会重试该请求。
- 当两个或多个并行请求尝试调度同一驱动器时,该驱动器仅会成功响应其中一个请求,其余请求将失败并自动重试。

自定义驱动器选择
DirectPV 提供了多种控制驱动器选择的方法。 这些方法包括:
- 节点选择器
- pod 亲和性与反亲和性
- 污点和容忍度
除了这些方法,DirectPV 还可以使用驱动器标签使用自定义存储类选择特定驱动器进行卷调度。
-
标记所选驱动器标签驱动器命令。
# Label the 'nvme1n1' drive in all nodes as 'fast' with the 'tier' key. kubectl directpv label drives --drives=nvme1n1 tier=fast -
使用驱动器标签创建一个新的存储类create-storage-class.sh 脚本.
# Create new storage class 'fast-tier-storage' with drive labels 'directpv.min.io/tier: fast' create-storage-class.sh fast-tier-storage 'directpv.min.io/tier: fast' -
使用新创建的存储类卷配置.
$ kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sleep-pvc spec: volumeMode: Filesystem storageClassName: fast-tier-storage accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 8Mi EOF
Unique Drive selection
默认的基于可用容量的磁盘选择会导致在 StatefulSet 部署中为单个磁盘分配多个卷。 对于像 MinIO 对象存储这样的应用,这种选择缺乏性能和高可用性。
为了克服这种行为,DirectPV 提供了一种为每个驱动器分配一个卷的方法。
要使用此功能,请创建一个自定义存储类带有标签,格式如directpv.min.io/volume-claim-id.
以下是一个创建自定义存储类的示例:create-storage-class.sh 脚本:
create-storage-class.sh tenant-1-storage 'directpv.min.io/volume-claim-id: 555e99eb-e255-4407-83e3-fc443bf20f86'
这个自定义存储类必须在您的 StatefulSet 部署中使用。 以下是部署 MinIO 对象存储的示例:
kind: Service
apiVersion: v1
metadata:
name: minio
labels:
app: minio
spec:
selector:
app: minio
ports:
- name: minio
port: 9000
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
labels:
app: minio
spec:
serviceName: "minio"
replicas: 2
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
directpv.min.io/organization: minio
directpv.min.io/app: minio-example
directpv.min.io/tenant: tenant-1
spec:
containers:
- name: minio
image: minio/minio
env:
- name: MINIO_ACCESS_KEY
value: minio
- name: MINIO_SECRET_KEY
value: minio123
volumeMounts:
- name: minio-data-1
mountPath: /data1
- name: minio-data-2
mountPath: /data2
args:
- "server"
- "http://minio-{0...1}.minio.default.svc.cluster.local:9000/data{1...2}"
volumeClaimTemplates:
- metadata:
name: minio-data-1
spec:
storageClassName: tenant-1-storage
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 16Mi
- metadata:
name: minio-data-2
spec:
storageClassName: tenant-1-storage
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 16Mi