存储类

本文档介绍了 Kubernetes 中 StorageClass 的概念。建议先熟悉持久卷

StorageClass 为管理员提供了一种描述其提供的存储“类别”的方法。不同的类别可能映射到服务质量级别、备份策略或由集群管理员确定的任意策略。Kubernetes 本身对类别代表什么没有意见。

Kubernetes 中存储类别的概念类似于某些其他存储系统设计中的“配置文件”。

StorageClass 对象

每个 StorageClass 都包含字段 provisionerparametersreclaimPolicy,这些字段在需要动态配置属于该类的持久卷以满足持久卷声明 (PVC) 时使用。

StorageClass 对象的名称很重要,用户可以通过该名称请求特定的类别。管理员在首次创建 StorageClass 对象时设置类别的名称和其他参数。

作为管理员,您可以指定一个默认的 StorageClass,该 StorageClass 适用于任何未请求特定类别的 PVC。有关更多详细信息,请参阅持久卷声明概念

以下是 StorageClass 的示例

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: low-latency
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: csi-driver.example-vendor.example
reclaimPolicy: Retain # default value is Delete
allowVolumeExpansion: true
mountOptions:
  - discard # this might enable UNMAP / TRIM at the block storage layer
volumeBindingMode: WaitForFirstConsumer
parameters:
  guaranteedReadWriteLatency: "true" # provider-specific

默认 StorageClass

您可以将 StorageClass 标记为集群的默认 StorageClass。有关设置默认 StorageClass 的说明,请参阅更改默认 StorageClass

当 PVC 未指定 storageClassName 时,将使用默认的 StorageClass。

如果您在集群中的多个 StorageClass 上将storageclass.kubernetes.io/is-default-class 注释设置为 true,然后创建一个未设置 storageClassName 的持久卷声明,则 Kubernetes 将使用最近创建的默认 StorageClass。

您可以创建一个持久卷声明,而无需为新的 PVC 指定 storageClassName,即使您的集群中不存在默认的 StorageClass,您也可以这样做。在这种情况下,新的 PVC 将按您定义的方式创建,并且该 PVC 的 storageClassName 将保持未设置状态,直到默认 StorageClass 可用。

您可以拥有一个没有任何默认 StorageClass 的集群。如果您没有将任何 StorageClass 标记为默认(并且没有由例如云提供商为您设置),则 Kubernetes 无法对需要它的持久卷声明应用该默认设置。

如果或当默认 StorageClass 可用时,控制平面将识别任何没有 storageClassName 的现有 PVC。对于 storageClassName 值为空或没有此键的 PVC,控制平面随后会更新这些 PVC,以将 storageClassName 设置为与新的默认 StorageClass 匹配。如果您有一个现有的 PVC,其中 storageClassName"",并且您配置了一个默认的 StorageClass,则不会更新此 PVC。

为了保持绑定到 storageClassName 设置为 "" 的 PV(当存在默认 StorageClass 时),您需要将关联 PVC 的 storageClassName 设置为 ""

配置器

每个 StorageClass 都有一个配置器,用于确定用于配置 PV 的卷插件。必须指定此字段。

卷插件内部配置器配置示例
AzureFileAzure 文件
CephFS--
FC--
FlexVolume--
iSCSI--
本地-本地
NFS-NFS
PortworxVolumePortworx 卷
RBD-Ceph RBD
VsphereVolumevSphere

您不限于指定此处列出的“内部”配置器(其名称以“kubernetes.io”开头并随 Kubernetes 一起提供)。您还可以运行和指定外部配置器,它们是遵循 Kubernetes 定义的规范的独立程序。外部配置器的作者可以完全决定其代码所在的位置、配置器的交付方式、运行方式、使用的卷插件(包括 Flex)等。存储库kubernetes-sigs/sig-storage-lib-external-provisioner包含一个用于编写外部配置器的库,该库实现了规范的大部分内容。一些外部配置器列在存储库kubernetes-sigs/sig-storage-lib-external-provisioner下。

