Kubernetes 中实现持久化存储的简单指南

了解如何在 Kubernetes 中为有状态应用程序实现持久化存储。本指南将揭秘持久卷 (PV) 和持久卷声明 (PVC),解释访问模式和存储类 (StorageClasses)。包含用于定义 PVC 和将存储挂载到 Pod 的实用 YAML 示例,从而实现容器化应用程序中可靠的数据持久性。

32 浏览量

Kubernetes 中实现持久化存储的简单指南

在容器编排领域,Kubernetes 擅长管理无状态应用——即那些在重启或扩缩容事件之间不需要保留数据的应用。然而,许多现代应用,例如数据库、消息队列和键值存储,本质上都是有状态的。这些应用需要一种可靠的方式来持久存储和访问数据,即使运行它们的 Pod 被重新调度或替换。这就是 Kubernetes 持久化存储发挥作用的地方。

本指南将阐明 PersistentVolumes (PVs) 和 PersistentVolumeClaims (PVCs) 的概念,它们是 Kubernetes 中管理持久化存储的核心组件。我们将通过实际的 YAML 示例,逐步讲解如何定义、请求存储并将其绑定到您的 Pod,使您能够自信地在 Kubernetes 集群上部署有状态应用。

理解 PersistentVolumes (PVs) 和 PersistentVolumeClaims (PVCs)

在深入实现之前,了解 PV 和 PVC 的作用至关重要:

  • PersistentVolume (PV): PV 是集群中的一块存储,它由管理员预先配置或通过 StorageClasses 动态配置。PV 是集群资源,很像节点 (Nodes)。它们具有独立于使用该 PV 的任何单个 Pod 的生命周期。PV 抽象了底层存储的实现细节(例如 NFS、iSCSI、云提供商块存储)。
  • PersistentVolumeClaim (PVC): PVC 是用户对存储的请求。它消费集群中可用的 PV 形式的存储资源。PVC 类似于 Pod,它们都消费计算资源,并且作用域限定在命名空间 (namespace) 内。PVC 指定了所需的存储容量、访问模式以及可选的 StorageClass。

这种职责分离使得集群管理员可以独立地配置和管理存储资源,而应用开发者则可以请求存储,而无需了解底层实现细节。

关键概念:访问模式和 StorageClasses

在使用 PV 和 PVC 时,需要掌握的两个重要概念是访问模式 (Access Modes) 和 StorageClasses:

访问模式

访问模式定义了卷如何可以挂载到 Pod。可用的访问模式有:

  • ReadWriteOnce (RWO):卷可以由单个节点以读写方式挂载。
  • ReadOnlyMany (ROX):卷可以由多个节点以只读方式挂载。
  • ReadWriteMany (RWX):卷可以由多个节点以读写方式挂载。

需要注意的是,这些模式的实际支持取决于底层存储提供商。

StorageClasses

StorageClass 提供了一种方式,让管理员可以描述他们提供的存储“类别”。不同的类别可能对应不同的服务质量 (quality-of-service) 等级、备份策略,或由集群管理员确定的任意策略。一个 StorageClass 有一个存储配置器 (provisioner) 和一组用于该配置器的参数。当创建的 PVC 没有指定特定的 PV,并且请求了一个 StorageClass 时,Kubernetes 将使用指定的 StorageClass 动态配置一个 PV。

实现持久化存储:分步指南

让我们来看一个常见的场景:为 Pod 请求和使用持久化存储。

步骤 1:定义 PersistentVolumeClaim (PVC)

首先,您需要创建一个 PVC 来指定您的存储需求。这个 PVC 将作为您的应用对存储的请求。

pvc.yaml 示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

在此示例中:

  • name: my-pvc:这是我们 PVC 的名称。
  • accessModes: - ReadWriteOnce:我们请求的存储可以由单个节点以读写方式挂载。
  • resources.requests.storage: 1Gi:我们请求 1 吉字节的存储空间。

