Kubernetes数据存储相关概念


1. 存储卷概述

存储卷(Volume) 是一个抽象层,是定义在Pod资源之上,表示可以被容器挂载的存储资源。每个容器都可以通过卷来持久化或共享数据。存储卷的生命周期由 Pod 控制,Pod 被销毁时,相关的卷也会被销毁(除非是持久化存储卷)。

img

Kubernetes 中的存储卷有以下几个关键特性:

  • 生命周期:与 Pod 生命周期相同。Pod 启动时,存储卷被挂载到容器中,Pod 销毁时,存储卷也随之销毁(但对于持久化存储卷,存储内容会被保留)。
  • 数据共享:多个容器可以挂载同一个存储卷,从而实现数据共享和互操作。
  • 支持多种存储后端:Kubernetes 支持多种存储类型,包括本地磁盘、NFS、云存储、分布式存储等。

存储卷类型:

  • 临时存储卷

  • 节点存储卷

  • 网络存储卷

  • 持久存储卷

2. 临时存储卷

临时存储卷是与 Pod 生命周期紧密绑定的,它们在 Pod 启动时创建,并在 Pod 被销毁时删除。临时存储卷适用于容器运行时的短期数据存储需求。例如,容器内部的缓存数据或其他不需要持久化的数据。

常见的临时存储卷:

  • emptyDir:在 Pod 启动时创建,Pod 被删除时删除,适合用于容器间的临时数据交换。例如,可以用它来在多个容器之间共享数据。
  • configMap:用于存储配置文件,将配置数据挂载为文件供容器访问。可以动态更新配置。
  • secret:用于存储敏感数据(如密码、API 密钥等),并提供加密存储和访问的能力。
  • downwardAPI:允许容器访问有关 Pod 和容器的元数据,如 Pod 名称、Pod IP 等信息。

emptyDir:配置参考

apiVersion: v1
kind: Pod
metadata:
  name: emptydir-example
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: data-volume
  volumes:
    - name: data-volume
      emptyDir: {}

特点:

  • 数据会在 Pod 销毁时丢失。
  • 不具有持久化能力,不适用于需要持久化数据的应用场景。

3. 节点存储卷

hostPath类型的存储卷是指与某个节点直接关联的存储资源,通常用于存储与特定节点相关的数据。。它们的生命周期依赖于节点,Pod 可以使用节点存储卷进行高效的本地存储。

hostPath存储卷将主机文件系统上的某个目录挂载到 Pod 中,可以使用本地节点的磁盘资源。这种类型的存储卷适用于测试环境、存储日志文件或共享存储等。

hostPath卷:配置参考

apiVersion: v1
kind: Pod
metadata:
  name: hostpath-example
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:   # 定义存储卷挂载列表
        - mountPath: /var/log   # 容器的挂载目录
          name: varlog
          readOnly: true  # 可选字段,默认false
  volumes:   # 定义存储卷列表
    - name: varlog
      hostPath:
        path: /var/log   # 主机上目录位置
        type: Directory  # 此字段可选

常见的hostPath卷类型type

类型 说明
"" 空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。
DirectoryOrCreate 路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755
Directory 路径上必须存在的目录
FileOrCreate 路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644
File 路径上必须存在的文件

特点:

  • 具有持久化能力,但仅限固定节点。
  • 适合需要在特定节点上存储数据的场景,daemonset控制器。
  • 存储卷只能在节点本地使用,无法跨节点共享(缺点)。
  • hostPath 卷的使用需要谨慎,因为它会与节点的文件系统直接交互,可能引发数据一致性和安全性问题。

4. 网络存储卷

网络存储卷是指通过网络协议将远程存储系统挂载到 Kubernetes 集群中的存储卷。它们适用于跨节点共享数据的场景,通常需要支持多 Pod 或多节点的并发访问。

常见的网络存储卷类型:

  • NFS(Network File System):通过 NFS 协议共享文件系统,多个 Pod 可以共享同一个存储卷,适用于文件存储、共享文件等场景。

  • GlusterFS:一个开源的分布式文件系统,支持高可用性和横向扩展,适用于大规模的文件存储。

  • CephFS:Ceph 的分布式文件系统,支持高可用、高性能和数据冗余,适合大规模存储系统。