例如,NFS 不提供内部配置器,但可以使用外部配置器。在某些情况下,第三方存储供应商也会提供自己的外部配置器。

回收策略

由 StorageClass 动态创建的持久卷将具有类别 reclaimPolicy 字段中指定的回收策略,可以是 DeleteRetain。如果在创建 StorageClass 对象时未指定 reclaimPolicy,则默认为 Delete

手动创建并通过 StorageClass 管理的持久卷将具有在创建时分配给它们的任何回收策略。

卷扩展

可以将持久卷配置为可扩展的。这允许您通过编辑相应的 PVC 对象并请求新的更大存储量来调整卷的大小。

当底层 StorageClass 的 allowVolumeExpansion 字段设置为 true 时,以下类型的卷支持卷扩展。

卷类型表及其所需的 Kubernetes 版本
卷类型卷扩展所需的 Kubernetes 版本
Azure 文件1.11
CSI1.24
FlexVolume1.13
Portworx1.11
rbd1.11

挂载选项

由 StorageClass 动态创建的持久卷将具有类别 mountOptions 字段中指定的挂载选项。

如果卷插件不支持挂载选项但指定了挂载选项,则配置将失败。不会在类别或 PV 上验证挂载选项。如果挂载选项无效,则 PV 挂载失败。

卷绑定模式

volumeBindingMode 字段控制何时应进行卷绑定和动态配置。如果未设置,则默认使用 Immediate 模式。

Immediate 模式表示卷绑定和动态配置在创建持久卷声明后立即发生。对于受拓扑约束且无法从集群中的所有节点全局访问的存储后端,将在不知道 Pod 的调度要求的情况下绑定或配置持久卷。这可能会导致 Pod 无法调度。

集群管理员可以通过指定 WaitForFirstConsumer 模式来解决此问题,该模式将延迟持久卷的绑定和配置,直到创建使用持久卷声明的 Pod。将根据 Pod 的调度约束指定的拓扑选择或配置持久卷。这些约束包括但不限于资源需求节点选择器Pod 亲和性和反亲和性以及污点和容忍度

以下插件支持使用动态配置的 WaitForFirstConsumer

  • CSI 卷,前提是特定的 CSI 驱动程序支持此功能

以下插件支持使用预先创建的持久卷绑定的 WaitForFirstConsumer

  • CSI 卷,前提是特定的 CSI 驱动程序支持此功能
  • 本地
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  nodeSelector:
    kubernetes.io/hostname: kube-01
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage

允许的拓扑

当集群操作员指定 WaitForFirstConsumer 卷绑定模式时,在大多数情况下不再需要将配置限制为特定的拓扑。但是,如果仍然需要,可以指定 allowedTopologies

此示例演示了如何将已配置卷的拓扑限制为特定区域,并且应该用作受支持插件的 zonezones 参数的替代品。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/example
parameters:
  type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
  - key: topology.kubernetes.io/zone
    values:
    - us-central-1a
    - us-central-1b

参数

StorageClass 具有描述属于存储类别的卷的参数。根据 provisioner,可以接受不同的参数。如果省略参数,则使用某些默认值。

一个 StorageClass 最多可以定义 512 个参数。参数对象的总长度(包括其键和值)不能超过 256 KiB。

AWS EBS

Kubernetes 1.30 不包含 awsElasticBlockStore 卷类型。

AWSElasticBlockStore 内置存储驱动程序在 Kubernetes v1.19 版本中已弃用,并在 v1.27 版本中完全删除。

Kubernetes 项目建议您改用AWS EBS外部存储驱动程序。

以下是 AWS EBS CSI 驱动程序的示例 StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  csi.storage.k8s.io/fstype: xfs
  type: io1
  iopsPerGB: "50"
  encrypted: "true"
allowedTopologies:
- matchLabelExpressions:
  - key: topology.ebs.csi.aws.com/zone
    values:
    - us-east-2c

NFS

