使用云盘动态存储卷

使用云盘动态存储卷

基于动态存储卷机制,可为每个应用副本自动创建并挂载一个独立的云盘,适用于数据库、中间件等等对 I/O 和延迟要求较高的场景,同时能够简化存储的生命周期管理。

工作原理在StatefulSet中使用云盘动态存储卷的流程如下:

定义模板新建或使用默认 StorageClass,作为动态创建云盘的模板,规定其类型、性能、回收策略等关键参数。

在应用中声明存储需求

在StatefulSet中定义 volumeClaimTemplates,并引用 StorageClass,声明Pod待使用的PVC的规格,如存储容量、访问模式等。

自动化创建并挂载存储卷StatefulSet 创建 Pod 时,系统会基于模板自动为其生成一个唯一的 PVC。CSI组件会根据 StorageClass 的规则创建 PV 并与 PVC 绑定,最终将该云盘挂载到 Pod 中。

适用范围可用区限制:除ESSD同城冗余云盘外,其他云盘类型无法跨可用区挂载,只能挂载到同一可用区下的Pod。

实例规格族限制:部分云盘类型仅支持挂载到特定的实例规格族。

CSI组件限制:已安装csi-plugin组件和csi-provisioner组件。

CSI组件默认安装,请确保未手动卸载。可在组件管理页面查看安装情况。建议升级CSI组件至最新版本。虚拟节点限制:如需在虚拟节点上使用云盘,需遵循集群和kube-scheduler版本要求。

展开查看版本要求

集群版本

kube-scheduler版本

1.28及以上

6.9.3及以上

1.26

6.8.7

1.24

6.4.7

1.22

6.4.5

灵骏节点限制:如需在灵骏节点上使用云盘,需满足以下要求。

展开查看

CSI 组件:不低于 v1.34.3。

为RAM角色授权:需为AliyunCCCSIPluginRole手动添加 eflo:DescribeNode 和 eflo:DescribeNodeType权限。

云盘标签:

访问ECS控制台-块存储-云盘。

在创建云盘过程中(仅支持在创建时添加),为云盘添加createdByProduct:eflo标签。

示例如下:

如挂载时报错OperationDenied.HpnZoneMismatch,请参见灵骏节点中挂载云盘时,Pod Event 报错 OperationDenied.HpnZoneMismatch怎么办?。创建后,使用该云盘来手动创建PV并通过PVC来绑定。该云盘可以且仅可以被调度到灵骏节点。

步骤一:选择StorageClass为便于使用,ACK提供多种默认StorageClass。由于StorageClass创建后无法修改,若默认配置不满足需求,可通过手动创建StorageClass新建。

使用默认StorageClass可从以下默认StorageClass中选择一个,在应用的storageClassName字段中引用其名称即可。

StorageClass名称

动态创建的云盘类型

alicloud-disk-topology-alltype(推荐)

默认先调度Pod再创建云盘,避免因可用区不匹配导致挂载失败(volumeBindingMode: WaitForFirstConsumer)。Pod调度到的节点可用区和实例规格,会结合云盘库存情况,按ESSD、SSD、高效云盘的顺序尝试创建。默认优先创建ESSD PL1,容量大小最低为20 GiB。

alicloud-disk-essd

ESSD云盘,默认为PL1性能级别,云盘容量大小最低为20 GiB。

重要 云盒内的ESSD云盘仅支持PL0级别,需手动创建StorageClass并指定performanceLevel为PL0。

alicloud-disk-ssd

SSD云盘,云盘容量大小最低为20 GiB。

alicloud-disk-efficiency

高效云盘,云盘容量大小最低为20 GiB。

可通过kubectl describe sc 查看StorageClass详细配置。手动创建StorageClasskubectl创建disk-sc.yaml。

示例以使用volumeBindingMode: WaitForFirstConsumer延迟绑定PV的StorageClass为例。

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

# StorageClass名称

name: alicloud-disk-wait-for-first-consumer

# 驱动类型,使用阿里云云盘CSI插件时固定为此值。

provisioner: diskplugin.csi.alibabacloud.com

parameters:

# 云盘类型,按优先级自适应选择

type: cloud_auto,cloud_essd,cloud_ssd

# 文件系统类型

fstype: ext4

diskTags: "a:b,b:c"

encrypted: "false"

# ESSD云盘的性能级别

performanceLevel: PL1

provisionedIops: "40000"

burstingEnabled: "false"

# 绑定模式,多可用区场景下建议使用WaitForFirstConsumer

volumeBindingMode: WaitForFirstConsumer

# 回收策略

reclaimPolicy: Retain

# 是否允许存储卷扩容

allowVolumeExpansion: true

# 拓扑限制:限制云盘只能在指定的可用区创建

allowedTopologies:

- matchLabelExpressions:

- key: topology.diskplugin.csi.alibabacloud.com/zone

values:

# 替换为实际可用区

- cn-hangzhou-i

- cn-hangzhou-k主要参数说明如下:

参数

说明

provisioner

驱动类型,必填参数。使用阿里云云盘CSI插件时固定为diskplugin.csi.alibabacloud.com。

parameters

type

云盘类型,必填参数。可取值:

cloud_essd(默认值):ESSD云盘

cloud_auto:ESSD AutoPL云盘

cloud_essd_entry:块存储概述

cloud_ssd:SSD云盘

cloud_efficiency:高效云盘

elastic_ephemeral_disk_standard:标准版弹性临时盘

elastic_ephemeral_disk_premium:高级版弹性临时盘

cloud_regional_disk_auto:ESSD同城冗余云盘

支持任意组合,例如type: cloud_ssd,cloud_essd,cloud_auto。系统将按配置顺序依次尝试创建。最终创建的云盘类型受节点实例、所在可用区云盘支持情况等因素影响。

resourceGroupId

云盘所属资源组。默认为""。

regionId

云盘所在地域,与集群地域相同。

fstype

云盘使用的文件系统。可取值:ext4(默认)、xfs。

mkfsOptions

云盘格式化参数,如mkfsOptions: "-O project,quota"。

diskTags

云盘标签。例如diskTags: "a:b,b:c",也可使用diskTags/a: b的格式指定。CSI组件需为v1.30.3及以上版本。

encrypted

云盘是否加密。默认为false,不加密。

performanceLevel

ESSD云盘性能级别,取值PL0、PL1(默认)、PL2或PL3。

通过云盒使用时需设置为PL0。volumeExpandAutoSnapshot【废弃】

自CSI 1.31.4版本起已废弃。

provisionedIops

使用ESSD AutoPL云盘时,配置云盘的预配置性能(IOPS)。

burstingEnabled

使用ESSD AutoPL云盘时,是否开启Burst(性能突发)。默认为false,不开启。

multiAttach

是否开启云盘多重挂载功能。默认为false,不开启。

volumeBindingMode

云盘的绑定模式。可取值:

Immediate(默认):先创建云盘再创建Pod。

WaitForFirstConsumer:延迟绑定,即先调度Pod,再根据Pod所在可用区创建云盘。

多可用区场景下,建议使用WaitForFirstConsumer,以优化因云盘和ECS节点不在同一可用区导致的挂载失败。

如需调度到虚拟节点,采用特定调度方式或添加了特定Annotation时,不支持使用WaitForFirstConsumer类型的StorageClass,请参见挂载云盘的Pod调度至虚拟节点时,PVC一直处于Pending状态怎么办?。reclaimPolicy

云盘回收策略。

Delete(默认):删除PVC时,PV和云盘会一起删除。

Retain:删除PVC时,PV和云盘数据不会被删除,需手动删除。

对数据安全性要求高时,推荐使用Retain,以免误删数据。

allowVolumeExpansion

配置为true时,允许在线扩容云盘存储卷。

allowedTopologies

限制云盘只能在特定的拓扑域中创建。

key:拓扑域标签。支持以下取值:

topology.diskplugin.csi.alibabacloud.com/zone:阿里云 CSI 插件提供的专用拓扑 key。

alibabacloud.com/ecs-instance-id:使用弹性临时盘时,支持指定节点。

values:包含可用区或节点 ID 的列表。

