概念

Edit This Page

Storage Classes

本文描述了 Kubernetes 中 StorageClass 的概念。建议先熟悉 持久卷 的概念。

介绍

StorageClass 为管理员提供了描述存储 "类" 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由群集管理员制定的任意策略。 Kubernetes 本身并不清楚各种代表的什么。这个的概念在其他存储系统中有时被称为”配置文件”。

StorageClass 资源

每个 StorageClass 都包含 provisionerparametersreclaimPolicy 字段, 这些字段会在StorageClass需要动态分配 PersistentVolume 时会使用到。

StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。

管理员可以为没有申请绑定到特定 StorageClass 的 PVC 指定一个默认的 : 更多详情请参阅 PersistentVolumeClaim 章节

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
mountOptions:
  - debug
volumeBindingMode: Immediate

存储分配器

StorageClass 有一个分配器,用来决定使用哪个卷插件分配持久化卷申领。该字段必须指定。

卷插件 提供厂商 配置例子
AWSElasticBlockStore AWS EBS
AzureFile Azure File
AzureDisk Azure Disk
CephFS - -
Cinder OpenStack Cinder
FC - -
Flexvolume - -
Flocker -
GCEPersistentDisk GCE PD
Glusterfs Glusterfs
iSCSI - -
Quobyte Quobyte
NFS - -
RBD Ceph RBD
VsphereVolume vSphere
PortworxVolume Portworx Volume
ScaleIO ScaleIO
StorageOS StorageOS
Local - Local

您不限于指定此处列出的”内置”分配器(其名称前缀为 kubernetes.io 并打包在 Kubernetes 中)。 您还可以运行和指定外部分配器,这些独立的程序遵循由 Kubernetes 定义的 规范。 外部供应商的作者完全可以自由决定他们的代码保存于何处、打包方式、运行方式、使用的插件(包括 Flex)等。 代码仓库 kubernetes-incubator/external-storage 包含一个用于为外部分配器编写功能实现的类库,以及各种社区维护的外部分配器。

例如,NFS 没有内部分配器,但可以使用外部分配器。一些外部分配器在代码仓库 kubernetes-incubator/external-storage 中。 也有第三方存储供应商提供自己的外部分配器。

回收策略

StorageClass 动态创建的持久化卷会在的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy ,它将默认为 Delete

通过 StorageClass 手动创建并管理的 Persistent Volume 会使用它们被创建时指定的回收政策。

挂载选项

StorageClass 动态创建的 Persistent Volume 将使用mountOption 字段指定的挂载选项。

如果卷插件不支持挂载选项,却指定了该选项,则分配操作会失败。 挂载选项在 StorageClass 和持久卷上都不会做验证,所以如果挂载选项无效,那么这个 PV 就会失败。

卷绑定模式

FEATURE STATE: Kubernetes v1.12 beta
该功能目前处于 beta 状态,意味着:

  • 版本名称包含 beta (例如 v2beta3)。
  • 代码经过了充分测试,启用该功能被认为是安全的。默认情况下被启用。
  • 对整体功能的支持在未来不会被移除,尽管细节上可能会做更改。
  • 在后续的 beta 或稳定版本中,对象的模式、语义可能以不兼容的方式发生变化。当这种情况发生时,我们将提供迁移到下一个版本的说明。这可能需要删除、编辑和重建 API 对象,编辑过程可能需要一些思考。这可能导致依赖该功能的应用程序停机一段时间。
  • 建议仅在非业务关键场景使用该功能,因为在后续版本中可能会发生不兼容的更改。如果您有多个可以独立升级的集群,那么您可能可以放松这个限制。
  • 请尝试使用我们的 beta 版功能,并给出反馈!在它们退出 beta 测试阶段之后,我们将很难去做更多的更改。

注意: 这个功能特性需要启用 VolumeScheduling 参数才能使用。

volumeBindingMode 字段控制了 卷绑定和动态分配 应该发生在什么时候。

默认情况下,Immediate 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态分配。 对于由于拓扑限制而非集群所有节点可达的存储后端,PersistentVolume 会在不知道 Pod 调度要求的情况下绑定或者分配。

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

以下插件支持动态分配的 WaitForFirstConsumer 模式:

以下插件支持预创建绑定 PersistentVolume 的 WaitForFirstConsumer 模式:

允许的拓扑结构

