--- reviewers: - jsafrane - saad-ali - thockin - msau42 title: Storage Classes content_template: templates/concept weight: 30 --- {{% capture overview %}} 本文描述了 Kubernetes 中 StorageClass 的概念。建议先熟悉 [卷](/docs/concepts/storage/volumes/) 和 [持久卷](/docs/concepts/storage/persistent-volumes) 的概念。 {{% /capture %}} {{% capture body %}} ## 介绍 StorageClass 为管理员提供了描述存储 "类" 的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。这个类的概念在其他存储系统中有时被称为 "配置文件"。 ## StorageClass 资源 每个 StorageClass 都包含 `provisioner`、`parameters` 和 `reclaimPolicy` 字段, 这些字段会在 StorageClass 需要动态分配 `PersistentVolume` 时会使用到。 StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。 管理员可以为没有申请绑定到特定 StorageClass 的 PVC 指定一个默认的存储类 : 更多详情请参阅 [PersistentVolumeClaim 章节](/docs/concepts/storage/persistent-volumes/#class-1)。 ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: standard provisioner: kubernetes.io/aws-ebs parameters: type: gp2 reclaimPolicy: Retain allowVolumeExpansion: true mountOptions: - debug volumeBindingMode: Immediate ``` ### 存储分配器 每个 StorageClass 都有一个分配器,用来决定使用哪个卷插件分配 PV。该字段必须指定。 | 卷插件 | 内置分配器 | 配置例子 | |:---------------------|:----------:|:-------------------------------------:| | AWSElasticBlockStore | ✓ | [AWS EBS](#aws-ebs) | | AzureFile | ✓ | [Azure File](#azure-file) | | AzureDisk | ✓ | [Azure Disk](#azure-disk) | | CephFS | - | - | | Cinder | ✓ | [OpenStack Cinder](#openstack-cinder) | | FC | - | - | | FlexVolume | - | - | | Flocker | ✓ | - | | GCEPersistentDisk | ✓ | [GCE PD](#gce-pd) | | Glusterfs | ✓ | [Glusterfs](#glusterfs) | | iSCSI | - | - | | Quobyte | ✓ | [Quobyte](#quobyte) | | NFS | - | - | | RBD | ✓ | [Ceph RBD](#ceph-rbd) | | VsphereVolume | ✓ | [vSphere](#vsphere) | | PortworxVolume | ✓ | [Portworx Volume](#portworx-volume) | | ScaleIO | ✓ | [ScaleIO](#scaleio) | | StorageOS | ✓ | [StorageOS](#storageos) | | Local | - | [Local](#local) | 您不限于指定此处列出的 "内置" 分配器(其名称前缀为 "kubernetes.io" 并打包在 Kubernetes 中)。 您还可以运行和指定外部分配器,这些独立的程序遵循由 Kubernetes 定义的 [规范](https://git.k8s.io/community/contributors/design-proposals/storage/volume-provisioning.md)。 外部供应商的作者完全可以自由决定他们的代码保存于何处、打包方式、运行方式、使用的插件(包括 Flex)等。 代码仓库 [kubernetes-sigs/sig-storage-lib-external-provisioner](https://github.com/kubernetes-sigs/sig-storage-lib-external-provisioner) 包含一个用于为外部分配器编写功能实现的类库。可以通过下面的代码仓库,查看外部分配器列表。 [kubernetes-incubator/external-storage](https://github.com/kubernetes-incubator/external-storage). 例如,NFS 没有内部分配器,但可以使用外部分配器。 也有第三方存储供应商提供自己的外部分配器。 ### 回收策略 由 StorageClass 动态创建的 PersistentVolume 会在类的 `reclaimPolicy` 字段中指定回收策略,可以是 `Delete` 或者 `Retain`。如果 StorageClass 对象被创建时没有指定 `reclaimPolicy`,它将默认为 `Delete`。 通过 StorageClass 手动创建并管理的 PersistentVolume 会使用它们被创建时指定的回收政策。 ### 允许卷扩展 {{< feature-state for_k8s_version="v1.11" state="beta" >}} PersistentVolume 可以配置为可扩展。将此功能设置为 `true` 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。 当基础存储类的 `allowVolumeExpansion` 字段设置为 true 时,以下类型的卷支持卷扩展。 {{< table caption = "Table of Volume types and the version of Kubernetes they require" >}} | 卷类型 | Kubernetes 版本要求 | |:---------------------|:--------------------------| | gcePersistentDisk | 1.11 | | awsElasticBlockStore | 1.11 | | Cinder | 1.11 | | glusterfs | 1.11 | | rbd | 1.11 | | Azure File | 1.11 | | Azure Disk | 1.11 | | Portworx | 1.11 | | FlexVolume | 1.13 | | CSI | 1.14 (alpha), 1.16 (beta) | {{< /table >}} {{< note >}} 此功能仅可用于扩容卷,不能用于缩小卷。 {{< /note >}} ### 挂载选项 由 StorageClass 动态创建的 PersistentVolume 将使用类中 `mountOptions` 字段指定的挂载选项。 如果卷插件不支持挂载选项,却指定了该选项,则分配操作会失败。 挂载选项在 StorageClass 和 PV 上都不会做验证,所以如果挂载选项无效,那么这个 PV 就会失败。 ### 卷绑定模式 `volumeBindingMode` 字段控制了 [卷绑定和动态分配](/docs/concepts/storage/persistent-volumes/#provisioning) 应该发生在什么时候。 默认情况下,`Immediate` 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态分配。 对于由于拓扑限制而非集群所有节点可达的存储后端,PersistentVolume 会在不知道 Pod 调度要求的情况下绑定或者分配。 集群管理员可以通过指定 `WaitForFirstConsumer` 模式来解决此问题。 该模式将延迟 PersistentVolume 的绑定和分配,直到使用该 PersistentVolumeClaim 的 Pod 被创建。 PersistentVolume 会根据 Pod 调度约束指定的拓扑来选择或分配。这些包括但不限于 [资源需求](/docs/concepts/configuration/manage-compute-resources-container), [节点筛选器](/docs/concepts/configuration/assign-pod-node/#nodeselector), [pod 亲和性和互斥性](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity), 以及 [污点和容忍度](/docs/concepts/configuration/taint-and-toleration). 以下插件支持动态分配的 `WaitForFirstConsumer` 模式: * [AWSElasticBlockStore](#aws-ebs) * [GCEPersistentDisk](#gce-pd) * [AzureDisk](#azure-disk) 以下插件支持预创建绑定 PersistentVolume 的 `WaitForFirstConsumer` 模式: * 上述全部 * [Local](#local) {{< feature-state state="beta" for_k8s_version="1.17" >}} 动态配置和预先创建的 PV 也支持 [CSI卷](/docs/concepts/storage/volumes/#csi), 但是您需要查看特定 CSI 驱动程序的文档以查看其支持的拓扑键名和例子。 ### 允许的拓扑结构 {{< feature-state for_k8s_version="v1.12" state="beta" >}} 当集群操作人员使用了 `WaitForFirstConsumer` 的卷绑定模式,在大部分情况下就没有必要将配置限制为特定的拓扑结构。 然而,如果还有需要的话,可以使用 `allowedTopologies`。 这个例子描述了如何将分配卷的拓扑限制在特定的区域,在使用时应该根据插件支持情况替换 `zone` 和 `zones` 参数。 ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass 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。当参数被省略时,会使用默认值。 一个 StorageClass 最多可以定义 512 个参数。这些参数对象的总长度不能超过 256 KiB, 包括参数的键和值。 ### AWS EBS ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: slow provisioner: kubernetes.io/aws-ebs parameters: type: io1 iopsPerGB: "10" fsType: ext4 ``` * `type`:`io1`,`gp2`,`sc1`,`st1`。详细信息参见 [AWS 文档](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)。默认值:`gp2`。 * `zone`(弃用):AWS 区域。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone` 和 `zones` 参数不能同时使用。 * `zones`(弃用):以逗号分隔的 AWS 区域列表。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone`和`zones`参数不能同时使用。 * `iopsPerGB`:只适用于 `io1` 卷。每 GiB 每秒 I/O 操作。AWS 卷插件将其与请求卷的大小相乘以计算 IOPS 的容量,并将其限制在 20 000 IOPS(AWS 支持的最高值,请参阅 [AWS 文档](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)。 这里需要输入一个字符串,即 `"10"`,而不是 `10`。 * `fsType`:受 Kubernetes 支持的文件类型。默认值:`"ext4"`。 * `encrypted`:指定 EBS 卷是否应该被加密。合法值为 `"true"` 或者 `"false"`。这里需要输入字符串,即 `"true"`, 而非 `true`。 * `kmsKeyId`:可选。加密卷时使用密钥的完整 Amazon 资源名称。如果没有提供,但 `encrypted` 值为 true,AWS 生成一个密钥。关于有效的 ARN 值,请参阅 AWS 文档。 {{< note >}} `zone` 和 `zones` 已被弃用并被 [允许的拓扑结构](#allowed-topologies) 取代。 {{< /note >}} ### GCE PD ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: slow provisioner: kubernetes.io/gce-pd parameters: type: pd-standard replication-type: none ``` * `type`:`pd-standard` 或者 `pd-ssd`。默认:`pd-standard` * `zone`(弃用):GCE 区域。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。`zone` 和 `zones` 参数不能同时使用。 * `zones`(弃用):逗号分隔的 GCE 区域列表。如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度(round-robin)分配。`zone` 和 `zones` 参数不能同时使用。 * `fstype`: `ext4` 或 `xfs`。 默认: `ext4`。宿主机操作系统必须支持所定义的文件系统类型。 * `replication-type`:`none` 或者 `regional-pd`。默认值:`none`。 如果 `replication-type` 设置为 `none`,会分配一个常规(当前区域内的)持久化磁盘。 如果 `replication-type` 设置为 `regional-pd`,会分配一个 [区域性持久化磁盘(Regional Persistent Disk)](https://cloud.google.com/compute/docs/disks/#repds)。在这种情况下,用户必须使用 `zones` 而非 `zone` 来指定期望的复制区域(zone)。如果指定来两个特定的区域,区域性持久化磁盘会在这两个区域里分配。如果指定了多于两个的区域,Kubernetes 会选择其中任意两个区域。如果省略了 `zones` 参数,Kubernetes 会在集群管理的区域中任意选择。 {{< note >}} `zone` 和 `zones` 已被弃用并被 [allowedTopologies](#allowed-topologies) 取代。 {{< /note >}} ### Glusterfs ```yaml 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" ``` * `resturl`:分配 gluster 卷的需求的 Gluster REST 服务/Heketi 服务 url。 通用格式应该是 `IPaddress:Port`,这是 GlusterFS 动态分配器的必需参数。 如果 Heketi 服务在 openshift/kubernetes 中安装并暴露为可路由服务,则可以使用类似于 `http://heketi-storage-project.cloudapps.mystorage.com` 的格式,其中 fqdn 是可解析的 heketi 服务网址。 * `restauthenabled`:Gluster REST 服务身份验证布尔值,用于启用对 REST 服务器的身份验证。如果此值为 'true',则必须填写 `restuser` 和 `restuserkey` 或 `secretNamespace` + `secretName`。此选项已弃用,当在指定 `restuser`,`restuserkey`,`secretName` 或 `secretNamespace` 时,身份验证被启用。 * `restuser`:在 Gluster 可信池中有权创建卷的 Gluster REST服务/Heketi 用户。 * `restuserkey`:Gluster REST 服务/Heketi 用户的密码将被用于对 REST 服务器进行身份验证。此参数已弃用,取而代之的是 `secretNamespace` + `secretName`。 * `secretNamespace`,`secretName`:Secret 实例的标识,包含与 Gluster REST 服务交互时使用的用户密码。 这些参数是可选的,`secretNamespace` 和 `secretName` 都省略时使用空密码。所提供的 Secret 必须将类型设置为 "kubernetes.io/glusterfs",例如以这种方式创建: ``` kubectl create secret generic heketi-secret \ --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' \ --namespace=default ``` secret 的例子可以在 [glusterfs-provisioning-secret.yaml](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml) 中找到。 * `clusterid`:`630372ccdc720a92c681fb928f27b53f` 是集群的 ID,当分配卷时,Heketi 将会使用这个文件。它也可以是一个 clusterid 列表,例如: `"8452344e2becec931ece4e33c4674e4e,42982310de6c63381718ccfa6d8cf397"`。这个是可选参数。 * `gidMin`,`gidMax`:storage class GID 范围的最小值和最大值。在此范围(gidMin-gidMax)内的唯一值(GID)将用于动态分配卷。这些是可选的值。如果不指定,卷将被分配一个 2000-2147483647 之间的值,这是 gidMin 和 gidMax 的默认值。 * `volumetype`:卷的类型及其参数可以用这个可选值进行配置。如果未声明卷类型,则由分配器决定卷的类型。 例如: 'Replica volume': `volumetype: replicate:3` 其中 '3' 是 replica 数量. 'Disperse/EC volume': `volumetype: disperse:4:2` 其中 '4' 是数据,'2' 是冗余数量. 'Distribute volume': `volumetype: none` 有关可用的卷类型和管理选项,请参阅 [管理指南](https://access.redhat.com/documentation/en-US/Red_Hat_Storage/3.1/html/Administration_Guide/part-Overview.html)。 更多相关的参考信息,请参阅 [如何配置 Heketi](https://github.com/heketi/heketi/wiki/Setting-up-the-topology)。 当动态分配持久卷时,Gluster 插件自动创建名为 `gluster-dynamic-` 的端点和 headless service。在 PVC 被删除时动态端点和 headless service 会自动被删除。 ### OpenStack Cinder ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: gold provisioner: kubernetes.io/cinder parameters: availability: nova ``` * `availability`:可用区域。如果没有指定,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。 {{< note >}} {{< feature-state state="deprecated" for_k8s_version="1.11" >}} OpenStack 的内部驱动程序已经被弃用。请使用 [OpenStack 的外部驱动程序](https://github.com/kubernetes/cloud-provider-openstack)。 {{< /note >}} ### vSphere 1. 使用用户指定的磁盘格式创建一个 StorageClass。 ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick ``` `diskformat`: `thin`, `zeroedthick` 和 `eagerzeroedthick`。默认值: `"thin"`。 2. 在用户指定的数据存储上创建磁盘格式的 StorageClass。 ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick datastore: VSANDatastore ``` `datastore`:用户也可以在 StorageClass 中指定数据存储。卷将在 storage class 中指定的数据存储上创建,在这种情况下是 `VSANDatastore`。该字段是可选的。如果未指定数据存储,则将在用于初始化 vSphere Cloud Provider 的 vSphere 配置文件中指定的数据存储上创建该卷。 3. 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 例子](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere) 供您在 Kubernetes for vSphere 中尝试进行 persistent volume 管理。 ### Ceph RBD ```yaml 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 monitor,逗号分隔。该参数是必需的。 * `adminId`:Ceph 客户端 ID,用于在池 ceph 池中创建映像。默认是 "admin"。 * `adminSecret`:`adminId` 的 Secret 名称。该参数是必需的。 提供的 secret 必须有值为 "kubernetes.io/rbd" 的 type 参数。 * `adminSecretNamespace`:`adminSecret` 的命名空间。默认是 "default"。 * `pool`: Ceph RBD 池. 默认是 "rbd"。 * `userId`:Ceph 客户端 ID,用于映射 RBD 镜像。默认与 `adminId` 相同。 * `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 ``` * `userSecretNamespace`:`userSecretName` 的命名空间。 * `fsType`:Kubernetes 支持的 fsType。默认:`"ext4"`。 * `imageFormat`:Ceph RBD 镜像格式,"1" 或者 "2"。默认值是 "1"。 * `imageFeatures`:这个参数是可选的,只能在你将 `imageFormat` 设置为 "2" 才使用。 目前支持的功能只是 `layering`。默认是 "",没有功能打开。 ### Quobyte ```yaml 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" ``` * `quobyteAPIServer`:Quobyte API 服务器的格式是 `"http(s)://api-server:7860"` * `registry`:用于挂载卷的 Quobyte registry。你可以指定 registry 为 ``:`` 或者如果你想指定多个 registry,你只需要在他们之间添加逗号,例如 ``:,:,:``。 主机可以是一个 IP 地址,或者如果您有正在运行的 DNS,您也可以提供 DNS 名称。 * `adminSecretNamespace`:`adminSecretName`的 namespace。 默认值是 "default"。 * `adminSecretName`:保存关于 Quobyte 用户和密码的 secret,用于对 API 服务器进行身份验证。 提供的 secret 必须有值为 "kubernetes.io/quobyte" 的 type 参数 和 `user` 与 `password` 的键值, 例如以这种方式创建: ```shell kubectl create secret generic quobyte-admin-secret \ --type="kubernetes.io/quobyte" --from-literal=key='opensesame' \ --namespace=kube-system ``` * `user`:对这个用户映射的所有访问权限。默认是 "root"。 * `group`:对这个组映射的所有访问权限。默认是 "nfsnobody"。 * `quobyteConfig`:使用指定的配置来创建卷。您可以创建一个新的配置,或者,可以修改 Web console 或 quobyte CLI 中现有的配置。默认是 "BASE"。 * `quobyteTenant`:使用指定的租户 ID 创建/删除卷。这个 Quobyte 租户必须已经于 Quobyte。 默认是 "DEFAULT"。 ### Azure 磁盘 #### Azure Unmanaged Disk Storage Class(非托管磁盘存储类){#azure-unmanaged-disk-storage-class} ```yaml 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 ``` * `skuName`:Azure 存储帐户 Sku 层。默认为空。 * `location`:Azure 存储帐户位置。默认为空。 * `storageAccount`:Azure 存储帐户名称。如果提供存储帐户,它必须位于与集群相同的资源组中,并且 `location` 是被忽略的。如果未提供存储帐户,则会在与群集相同的资源组中创建新的存储帐户。 #### Azure 磁盘 Storage Class(从 v1.7.2 开始){#azure-disk-storage-class} ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: slow provisioner: kubernetes.io/azure-disk parameters: storageaccounttype: Standard_LRS kind: Shared ``` * `storageaccounttype`:Azure 存储帐户 Sku 层。默认为空。 * `kind`:可能的值是 `shared`(默认)、`dedicated` 和 `managed`。 当 `kind` 的值是 `shared` 时,所有非托管磁盘都在集群的同一个资源组中的几个共享存储帐户中创建。 当 `kind` 的值是 `dedicated` 时,将为在集群的同一个资源组中新的非托管磁盘创建新的专用存储帐户。 * `resourceGroup`: 指定要创建 Azure 磁盘所属的资源组。必须是已存在的资源组名称。若未指定资源组,磁盘会默认放入与当前 Kubernetes 集群相同的资源组中。 - Premium VM 可以同时添加 Standard_LRS 和 Premium_LRS 磁盘,而 Standard 虚拟机只能添加 Standard_LRS 磁盘。 - 托管虚拟机只能连接托管磁盘,非托管虚拟机只能连接非托管磁盘。 ### Azure 文件 ```yaml 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 ``` * `skuName`:Azure 存储帐户 Sku 层。默认为空。 * `location`:Azure 存储帐户位置。默认为空。 * `storageAccount`:Azure 存储帐户名称。默认为空。 如果不提供存储帐户,会搜索所有与资源相关的存储帐户,以找到一个匹配 `skuName` 和 `location` 的账号。 如果提供存储帐户,它必须存在于与集群相同的资源组中,`skuName` 和 `location` 会被忽略。 * `secretNamespace`:包含 Azure 存储帐户名称和密钥的密钥的名称空间。 默认值与 Pod 相同。 * `secretName`:包含 Azure 存储帐户名称和密钥的密钥的名称。 默认值为 `azure-storage-account--secret` * `readOnly`:指示是否将存储安装为只读的标志。默认为 false,表示 读/写 挂载。 该设置也会影响VolumeMounts中的 `ReadOnly` 设置。 在存储分配期间,为挂载凭证创建一个名为 `secretName` 的 secret。如果集群同时启用了 [RBAC](/docs/admin/authorization/rbac/) 和 [Controller Roles](/docs/admin/authorization/rbac/#controller-roles), 为 `system:controller:persistent-volume-binder` 的 clusterrole 添加 `secret` 资源的 `create` 权限。 在多租户上下文中,强烈建议显式设置 `secretNamespace` 的值,否则其他用户可能会读取存储帐户凭据。 ### Portworx 卷 ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: portworx-io-priority-high provisioner: kubernetes.io/portworx-volume parameters: repl: "1" snap_interval: "70" io_priority: "high" ``` * `fs`:选择的文件系统:`none/xfs/ext4`(默认:`ext4`)。 * `block_size`:以 Kbytes 为单位的块大小(默认值:`32`)。 * `repl`:同步副本数量,以复制因子 `1..3`(默认值:`1`)的形式提供。 这里需要填写字符串,即,`"1"` 而不是 `1`。 * `io_priority`:决定是否从更高性能或者较低优先级存储创建卷 `high/medium/low`(默认值:`low`)。 * `snap_interval`:触发快照的时钟/时间间隔(分钟)。快照是基于与先前快照的增量变化,0 是禁用快照(默认:`0`)。 这里需要填写字符串,即,是 `"70"` 而不是 `70`。 * `aggregation_level`:指定卷分配到的块数量,0 表示一个非聚合卷(默认:`0`)。 这里需要填写字符串,即,是 `"0"` 而不是 `0`。 * `ephemeral`:指定卷在卸载后进行清理还是持久化。 `emptyDir` 的使用场景可以将这个值设置为 true , `persistent volumes` 的使用场景可以将这个值设置为 false(例如 Cassandra 这样的数据库)`true/false`(默认为 `false`)。这里需要填写字符串,即,是 `"true"` 而不是 `true`。 ### ScaleIO ```yaml 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 ``` * `provisioner`:属性设置为 `kubernetes.io/scaleio` * `gateway` 到 ScaleIO API 网关的地址(必需) * `system`:ScaleIO 系统的名称(必需) * `protectionDomain`:ScaleIO 保护域的名称(必需) * `storagePool`:卷存储池的名称(必需) * `storageMode`:存储提供模式:`ThinProvisioned`(默认)或 `ThickProvisioned` * `secretRef`:对已配置的 Secret 对象的引用(必需) * `readOnly`:指定挂载卷的访问模式(默认为 false) * `fsType`:卷的文件系统(默认是 ext4) ScaleIO Kubernetes 卷插件需要配置一个 Secret 对象。 secret 必须用 `kubernetes.io/scaleio` 类型创建,并与引用它的 PVC 所属的名称空间使用相同的值 如下面的命令所示: ```shell kubectl create secret generic sio-secret --type="kubernetes.io/scaleio" \ --from-literal=username=sioadmin --from-literal=password=d2NABDNjMA== \ --namespace=default ``` ### StorageOS ```yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/storageos parameters: pool: default description: Kubernetes volume fsType: ext4 adminSecretNamespace: default adminSecretName: storageos-secret ``` * `pool`:分配卷的 StorageOS 分布式容量池的名称。如果未指定,则使用通常存在的 `default` 池。 * `description`:分配给动态创建的卷的描述。所有卷描述对于 storage class 都是相同的, 但不同的 storage class 可以使用不同的描述,以区分不同的使用场景。 默认为 `Kubernetas volume`。 * `fsType`:请求的默认文件系统类型。请注意,在 StorageOS 中用户定义的规则可以覆盖此值。默认为 `ext4` * `adminSecretNamespace`:API 配置 secret 所在的命名空间。如果设置了 adminSecretName,则是必需的。 * `adminSecretName`:用于获取 StorageOS API 凭证的 secret 名称。如果未指定,则将尝试默认值。 StorageOS Kubernetes 卷插件可以使 Secret 对象来指定用于访问 StorageOS API 的端点和凭据。 只有当默认值已被更改时,这才是必须的。 secret 必须使用 `kubernetes.io/storageos` 类型创建,如以下命令: ```shell 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 for_k8s_version="v1.14" state="stable" >}} ```yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer ``` 本地卷还不支持动态分配,然而还是需要创建 StorageClass 以延迟卷绑定,直到完成 pod 的调度。这是由 `WaitForFirstConsumer` 卷绑定模式指定的。 延迟卷绑定使得调度器在为 PersistentVolumeClaim 选择一个合适的 PersistentVolume 时能考虑到所有 pod 的调度限制。 {{% /capture %}}