创建StorageClass。

kubectl create -f disk-sc.yaml查看StorageClass。

kubectl get sc输出中,StorageClass已创建,处于WaitForFirstConsumer绑定模式。

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE

alicloud-disk-wait-for-first-consumer diskplugin.csi.alibabacloud.com Retain WaitForFirstConsumer true 10s控制台

在ACK集群列表页面,单击目标集群名称,在集群详情页左侧导航栏,选择存储 > 存储类。

单击创建,选择存储卷类型为云盘,完成参数配置,然后单击创建。

参数

描述

参数

默认参数:type。

云盘类型,必填参数。可取值:

cloud_essd(默认值):ESSD云盘

cloud_auto:ESSD AutoPL云盘

cloud_essd_entry:块存储概述

cloud_ssd:SSD云盘

cloud_efficiency:高效云盘

elastic_ephemeral_disk_standard:标准版弹性临时盘

elastic_ephemeral_disk_premium:高级版弹性临时盘

cloud_regional_disk_auto:ESSD同城冗余云盘

支持任意组合,例如type: cloud_ssd,cloud_essd,cloud_auto。系统将按配置顺序依次尝试创建。最终创建的云盘类型受节点实例、所在可用区云盘支持情况等因素影响。

展开查看可选参数

resourceGroupId:云盘所属资源组。默认为""。

regionId:云盘所在地域,与集群地域相同。

fstype:云盘使用的文件系统。可取值:ext4(默认)、xfs。

mkfsOptions:云盘格式化参数,如mkfsOptions: "-O project,quota"。

diskTags:云盘标签。例如diskTags: "a:b,b:c",也可使用diskTags/a: b的格式指定。CSI组件需为v1.30.3及以上版本。

encrypted:云盘是否加密。默认为false,不加密。

performanceLevel:ESSD云盘性能级别,取值PL0、PL1(默认)、PL2或PL3。

通过云盒使用时需设置为PL0。provisionedIops:使用ESSD AutoPL云盘时,配置云盘的预配置性能(IOPS)。

burstingEnabled:使用ESSD AutoPL云盘时,是否开启Burst(性能突发)。默认为false,不开启。

multiAttach:是否开启云盘多重挂载功能。默认为false,不开启。

回收策略

云盘回收策略。

Delete(默认):删除PVC时,PV和云盘会一起删除。

Retain:删除PVC时,PV和云盘数据不会被删除,需手动删除。

对数据安全性要求高时,推荐使用Retain,以免误删数据。

绑定模式

云盘的绑定模式。可取值:

Immediate(默认):先创建云盘再创建Pod。

WaitForFirstConsumer:延迟绑定,即先调度Pod,再根据Pod所在可用区创建云盘。

多可用区场景下,建议使用WaitForFirstConsumer,以优化因云盘和ECS节点不在同一可用区导致的挂载失败。

如需调度到虚拟节点,采用特定调度方式或添加了特定Annotation时,不支持使用WaitForFirstConsumer类型的StorageClass,请参见挂载云盘的Pod调度至虚拟节点时,PVC一直处于Pending状态怎么办?。创建完成后,可在存储类页面查看新创建的StorageClass。

步骤二:创建应用并挂载云盘以StatefulSet为例介绍如何挂载云盘存储卷。

重要 云盘为非共享存储,未开启多重挂载时一次只能挂载一个Pod。在多副本 Deployment 中共享PVC会导致新Pod无法挂载仍被旧Pod占用的云盘而启动失败。推荐使用StatefulSet或单独为Pod挂载云盘。

如仍需在Deployment中使用云盘,建议使用云盘作为临时存储卷。如需启用多重挂载,请参见使用NVMe云盘多重挂载及Reservation。

创建statefulset.yaml。

以下示例创建了包含2个Pod的StatefulSet,使用 volumeClaimTemplates 来为每个 Pod 自动创建并绑定独立的持久化存储。apiVersion: apps/v1

kind: StatefulSet

metadata:

name: web

spec:

serviceName: "nginx"

replicas: 2

selector:

matchLabels:

app: nginx

template:

metadata:

labels:

app: nginx

spec:

# 建议配置以下securityContext以优化挂载性能

securityContext:

fsGroup: 1000

fsGroupChangePolicy: "OnRootMismatch"

containers:

- name: nginx

image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6

ports:

- containerPort: 80

volumeMounts:

# 将数据卷挂载到容器的/data目录

# name需与volumeClaimTemplates中定义的metadata.name一致

- name: pvc-disk

mountPath: /data

# 定义PVC模板

volumeClaimTemplates:

- metadata:

name: pvc-disk

spec:

# 访问模式

accessModes: [ "ReadWriteOnce" ]

# 关联此前创建的StorageClass

storageClassName: "alicloud-disk-wait-for-first-consumer"

resources:

requests:

# 申请的存储容量,即云盘大小

storage: 20Gi重要 在 Pod 中配置 securityContext.fsgroup 会导致kubelet在挂载卷时递归修改文件权限(chmod/chown)。若文件数量庞大,将显著延长挂载时间。

对于1.20及以上版本的集群,建议将fsGroupChangePolicy配置为OnRootMismatch,仅在首次挂载且卷根目录权限不匹配时才执行递归的权限变更,以优化挂载性能。若性能仍不满足要求或需更精细的权限控制,建议使用initContainer在主应用容器启动前自行执行权限调整命令。

创建StatefulSet。

kubectl create -f statefulset.yaml确认Pod处于Running状态。

kubectl get pod -l app=nginx查看挂载路径,确认已挂载云盘。

本示例Pod名称为web-1,请按实际替换。kubectl exec web-1 -- df -h /data预期输出:

Filesystem Size Used Avail Use% Mounted on

/dev/vdb 20G 24K 20G 1% /data步骤三:验证持久化存储通过“写入数据 -> 删除 Pod -> 检查数据”的流程,来验证存储在云盘上的数据在 Pod 重建后是否仍然存在。

在 Pod 中写入测试数据。

以Pod web-1为例,在其挂载的云盘路径 /data下创建一个test文件。

kubectl exec web-1 -- touch /data/test

kubectl exec web-1 -- ls /data预期输出:

lost+found

test模拟 Pod 故障,删除 Pod。

kubectl delete pod web-1再次执行kubectl get pod -l app=nginx,可以发现已自动创建一个同名的Pod web-1。

验证新 Pod 中的数据。

在新Pod web-1中再次检查 /data 目录。

kubectl exec web-1 -- ls /data预期输出中,此前创建的 test 文件依然存在,表明即使 Pod 被删除重建,数据也实现了持久化存储。

lost+found

test应用于生产环境高可用性

云盘选型

需综合评估其性能、计费以及节点的可用区和实例规格族,确保Pod能被调度至兼容的节点。

选择云盘类型时,SSD云盘、高效云盘已逐步停止售卖。建议选用ESSD PL0云盘或ESSD Entry云盘替换高效云盘,选用ESSD AutoPL云盘替换SSD云盘。

构建跨可用区容灾方案

应用层容灾: 对于数据库等关键业务,在多个可用区部署应用实例,并通过应用自身的数据同步机制实现高可用。

存储层容灾:选用支持多可用区容灾的云盘类型,将数据实时同步写入同一地域的不同可用区,实现跨可用区的故障恢复,请参见使用ESSD同城冗余云盘。

数据安全与备份

防止意外删除数据:

为防止数据丢失,建议将StorageClass的reclaimPolicy设置为Retain,PVC删除后,后端的云盘不会被删除,便于数据恢复。

常态化备份

动态卷简化了资源供给,但不能替代数据备份。对于核心业务,使用备份中心进行数据的备份和恢复。

启用静态加密:对于数据敏感型应用,在StorageClass中配置encrypted: "true"来加密云盘。

性能与成本优化

启用并行挂载

默认情况下,单个节点的云盘操作是串行的。可使用云盘并行挂载,加速Pod启动。

启用存储卷在线扩容

在StorageClass中设置allowVolumeExpansion: true,以便在未来存储需求增长时,在线扩容云盘存储卷。

配置存储监控与告警