要配置 NFS 存储,您可以使用内置驱动程序或适用于 Kubernetes 的 NFS CSI 驱动程序(推荐)。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: example-nfs
provisioner: example.com/external-nfs
parameters:
  server: nfs-server.example.com
  path: /share
  readOnly: "false"
  • server:服务器是 NFS 服务器的主机名或 IP 地址。
  • path:NFS 服务器导出的路径。
  • readOnly:一个标志,指示存储是否将以只读方式挂载(默认为 false)。

Kubernetes 不包含内部 NFS 配置器。您需要使用外部配置器为 NFS 创建 StorageClass。以下是一些示例

vSphere

vSphere 存储类别有两种类型的配置器

树内供应程序已弃用。有关 CSI 供应程序的更多信息,请参阅Kubernetes vSphere CSI 驱动程序vSphereVolume CSI 迁移

CSI 供应程序

vSphere CSI StorageClass 供应程序可与 Tanzu Kubernetes 集群配合使用。有关示例,请参阅vSphere CSI 代码库

vCP 供应程序

以下示例使用 VMware Cloud Provider (vCP) StorageClass 供应程序。

  1. 使用用户指定的磁盘格式创建 StorageClass。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast
    provisioner: kubernetes.io/vsphere-volume
    parameters:
      diskformat: zeroedthick
    

    diskformatthinzeroedthickeagerzeroedthick。默认值:"thin"

  2. 在用户指定的数据存储上使用磁盘格式创建 StorageClass。

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast
    provisioner: kubernetes.io/vsphere-volume
    parameters:
      diskformat: zeroedthick
      datastore: VSANDatastore
    

    datastore:用户还可以在 StorageClass 中指定数据存储。卷将在 StorageClass 中指定的数据存储上创建,在本例中为 VSANDatastore。此字段是可选的。如果未指定数据存储,则将在用于初始化 vSphere Cloud Provider 的 vSphere 配置文件中指定的数据存储上创建卷。

  3. Kubernetes 内的存储策略管理

    • 使用现有的 vCenter SPBM 策略

      vSphere 用于存储管理的最重要功能之一是基于策略的管理。基于存储策略的管理 (SPBM) 是一个存储策略框架,可在广泛的数据服务和存储解决方案中提供单一统一的控制平面。SPBM 使 vSphere 管理员能够克服前期存储配置挑战,例如容量规划、差异化服务级别和管理容量余量。

      可以使用 storagePolicyName 参数在 StorageClass 中指定 SPBM 策略。

    • Kubernetes 内的 Virtual SAN 策略支持

      vSphere Infrastructure (VI) 管理员将能够在动态卷配置期间指定自定义 Virtual SAN 存储功能。现在,您可以在动态卷配置期间以存储功能的形式定义存储要求,例如性能和可用性。存储功能要求将转换为 Virtual SAN 策略,然后在创建持久卷(虚拟磁盘)时向下推送到 Virtual SAN 层。虚拟磁盘分布在 Virtual SAN 数据存储中以满足要求。

      您可以查看基于存储策略的卷动态配置管理,以详细了解如何将存储策略用于持久卷管理。

您可以尝试一些vSphere 示例,以了解 Kubernetes for vSphere 中的持久卷管理。

Ceph RBD(已弃用)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/rbd
parameters:
  monitors: 10.16.153.105:6789
  adminId: kube
  adminSecretName: ceph-secret
  adminSecretNamespace: kube-system
  pool: kube
  userId: kube
  userSecretName: ceph-secret-user
  userSecretNamespace: default
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"
  • monitors:Ceph 监视器,以逗号分隔。此参数是必需的。

  • adminId:能够在池中创建映像的 Ceph 客户端 ID。默认值为“admin”。

  • adminSecretNameadminId 的密钥名称。此参数是必需的。提供的密钥必须具有“kubernetes.io/rbd”类型。

  • adminSecretNamespaceadminSecretName 的命名空间。默认值为“default”。

  • pool:Ceph RBD 池。默认值为“rbd”。

  • userId:用于映射 RBD 映像的 Ceph 客户端 ID。默认值与 adminId 相同。

  • userSecretName:用于映射 RBD 映像的 userId 的 Ceph 密钥名称。它必须与 PVC 位于同一命名空间中。此参数是必需的。提供的密钥必须具有“kubernetes.io/rbd”类型,例如以这种方式创建

    kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
      --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \
      --namespace=kube-system
    
  • userSecretNamespaceuserSecretName 的命名空间。

  • fsType:kubernetes 支持的 fsType。默认值:"ext4"

  • imageFormat:Ceph RBD 映像格式,“1”或“2”。默认值为“2”。

  • imageFeatures:此参数是可选的,仅当您将 imageFormat 设置为“2”时才应使用。当前支持的功能只有 layering。默认值为“”,并且没有启用任何功能。