FEATURE STATE: Kubernetes v1.12 beta
该功能目前处于 beta 状态,意味着:

  • 版本名称包含 beta (例如 v2beta3)。
  • 代码经过了充分测试,启用该功能被认为是安全的。默认情况下被启用。
  • 对整体功能的支持在未来不会被移除,尽管细节上可能会做更改。
  • 在后续的 beta 或稳定版本中,对象的模式、语义可能以不兼容的方式发生变化。当这种情况发生时,我们将提供迁移到下一个版本的说明。这可能需要删除、编辑和重建 API 对象,编辑过程可能需要一些思考。这可能导致依赖该功能的应用程序停机一段时间。
  • 建议仅在非业务关键场景使用该功能,因为在后续版本中可能会发生不兼容的更改。如果您有多个可以独立升级的集群,那么您可能可以放松这个限制。
  • 请尝试使用我们的 beta 版功能,并给出反馈!在它们退出 beta 测试阶段之后,我们将很难去做更多的更改。

注意: 这个特性需要开启 VolumeScheduling 特性开关。

当集群操作人员使用了 WaitForFirstConsumer 的卷绑定模式,在大部分情况下就没有必要将配置限制为特定的拓扑结构。 然而,如果还有需要的话,可以使用 allowedTopologies

这个例子描述了如何将分配卷限的拓扑限制在特定的区域,在使用时应该根据插件支持情况替换 zonezones 参数。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: standard
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
  - key: failure-domain.beta.kubernetes.io/zone
    values:
    - us-central1-a
    - us-central1-b

参数

Storage class 具有描述属于卷的参数。取决于分配器,可以接受不同的参数。 例如,参数 type 的值 io1 和参数 iopsPerGB 特定于 EBS PV。当参数被省略时,会使用默认值。

AWS EBS

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "10"
  fsType: ext4

GCE PD

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  replication-type: none

如果 replication-type 设置为 none,会分配一个常规(当前区域内的)持久化磁盘。

如果 replication-type 设置为 regional-pd,会分配一个 区域性持久化磁盘(Regional Persistent Disk)。在这种情况下,用户必须使用 zones 而非 zone 来指定期望的复制区域(zone)。如果指定来两个特定的区域,区域性持久化磁盘会在这两个区域里分配。如果指定了多于两个的区域,Kubernetes 会选择其中任意两个区域。如果省略了 zones 参数,Kubernetes 会在集群管理的区域中任意选择。

注意: zonezones 已被弃用并被 allowedTopologies 取代。

Glusterfs

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/glusterfs
parameters:
  resturl: "http://127.0.0.1:8081"
  clusterid: "630372ccdc720a92c681fb928f27b53f"
  restauthenabled: "true"
  restuser: "admin"
  secretNamespace: "default"
  secretName: "heketi-secret"
  gidMin: "40000"
  gidMax: "50000"
  volumetype: "replicate:3"

OpenStack Cinder

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: gold
provisioner: kubernetes.io/cinder
parameters:
  availability: nova
Note:
FEATURE STATE: Kubernetes 1.11 废弃
该功能已被*弃用*。有关此状态的更多信息,请参见Kubernetes 弃用策略

OpenStack 的内部驱动程序已经被弃用。请使用 OpenStack 的外部驱动程序

vSphere

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

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: fast
    provisioner: kubernetes.io/vsphere-volume
    parameters:
      diskformat: zeroedthick
`diskformat`: `thin`, `zeroedthick` 和 `eagerzeroedthick`。默认值: `"thin"`。
  1. 在用户指定的数据存储上创建磁盘格式的 StorageClass。

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: fast
    provisioner: kubernetes.io/vsphere-volume
    parameters:
        diskformat: zeroedthick
        datastore: VSANDatastore
`datastore`:用户也可以在 StorageClass 中指定数据存储。卷将在 storage class 中指定的数据存储上创建,在这种情况下是 `VSANDatastore`。该字段是可选的。如果未指定数据存储,则将在用于初始化 vSphere Cloud Provider 的 vSphere 配置文件中指定的数据存储上创建该卷。
  1. Kubernetes 中的存储策略管理
* 使用现有的 vCenter SPBM 策略

    vSphere 用于存储管理的最重要特性之一是基于策略的管理。基于存储策略的管理(SPBM)是一个存储策略框架,提供单一的统一控制平面的跨越广泛的数据服务和存储解决方案。 SPBM 使能 vSphere 管理员克服先期的存储配置挑战,如容量规划,差异化服务等级和管理容量空间。

    SPBM 策略可以在 StorageClass 中使用 `storagePolicyName` 参数声明。
* Kubernetes 内的 Virtual SAN 策略支持

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

    更多有关 persistent volume 管理的存储策略的详细信息,
    您可以参考 [基于存储策略的动态分配卷管理](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/policy-based-mgmt.html)。

有几个 vSphere 例子 供您在 Kubernetes for vSphere 中尝试进行 persistent volume 管理。

Ceph RBD

kind: StorageClass
apiVersion: storage.k8s.io/v1
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"

–> * userSecretName:用于映射 RBD 镜像的 userId 的 Ceph Secret 的名字。 它必须与 PVC 存在于相同的 namespace 中。该参数是必需的。 提供的 secret 必须具有值为 “kubernetes.io/rbd” 的 type 参数,例如以这样的方式创建:

```shell
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
  --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \
  --namespace=kube-system
```

Quobyte

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: slow
provisioner: kubernetes.io/quobyte
parameters:
    quobyteAPIServer: "http://138.68.74.142:7860"
    registry: "138.68.74.142:7861"
    adminSecretName: "quobyte-admin-secret"
    adminSecretNamespace: "kube-system"
    user: "root"
    group: "root"
    quobyteConfig: "BASE"
    quobyteTenant: "DEFAULT"

–> * adminSecretName:保存关于 Quobyte 用户和密码的 secret,用于对 API 服务器进行身份验证。 提供的 secret 必须有值为 “kubernetes.io/quobyte” 的 type 参数,例如以这种方式创建:

```shell
kubectl create secret generic quobyte-admin-secret \
  --type="kubernetes.io/quobyte" --from-literal=key='opensesame' \
  --namespace=kube-system
```

Azure 磁盘

Azure Unmanaged Disk Storage Class(非托管磁盘存储类)

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/azure-disk
parameters:
  skuName: Standard_LRS
  location: eastus
  storageAccount: azure_storage_account_name

新的 Azure 磁盘 Storage Class(从 v1.7.2 开始)

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/azure-disk
parameters:
  storageaccounttype: Standard_LRS
  kind: Shared

Azure 文件

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
  skuName: Standard_LRS
  location: eastus
  storageAccount: azure_storage_account_name

在分配期间,为挂载凭证创建一个 secret。如果集群同时启用了 RBACController Roles, 为 system:controller:persistent-volume-binder 的 clusterrole 添加 secret 资源的 create 权限。

Portworx 卷

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume
parameters:
  repl: "1"
  snap_interval:   "70"
  io_priority:  "high"

ScaleIO

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/scaleio
parameters:
  gateway: https://192.168.99.200:443/api
  system: scaleio
  protectionDomain: pd0
  storagePool: sp1
  storageMode: ThinProvisioned
  secretRef: sio-secret
  readOnly: false
  fsType: xfs

ScaleIO Kubernetes 卷插件需要配置一个 Secret 对象。 secret 必须用 kubernetes.io/scaleio 类型创建,并与引用它的 PVC 所属的名称空间使用相同的值 如下面的命令所示:

kubectl create secret generic sio-secret --type="kubernetes.io/scaleio" \
--from-literal=username=sioadmin --from-literal=password=d2NABDNjMA== \
--namespace=default

StorageOS

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast
provisioner: kubernetes.io/storageos
parameters:
  pool: default
  description: Kubernetes volume
  fsType: ext4
  adminSecretNamespace: default
  adminSecretName: storageos-secret

StorageOS Kubernetes 卷插件可以使 Secret 对象来指定用于访问 StorageOS API 的端点和凭据。 只有当默认值已被更改时,这才是必须的。 secret 必须使用 kubernetes.io/storageos 类型创建,如以下命令:

kubectl create secret generic storageos-secret \
--type="kubernetes.io/storageos" \
--from-literal=apiAddress=tcp://localhost:5705 \
--from-literal=apiUsername=storageos \
--from-literal=apiPassword=storageos \
--namespace=default

用于动态分配卷的 Secret 可以在任何名称空间中创建,并通过 adminSecretNamespace 参数引用。 预先配置的卷使用的 Secret 必须在与引用它的 PVC 在相同的名称空间中。

本地

FEATURE STATE: Kubernetes v1.10 beta
该功能目前处于 beta 状态,意味着:

  • 版本名称包含 beta (例如 v2beta3)。
  • 代码经过了充分测试,启用该功能被认为是安全的。默认情况下被启用。
  • 对整体功能的支持在未来不会被移除,尽管细节上可能会做更改。
  • 在后续的 beta 或稳定版本中,对象的模式、语义可能以不兼容的方式发生变化。当这种情况发生时,我们将提供迁移到下一个版本的说明。这可能需要删除、编辑和重建 API 对象,编辑过程可能需要一些思考。这可能导致依赖该功能的应用程序停机一段时间。
  • 建议仅在非业务关键场景使用该功能,因为在后续版本中可能会发生不兼容的更改。如果您有多个可以独立升级的集群,那么您可能可以放松这个限制。
  • 请尝试使用我们的 beta 版功能,并给出反馈!在它们退出 beta 测试阶段之后,我们将很难去做更多的更改。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

本地卷还不支持动态分配,然而还是需要创建 StorageClass 以延迟卷绑定,直到完成 pod 的调度。这是由 WaitForFirstConsumer 卷绑定模式指定的。

延迟卷绑定使得调度器在为 PersistentVolumeClaim 选择一个合适的 PersistentVolume 时能考虑到所有 pod 的调度限制。

反馈