基于容器存储监控配置告警,及时发现存储卷异常或性能瓶颈。

计费说明通过StorageClass动态创建的云盘采用按量付费,请参见块存储计费、块存储价格。

资源释放指引为避免产生预期外费用并确保数据安全,请遵循以下流程释放无需使用的资源。

删除工作负载

操作:删除所有使用相关PVC的应用,例如Deployment、StatefulSet等。此操作将停止运行的Pod并卸载存储卷。

命令示例:kubectl delete deployment

删除PVC

操作:删除应用关联的PVC。关联资源(PV和云盘)的释放取决于StorageClass的reclaimPolicy。

Delete:删除PVC后,其绑定的PV以及后端的云盘会被自动删除。此操作不可逆,请谨慎操作。

为防止数据意外丢失,可在执行删除前为云盘创建自动快照策略进行备份。Retain:删除PVC后,其绑定的PV状态会变为Released,但PV对象和后端的云盘会被完整保留。如确认云盘及其上的所有数据无需使用,请参见释放云盘删除。此操作不可逆,请务必谨慎操作。

命令示例:kubectl delete pvc

删除Kubernetes存储资源定义:此操作仅移除集群内的资源定义,不会删除后端的云盘实体。

删除PV

操作:手动删除处于Released状态的PV,可手动删除其定义。

命令示例:kubectl delete pv

删除StorageClass

操作:如果不再需要该类型的存储,可以删除对应的StorageClass。

命令示例:kubectl delete sc

常见问题挂载云盘的Pod调度至虚拟节点时,PVC一直处于Pending状态怎么办?可能是使用了不支持虚拟节点调度场景的StorageClass。当通过特定标签(Label)或注解(Annotation)将Pod调度到虚拟节点时,不支持使用volumeBindingMode: WaitForFirstConsumer模式的StorageClass。

原因:WaitForFirstConsumer模式依赖kube-scheduler为Pod选择一个物理节点,从而确定其可用区,然后再根据可用区创建云盘。但虚拟节点的部分调度机制不遵循此流程,导致CSI无法获取可用区信息,继而无法创建PV,PVC便处于Pending状态。

如遇问题,请检查Pod或其命名空间中是否包含以下任意一种配置:

Label:

alibabacloud.com/eci: "true":调度至ECI Pod。

alibabacloud.com/acs: "true":调度至ACS Pod。

指定节点:

通过spec.nodeName直接指定一个节点(节点名称前缀为virtual-kubelet)。

Annotation:

k8s.aliyun.com/eci-vswitch:指定ECI Pod的交换机。

k8s.aliyun.com/eci-fail-strategy: "fail-fast":ECI Pod的故障处理策略为快速失败。

如何为单个Pod或单副本Deployment挂载云盘存储卷?对于不需要多副本伸缩和稳定网络标识的简单应用,可手动创建PVC并将其挂载到Pod或Deployment,以实现持久化存储。

链路为:选择StorageClass -> 创建PVC -> 在应用中挂载PVC。

准备StorageClass。

创建PVC,申请存储资源。

kubectl创建disk-pvc.yaml。

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: disk-pvc

spec:

# 访问模式

accessModes:

- ReadWriteOnce

volumeMode: Filesystem

resources:

requests:

# 申请的存储容量,即云盘大小

storage: 20Gi

# 关联此前创建的StorageClass

storageClassName: alicloud-disk-topology-alltype 相关参数说明如下:

参数

说明

accessModes

存储卷的访问模式。可取值:ReadWriteOnce、ReadOnlyMany或ReadWriteMany。具体取决于StorageClass中的multiAttach配置以及PVC中的volumeMode配置。

multiAttach表示是否开启云盘多重挂载。默认为false,不开启。multiAttach为false,volumeMode配置为任意值时,访问模式仅支持ReadWriteOnce。

multiAttach为true,volumeMode为Filesystem时,访问模式仅支持ReadWriteOnce和ReadOnlyMany。

multiAttach为true,volumeMode为Block时,三种访问模式均支持。