应用 PVC:

将上述内容保存到名为 pvc.yaml 的文件中,并将其应用到您的集群:

kubectl apply -f pvc.yaml

应用后,您可以检查 PVC 的状态:

kubectl get pvc my-pvc

如果存在合适的 PV 或已动态配置 PV,您应该看到输出显示 PVC 处于 Bound(已绑定)状态。

步骤 2:创建一个使用 PVC 的 Pod

现在,让我们创建一个 Pod,它将利用我们 PVC 请求的存储。我们将把 PVC 提供的卷挂载到容器内的特定目录中。

pod-with-pv.yaml 示例:

apiVersion: v1
kind: Pod
metadata:
  name: my-stateful-pod
spec:
  containers:
    - name: my-container
      image: nginx
      ports:
        - containerPort: 80
      volumeMounts:
        - name: my-persistent-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: my-persistent-storage
      persistentVolumeClaim:
        claimName: my-pvc

在此示例中:

  • volumes:我们定义了一个名为 my-persistent-storage 的卷。
  • persistentVolumeClaim.claimName: my-pvc:这会将我们的卷链接到我们之前创建的 PVC。
  • volumeMounts:在容器定义内部,我们指定了该卷应挂载的位置 (mountPath: /usr/share/nginx/html)。

应用 Pod:

将上述内容保存到名为 pod-with-pv.yaml 的文件中,并将其应用:

kubectl apply -f pod-with-pv.yaml

现在,您的 nginx 容器将可以在 /usr/share/nginx/html 路径访问由 my-pvc 定义的持久化存储。即使 Pod 被删除并重新创建,只要 PVC 及其底层 PV 保持不变,写入此路径的任何数据都将得到持久化。

使用 StorageClasses 进行动态配置

手动创建 PV 可能会很繁琐。Kubernetes 提供了动态配置 (dynamic provisioning),当 PVC 请求的存储无法由现有 PV 满足时,PV 会自动创建。这通过 StorageClasses 实现。

大多数云提供商(AWS、GCP、Azure)都提供了预配置的 StorageClasses。您可以使用以下命令检查它们:

kubectl get storageclass

要使用动态配置,您只需在 PVC 定义中添加 storageClassName 字段:

pvc-dynamic.yaml 示例:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-dynamic-pvc
spec:
  storageClassName: standard # Replace 'standard' with an actual StorageClass name
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

当您应用此 PVC 时,Kubernetes 将查找名为 standard(或您指定的任何名称)的 StorageClass,并指示其配置器创建一个新的 5Gi PV 并将其绑定到此 PVC。

提示和最佳实践

  • 选择正确的访问模式: 仔细考虑您的应用程序所需的访问模式。ReadWriteOnce 通常用于单副本数据库,而 ReadWriteMany 对于多个 Pod 使用的共享文件系统是必需的。
  • 理解存储性能: 不同的存储提供商和 StorageClasses 提供不同的性能特征(IOPS、吞吐量)。选择一个符合您应用程序性能需求的 StorageClass。
  • 备份策略: 持久化存储并不自动意味着备份。为您的持久卷实施一个可靠的备份策略,尤其是对于关键数据。
  • PV 回收策略: PV 具有 reclaimPolicy,可以是 Delete(默认)、RetainRecycle(已弃用)。Retain 对于在 PV 被删除但底层存储仍然存在时确保数据不丢失非常有用。
  • 命名空间考量: PVC 是命名空间范围的。确保您的 Pod 和 PVC 位于同一命名空间中才能进行绑定。

总结

实现持久化存储是在 Kubernetes 中运行有状态应用程序的基本要求。通过理解和利用 PersistentVolumes 和 PersistentVolumeClaims,以及 StorageClasses 的灵活性,您可以可靠地管理应用程序的数据。本指南提供了入门的基础知识和实践示例,使您能够在 Kubernetes 上部署更复杂、更具弹性的有状态工作负载。