温馨提示:

  • GlusterFS在v1.25 版本中被弃用,然后在 v1.26 版本中被完全移除。

  • Ceph RBD在v1.28 版本中被弃用,并在 v1.31 版本中被完全移除。

  • NFS存储仍然支持,后期可能进入大量支持云存储阶段

4.1 NFS卷:配置参考

前提:有可用的NFS服务器并配置相应的挂载目录。

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
    - name: redis
      image: redis
      volumeMounts:
        - mountPath: /data # 挂载到容器的路径
          name: nfs-volume
  volumes:
    - name: nfs-volume
      nfs:
        server: <nfs-server-ip>  # NFS服务器IP
        path: /data/redis    # nfs服务器的共享路径
        readOnly: true   # 可选,默认为false

4.2 RBD存储卷:配置参考

前提:在Kubernetes集群外存在一个Ceph RBD存储集群,网络与集群互通。

apiVersion v1
kind: Pod
metadata:
  name: rbd-pod
spec:
  containers:
  - name: redis
    image: redis
    ports:
    - containerPort: 6379
      name: redisport
    volumeMounts:
    - mountPath: /data
      name: reids-rdb-vol
  volumes:
    - name: redis-rbd-vol
      rbd:
        monitors:
        - '10.0.0.105':6789
        - '10.0.0.106':6789
        - '10.0.0.107':6789
        pool: k8s-rbd
        image: redis
        fsType: xfs
        readOnly: false
        user: admin
        secretRef:
          name: ceph-secret

字段说明:

  • monitors:Ceph 存储监视器
  • image: rados image 的名称
  • pool: rados 存储名称,默认为 RBD。
  • user: rados 用户名,默认为 admin。
  • secretRef:RBD 用户认证时使用的保存有相应认证信息的 Secret 对象
  • readOnly:是否以只读的方式进行访问,默认为false。
  • fsType:要挂载的存储卷的文件系统类型,如 ext4、xfs、ntfs 等,默认为 ext4。

网络存储卷特点:

  • 支持跨节点的文件共享。
  • 适用于多容器共享数据的场景。
  • 性能可能受到网络带宽和延迟的影响。

5. 持久存储卷

持久存储卷(Persistent Volumes,简称 PV)与普通的临时存储卷不同,PV 设计用于持久化存储,在 Pod 的生命周期之外仍然存在,适用于需要长期存储的数据,如数据库、日志文件、缓存、重要的配置文件等。

持久化存储卷(PV)有两种形式:

  • 静态 PV:管理员手动预先创建并配置 PV,它绑定到一个具体的存储资源(如 NFS、iSCSI、云存储等)。PV 的生命周期与 Pod 无关,即便 Pod 被销毁,PV 中的数据仍然保留。PV 的生命周期与 Pod 无关,即便 Pod 被销毁,PV 中的数据仍然保留。
  • 动态 PV:通过 StorageClass 进行动态创建。管理员通过 StorageClass 定义存储的类型和参数,Kubernetes 会根据 PVC 请求动态创建相应的 PV。

5.1. PV 和 PVC 的关系

在 Kubernetes 中,PV(Persistent Volume) 和 PVC(Persistent Volume Claim) 是用于管理和使用持久化存储的资源。它们的关系可以简单理解为:

  • PV 是存储资源,由管理员创建和管理,类似于“硬盘”。
  • PVC 是用户的需求,由用户创建,用于申请存储资源,类似于“申请使用硬盘”。
  • PV 和 PVC 绑定在一起,用户通过 PVC 使用 PV 提供的存储。
  • 它们通常用于数据的持久化存储,确保数据在 Pod 生命周期之外依然存在。

PV和PVC通过声明式的方式实现存储的管理:

  • PV集群层面资源,不受namespace限制。通常与物理存储或云存储后端绑定。每个 PV 定义了存储容量、访问模式、存储类型(如 NFS、Ceph、EBS)等属性。
  • PVC是对 PV 的请求。PVC 声明了存储需求(例如容量、访问模式等),Kubernetes 会根据 PVC 来匹配并绑定到合适的 PV。

