本文以动态创建存储卷方式为例,介绍如何通过容器服务 VKE 实现云盘持久化存储。
通常 Deployment 用于部署无状态服务,StatefulSet 用于部署有状态服务。本节内容主要针对有状态服务挂载块存储实现数据持久化存储。有状态负载 StatefulSet 的应用场景如下:
StatefulSet 对应 Pod 的存储需要通过 StorageClass 来动态创建。每个 Pod 都会根据 StatefulSet 中定义的 VolumeClaimTemplate 来创建一个对应的 PVC,然后 PVC 通过 StorageClass 自动创建对应的 PV,并挂载给 Pod。因此,需要首先创建 StorageClass,即采用动态创建模式。
云盘又称弹性块存储,根据用途可分为系统盘和数据盘。
说明
云盘规格的详细说明,请参见 云盘规格。
限制项 | 限制说明 |
---|---|
单台云服务器可挂载的最大数量 | 不同计算规格可挂载的云盘数量有所不同,详细请参考 实例规格介绍。 |
单块系统盘的容量 | 极速型 SSD:40GiB~500GiB |
单块数据盘的容量 | 极速型 SSD:20GiB~32768GiB |
本地盘云服务器是否支持自定义挂载新本地盘 | 不支持,本地盘随云服务器创建和销毁。 |
单个云盘类型的最大使用量 | 对于单个云盘类型,每个火山引擎账号在每个地域最大使用 64TiB 容量。 |
本章为您简单介绍,创建存储卷涉及的资源类型以及动态存储卷和静态存储卷的差异。
从消费存储的逻辑上看,使用时应用层会声明一个对存储的需求(PVC),而 Kubernetes 会通过最佳匹配的方式选择一个满足 PVC 需求的 PV,并与之绑定。而根据 PV 的创建方式可以将存储卷分为动态存储和静态存储卷:
静态存储卷通常由集群管理员结合集群中存储需求,事先规划好存储介质,并创建对应的 PV 对象提供给 PVC 来消费。如果工作负载中定义了 PVC 需求,Kubernetes 会通过相关规则实现 PVC 和匹配的 PV 进行绑定,实现了应用对存储服务的访问能力。
动态存储卷是集群管理员配置好存储资源池,并创建存储类,当有 PVC 需要消费 PV 的时候,根据 PVC 定义的需求,结合存储类定义的存储模版信息,由 Provisioner 插件动态创建一个 PV。
动态存储卷和静态存储卷区别是:动态卷是插件自动创建 PV,而静态卷是集群管理员手动创建 PV。
动态存储卷的优势:
当您定义存储类时,可以选择存储卷的绑定模式,包括
绑定模式 | 说明 |
---|---|
Immediate | 立即创建 |
WaitForFirstConsumer | 延迟创建 |
在以下示例中,在 YAML 文件中使用 volumeBindingMode
字段定义了动态创建 PV 的绑定模式 ,WaitForFirstConsume
代表延迟创建,直到使用该存储卷声明的 Pod 被创建。
allowVolumeExpansion: true apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ebs-ssd parameters: ChargeType: PostPaid type: ESSD_PL0 provisioner: ebs.csi.volcengine.com reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer
当用户创建 PVC 时,会在集群寻找符合要求的 PV 进行绑定,如果没有找到符合要求的 PV ,则会开启自动创建流程:
总的来说,如果存储类中定义以 Immediate 绑定模式完成 PV 和 PVC 的绑定,那么当 PVC 创建时会立即绑定现有的合适 PV,若没有合适的,则立即新建一个合适的 PV 以供绑定。
当用户创建 PVC 时,不会立即执行绑定 PV 的动作,而是等待这个 PVC 被 Pod 消费,绑定的流程如下:
说明
云盘在挂载时,存在可用区的限制,只有可用区一致的的云盘和节点才能挂载在一起,这种限制可能导致使用时存在以下问题。
当存在多个可用区时,可以采用 WaitForFirstConsumer
绑定模式可以规避以上问题。当用户创建 PVC 时,Provisioner 将不再立即进行 PV 的绑定或新建,而是会等待这个 PVC 被 Pod 消费时才会执行创建过程。在此模式下,在 Pod 启动时,先进行 Pod 的调度,当确认 Pod 的运行位置后,再根据 Pod 所在可用区信息进行 PV 和云盘的创建,从而保障云盘 Pod 运行节点在相同可用区。所以,在具备多个可用区的集群环境下,更加推荐使用 WaitForFirstConsumer
绑定模式。
说明
本操作指引中选择存储类型为云盘,若您需要文件存储类型,可参考 NAS 存储持久化。
支持通过控制台或 YAML 文件两种方式创建工作负载。
您可以通过执行 YAML 文件实现工作负载的创建,示例如下:
apiVersion: v1 kind: Service metadata: name: headless-svc-web namespace: default spec: clusterIP: None clusterIPs: - None ports: - name: headless-service-port-0 port: 80 protocol: TCP targetPort: 80 selector: app: web sessionAffinity: None type: ClusterIP --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web namespace: default spec: podManagementPolicy: OrderedReady replicas: 2 selector: matchLabels: app: web serviceName: headless-svc-web template: metadata: labels: app: web spec: containers: - image: cr-demo-cn-beijing.cr.volces.com/xxxx/hg-web-test:v2.0 name: web ports: - containerPort: 80 protocol: TCP volumeMounts: - mountPath: /test name: ssd volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null name: ssd namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi storageClassName: ebs-ssd volumeMode: Filesystem
检测有状态工作负载创建完成情况。
扩容 Pod,验证 PVC 同步扩容。
验证 Pod 删除后,PVC 保留不变。
验证 StatefulSet 服务的持久化存储。
/test
路径下的文件。kubectl exec web-0 ls /test
预期输出:
lost+found
/test
路径下创建文件 test
。kubectl exec web-0 touch /test/test
/test
路径下的文件。kubectl exec web-0 ls /test
预期输出:
lost+found test
web-0
的 Pod。kubectl delete pod web-0
预期输出:
pod "web-0" deleted
/test
路径下的文件。kubectl exec web-0 ls /test
预期输出:
lost+found test
test
文件在 Pod 删除后仍然存在,说明云盘的数据可持久化保存。