Azure 磁盘

Kubernetes 1.30 不包含 azureDisk 卷类型。

azureDisk 树内存储驱动程序在 Kubernetes v1.19 版本中已弃用,然后在 v1.27 版本中完全删除。

Kubernetes 项目建议您改用Azure 磁盘第三方存储驱动程序。

Azure 文件(已弃用)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
  skuName: Standard_LRS
  location: eastus
  storageAccount: azure_storage_account_name
  • skuName:Azure 存储帐户 SKU 层。默认值为空。
  • location:Azure 存储帐户位置。默认值为空。
  • storageAccount:Azure 存储帐户名称。默认值为空。如果未提供存储帐户,则会搜索与资源组关联的所有存储帐户,以找到与 skuNamelocation 匹配的帐户。如果提供了存储帐户,则它必须与集群位于同一资源组中,并且 skuNamelocation 将被忽略。
  • secretNamespace:包含 Azure 存储帐户名称和密钥的密钥的命名空间。默认值与 Pod 相同。
  • secretName:包含 Azure 存储帐户名称和密钥的密钥的名称。默认值为 azure-storage-account-<accountName>-secret
  • readOnly:一个标志,指示存储是否将挂载为只读。默认为 false,表示读/写挂载。此设置也会影响 VolumeMounts 中的 ReadOnly 设置。

在存储配置期间,将为挂载凭据创建名为 secretName 的密钥。如果集群同时启用了RBAC控制器角色,请为集群角色 system:controller:persistent-volume-binder 添加资源 secretcreate 权限。

在多租户环境中,强烈建议显式设置 secretNamespace 的值,否则存储帐户凭据可能会被其他用户读取。

Portworx 卷(已弃用)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume
parameters:
  repl: "1"
  snap_interval: "70"
  priority_io: "high"
  • fs:要布局的文件系统:none/xfs/ext4(默认值:ext4)。
  • block_size:块大小,以 KB 为单位(默认值:32)。
  • repl:要以复制因子 1..3 的形式提供的同步副本数(默认值:1)此处应使用字符串,即 "1" 而不是 1
  • priority_io:确定是从高性能存储还是从低优先级存储创建卷 high/medium/low(默认值:low)。
  • snap_interval:以分钟为单位的时钟/时间间隔,用于触发快照。快照是基于与先前快照的差异进行增量备份的,0 表示禁用快照(默认值:0)。此处应使用字符串,即 "70" 而不是 70
  • aggregation_level:指定卷将分布到的块数,0 表示非聚合卷(默认值:0)。此处应使用字符串,即 "0" 而不是 0
  • ephemeral:指定在卸载后是否应清理卷或应保留卷。emptyDir 用例可以将此值设置为 true,而 persistent volumes 用例(例如用于 Cassandra 等数据库)应设置为 false,true/false(默认值 false)。此处应使用字符串,即 "true" 而不是 true

本地

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

本地卷在 Kubernetes 1.30 中不支持动态配置;但是,仍然应该创建 StorageClass 以延迟卷绑定,直到 Pod 实际调度到适当的节点。这是由 WaitForFirstConsumer 卷绑定模式指定的。

延迟卷绑定允许调度程序在为 PersistentVolumeClaim 选择适当的 PersistentVolume 时考虑 Pod 的所有调度约束。

上次修改时间:2024 年 6 月 24 日下午 1:39 PST:更新了默认存储类中的错误链接 (0f25d68a3f)