用户通过 PVC 请求存储,Kubernetes 会自动将 PVC 和 PV 绑定。PVC 提供了对存储资源的抽象,应用程序无需关心具体的存储实现

绑定过程: 当用户创建一个 PVC 后,Kubernetes 会自动查找一个满足条件的 PV(容量、访问模式等)。 如果找到了合适的 PV,PVC 和 PV 就会绑定在一起。 如果找不到合适的 PV,PVC 会处于“Pending”状态,直到有合适的 PV 出现。

PV配置参考:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs-storage-class
  nfs:
    path: /data/nfs
    server: <nfs-server-ip>

PVC配置参考:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-storage-class

5.2. PV/PVC的生命周期

其实PV 的生命周期和 PVC 的生命周期是分开的,PV 的生命周期与 Pod 无关,即便 Pod 被销毁,PV 中的数据仍然保留。

PV和PVC的整体的生命周期:

图片

5.2.1. PV 的生命周期

创建完成的PV资源可能处于下面四种状态的其中一种,代表着PV资源生命周期的各个阶段

  • 可用状态(Available):当 PV 被创建时,它处于Available状态。此时,PV 可以绑定到 PVC。
  • 已绑定状态(Bound):当 PVC 与 PV 绑定时,PV 会进入Bound状态。此时,PVC 和 PV 之间存在绑定关系,存储已经被分配给 Pod。
  • 回收状态(Released):当 PVC 被删除时,PV 进入Released状态,但存储本身仍然存在,资源尚未被集群回收。
  • 失败(Falied):因自动回收资源失败而处于的故障状态,此时,PV不可用

5.2.2. PVC 的生命周期

  • Pending 状态:PVC 创建后处于 Pending 状态,表示系统正在寻找合适的 PV 来满足 PVC 的请求。
  • Bound 状态:当 PVC 与 PV 成功绑定后,PVC 会进入 Bound 状态,表示存储已经分配给 PVC。
  • Deleted 状态:当 PVC 被删除时,绑定的 PV 进入 Released 状态,存储资源的回收与否取决于 PV 的 ReclaimPolicy

5.2.3. 回收策略

ReclaimPolicy 决定了当 PVC 删除时,PV 的处理方式。常见的回收策略有:

  • Retain:保留 PV,存储资源不会被删除,数据仍然保留,需要管理员手动清理。
  • Delete:删除 PV,相关的存储资源会被删除
  • Recycle:将 PV 中的数据清除(已废弃,不推荐使用)。

5.3. PV 的访问模式

  • ReadWriteOnce (RWO):PV 可以被单个节点的一个 Pod 以读写模式访问。
  • ReadOnlyMany (ROX):多个 Pod 可以以只读模式同时访问 PV。通常用于只读文件共享存储。
  • ReadWriteMany (RWX):多个 Pod 可以以读写模式同时访问 PV。通常用于支持并发读写的网络文件系统(如 NFS、GlusterFS、CephFS)等存储后端。

5.4. 动态存储卷

动态存储卷 是通过 StorageClass 结合 PVC 实现的。

通过 StorageClass,可以实现动态创建 PV,避免手动管理 PV 的麻烦。

当用户创建 PVC 时,Kubernetes 根据指定的 StorageClass 动态创建相应的 PV,而无需管理员手动创建 PV。

动态存储卷使得存储管理更加灵活和自动化。

StorageClass配置参考:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4

StorageClass 参数解释:

  • provisioner:指定存储后端供应器。
  • parameters:可以定义与存储类型相关的参数,

总结:持久化存储特点:

  • 数据在 Pod 销毁时依然存在,数据能够跨 Pod 和节点持久化。
  • 支持多种存储后端,包括云存储、本地存储和分布式文件系统。
  • 提供高可用性和冗余机制,保证数据的持久性和容错能力。
  • 易于备份、恢复和扩展,支持弹性和跨平台迁移。