重要 此场景下,访问模式通常为ReadWriteOnce (RWO) ,即同一时间只能被一个Pod挂载。因此Deployment副本数不能大于1。如尝试扩容,新Pod会因无法挂载已被占用的云盘而一直处于Pending状态。

volumeMode

存储卷的模式。可取值:

Filesystem(默认):存储卷会被格式化并挂载为目录。

Block:存储卷以未格式化的块设备形式直接提供给 Pod。

storage

申请的存储容量大小。不同云盘类型的容量范围不同。请确保storage取值符合其引用的 StorageClass 所对应的云盘类型的容量限制,以免云盘创建失败。

storageClassName

待绑定的StorageClass。

创建PVC。

kubectl create -f disk-pvc.yaml查看PVC。

kubectl get pvc输出中,由于StorageClass使用WaitForFirstConsumer模式,此时PVC处于Pending状态,直到第一个使用它的 Pod 被成功调度。

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE

disk-pvc Pending alicloud-disk-wait-for-first-consumer 14s控制台在集群管理页左侧导航栏,选择存储 > 存储声明。

在存储声明页面,单击创建,选择存储声明类型为云盘,按照页面提示完成参数的配置。

参数

描述

分配模式

选择使用存储类动态创建。

已有存储类

默认创建或手动创建的StorageClass。

总量

申请的存储容量大小。不同云盘类型的容量范围不同。请确保storage取值符合其引用的 StorageClass 所对应的云盘类型的容量限制,以免云盘创建失败。

访问模式

当前场景仅支持ReadWriteOnce,表示卷只能被一个Pod以读写方式挂载。

创建完成后,可在存储声明页面查看新创建的PVC。

在应用中挂载PVC。

创建disk-deployment.yaml。

展开查看示例YAML

apiVersion: apps/v1

kind: Deployment

metadata:

name: single-pod-app

spec:

# 确保副本数为1

replicas: 1

selector:

matchLabels:

app: nginx-single

template:

metadata:

labels:

app: nginx-single

spec:

containers:

- name: nginx

image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6

ports:

- containerPort: 80

# 在容器内定义挂载点

volumeMounts:

- name: my-persistent-storage # 必须与下面volumes中定义的name一致

mountPath: /data # 挂载到容器内的/data目录

# 在Pod级别声明并引用PVC

volumes:

- name: my-persistent-storage # 供容器引用的卷

persistentVolumeClaim:

claimName: disk-pvc # 引用此前创建的PVC部署Deployment。

kubectl create -f disk-deployment.yaml验证挂载结果。

确认Pod已经成功运行。

kubectl get pods -l app=nginx-single进入Pod内部,检查/data目录是否已成功挂载云盘。

# 获取Pod名称

POD_NAME=$(kubectl get pods -l app=nginx-single -o jsonpath='{.items[0].metadata.name}')

# 执行df -h命令

kubectl exec $POD_NAME -- df -h /data输出如下,表明20GiB的云盘已成功挂载。

Filesystem Size Used Avail Use% Mounted on

/dev/vdb 20G 24K 20G 1% /data相关文档云盘多可用区部署的配置优化建议,请参见云盘存储卷的高可用配置建议。

可参见创建有状态工作负载StatefulSet、创建无状态工作负载Deployment了解工作负载配置参数。

如果不再使用某块云盘且希望云盘停止计费时,可释放云盘。释放后,云盘及存储在云盘上的数据会被删除、云盘停止计费。

使用云盘存储卷时如遇问题,请参见云盘存储卷FAQ。

如集群仍在使用废弃的Flexvolume组件,请迁移Flexvolume至CSI。

相关推荐

P2P理财平台“有利网”获软银中国资本千万美元级别首轮投资,总交易额已超过2.6亿人民币
《瘟疫传说安魂曲》流程时长介绍 游戏通关多久?
365365bet体育在

《瘟疫传说安魂曲》流程时长介绍 游戏通关多久?

📅 08-13 👁️ 8739
什么叫做内推(内推招聘的两大黄金期和四个最佳时机浅析)
必发365手机在线登录

什么叫做内推(内推招聘的两大黄金期和四个最佳时机浅析)

📅 09-25 👁️ 8574