K8s存储系统(通俗易懂版)

Kubernetes中存储中有四个重要的概念:

Volume、PersistentVolume PV、PersistentVolumeClaim PVC、StorageClass

一、存储系统核心概念
  1. Volume(卷)

    • 定义:Kubernetes 中最基础的存储单元,用于将外部存储挂载到 Pod 中的容器。

    • 特点

      • 生命周期与 Pod 绑定(Pod 删除则 Volume 销毁,但部分类型如 PV 可持久化)。

      • 支持多种存储类型:本地存储(emptyDirhostPath)、网络存储(NFS、CephFS)、云存储(AWS EBS、GCE PD)等。

    • 典型用法

      yaml

      复制代码
      volumes:                   # 定义存储类型
      - name: data
        hostPath:
          path: /mnt/data
      volumeMounts:             # 挂载到容器路径
      - name: data
        mountPath: /app/data
  2. PersistentVolume(PV,持久卷)

    • 定义:集群级别的存储资源(如一块云磁盘、一个 Ceph RBD 镜像),由管理员预先创建。

    • 核心属性

      • capacity:存储容量(如 10Gi)。

      • accessModes:访问模式(单节点读写 ReadWriteOnce、多节点只读 ReadOnlyMany、多节点读写 ReadWriteMany)。

      • persistentVolumeReclaimPolicy:回收策略(保留 Retain、删除 Delete)。

    • 示例

      yaml

      复制代码
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: ceph-pv
      spec:
        capacity: { storage: 10Gi }
        accessModes: [ReadWriteOnce]
        cephfs:
          monitors: ["ceph-mon:6789"]
          path: /data
        storageClassName: ceph-storage
  3. PersistentVolumeClaim(PVC,持久卷声明)

    • 定义:用户对存储资源的"需求清单",声明所需的存储大小、访问模式等,由 Kubernetes 自动绑定到匹配的 PV。

    • 核心属性

      • resources.requests.storage:请求的存储大小(如 5Gi)。

      • storageClassName:指定动态供给的存储类型。

    • 示例

      yaml

      复制代码
      kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: app-data-pvc
      spec:
        accessModes: [ReadWriteOnce]
        resources:
          requests:
            storage: 5Gi
        storageClassName: ceph-storage
  4. StorageClass(存储类)

    • 定义:动态供给的模板,定义如何按需创建 PV(例如自动创建云盘或 Ceph RBD 镜像)。

    • 核心属性

      • provisioner:存储驱动(如 kubernetes.io/aws-ebs)。

      • parameters:存储后端参数(如 Ceph 集群地址)。

    • 示例

      yaml

      复制代码
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: ceph-rbd
      provisioner: kubernetes.io/rbd
      parameters:
        monitors: ceph-mon:6789
        adminId: admin
        pool: kube

1、工作流程对比
静态供给:

管理员创建PV → 用户创建PVC → 系统绑定PV/PVC → Pod使用PVC
动态供给:

用户创建PVC → StorageClass自动创建PV → 系统绑定 → Pod使用PVC

二、核心流程对比
  1. 静态 PV 工作流程

    • 步骤

      1. 管理员创建 PV(如 Ceph RBD 镜像)。

      2. 用户创建 PVC,声明存储需求。

      3. Kubernetes 将 PVC 绑定到匹配的 PV。

      4. Pod 挂载 PVC。

    • 痛点:需人工维护大量 PV,存储扩容需手动操作。

  2. 动态 PV 工作流程

    • 步骤

      1. 管理员创建 StorageClass(定义存储类型)。

      2. 用户创建 PVC,指定 StorageClass。

      3. Kubernetes 自动创建 PV 并绑定 PVC。

      4. Pod 挂载 PVC。

    • 优势:自动化创建存储资源,适合云环境弹性需求。

如果还不清晰,这里用租房子的比喻来解释这四个概念和两种供给模式,再配上实际流程,保证通俗易懂。

三、核心概念和流程比喻(通俗版):

想象你要租房子(需要存储空间):

  1. Volume (卷): 就像你最终拿到手的房子钥匙和门牌号。它定义了具体的存储位置(地址)和如何挂载到你的应用(Pod)里使用(钥匙)。Volume 是 Pod 的一部分配置。

  2. PersistentVolume (PV, 持久卷): 就像城市里可出租的实体房子资源。这些房子是由物业公司(集群管理员)提前建好(配置好)并登记在册的。每套房子(PV)有明确的属性:

    • 大小 (capacity): 比如 80 平米(100Gi)。

    • 访问规则 (accessModes): 是只能一个人住(单节点读写 ReadWriteOnce),还是可以很多人参观但不能住(多节点只读 ReadOnlyMany),或者可以合租(多节点读写 ReadWriteMany)。

    • 地段/特性 (storageClassName): 属于哪个小区、是公寓还是别墅(存储类型,比如 fast-ssd, ceph-rbd)。

    • 退租处理 (persistentVolumeReclaimPolicy): 租客退租后,房子是保留原样等人再租(Retain),还是清空重新装修(旧模式 Recycle,已基本不用),或是直接拆掉(Delete)。

  3. PersistentVolumeClaim (PVC, 持久卷声明): 就像你提交给租房中介的一份租房需求清单。你告诉中介(Kubernetes 系统):

    • 我要多大 (resources.requests.storage): 至少 60 平米(5Gi)。

    • 我要怎么用 (accessModes): 我一个人住要能做饭洗澡(ReadWriteOnce)。

    • 我想租哪种类型 (storageClassName): 我想要交通方便的公寓(比如 fast-ssd)。

  4. StorageClass (SC, 存储类): 就像一个高效的房屋建造和管理中介公司。它定义了:

    • 我们能提供什么类型的房子 (provisioner): 比如"快速公寓建造公司"(kubernetes.io/aws-ebskubernetes.io/gce-pd, rbd.csi.ceph.com)。

    • 房子的默认配置 (parameters): 比如默认精装修、带电梯(存储后端的具体参数,如 Ceph 集群地址、池名)。

    • 我们的服务规则 : 比如先签合同再建房(WaitForFirstConsumer,等 Pod 调度好再创建 PV),或者有现房(立即创建)。

它们之间的关系:

  • PVC 绑定 PV: 你的租房需求清单 (PVC) 会被中介 (Kubernetes) 拿去匹配现成的房子 (PV)。如果找到大小、类型、访问规则都满足的房子,就把这套房子分配给你(绑定)。Pod 不能直接租房子 (PV),必须通过你的需求清单 (PVC) 来租。

  • SC 动态创建 PV: 如果中介 (Kubernetes) 发现没有现成的房子 (PV) 能满足你的需求清单 (PVC),并且你的清单里指定了要找某个房屋建造中介公司 (StorageClass),那么中介公司 (SC) 就会立刻根据你的需求清单 (PVC) 自动建造一套新房子 (PV),然后中介 (Kubernetes) 再把这套新房分配给你 (绑定 PVC 和 PV)。

  • Pod 使用 Volume: 当你 (Pod) 要入住时,中介 (Kubernetes) 会告诉你具体的门牌号和给你钥匙 (Volume)。你 (Pod) 在配置里写明"我要用清单A对应的房子" (引用 PVC 名字),系统就会自动把对应的门牌号和钥匙 (Volume) 配置给你,你就可以搬进去住(把存储挂载到容器里指定路径)了。


静态供给流程 (管理员提前造好房子):

  1. 管理员造房 (创建 PV): 集群管理员像物业公司,提前在存储后端(如 NFS 服务器、Ceph 集群)准备好"房子"(存储空间),并在 Kubernetes 里创建 PersistentVolume (PV) 对象来描述这些房子(大小、访问模式、地址等)。

    • 例子: 管理员在 Ceph 里创建了一个 100GB 的 RBD 镜像 image-db,然后创建 PV:

      yaml

      复制代码
      apiVersion: v1
      kind: PersistentVolume
      metadata:
        name: pv-ceph-db-100g # 房子名字:Ceph数据库房100G
      spec:
        capacity:
          storage: 100Gi # 大小:100平米
        accessModes:
          - ReadWriteOnce # 访问规则:单租客可读写
        cephfs: # 或者 rbd: 取决于类型
          monitors:
            - 10.0.0.1:6789 # Ceph 监控地址
          path: /data/db # 具体路径 / 池和镜像名
          user: admin
          secretRef:
            name: ceph-secret
        persistentVolumeReclaimPolicy: Retain # 退租处理:保留原样
        storageClassName: ceph-slow # 地段/类型:Ceph普通盘区
  2. 用户提交需求 (创建 PVC): 开发者(用户)编写应用部署文件 (如 deployment.yaml),在里面声明需要一个 PersistentVolumeClaim (PVC)。

    • 例子: 应用需要 80GB 数据库存储,单节点读写。

      yaml

      复制代码
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: pvc-mysql-data # 我的需求清单名字:MySQL数据需求
      spec:
        accessModes:
          - ReadWriteOnce # 我要单租客可读写
        resources:
          requests:
            storage: 80Gi # 我要至少80平米
        storageClassName: ceph-slow # 我想租Ceph普通盘区的房子 (可选,如果指定必须匹配PV的class)
  3. 系统匹配房源 (绑定 PV & PVC): Kubernetes 系统(中介)看到 PVC 需求后,在现成的 PV(房子)里找:

    • 大小满足:PVC 要 80Gi,PV 有 100Gi (80 <= 100,满足)。

    • 访问模式匹配:都是 ReadWriteOnce

    • 存储类匹配:如果 PVC 指定了 ceph-slow,PV 也必须是 ceph-slow;如果 PVC 没指定,则匹配没有存储类或任意存储类的 PV(但通常建议明确指定)。

    • 找到后,系统将 PV 和 PVC 绑定 (Bound) 。PV 的状态从 Available 变成 Bound

  4. 用户入住 (Pod 挂载 Volume): 用户创建 Pod(比如 MySQL 数据库 Pod)。在 Pod 的配置里:

    • 声明要使用哪个 PVC (pvc-mysql-data)。

    • 指定把存储挂载到容器里的哪个路径 (/var/lib/mysql)。

    yaml

    复制代码
    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql-pod
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          volumeMounts:
            - name: mysql-storage # 给这个挂载起个名字
              mountPath: /var/lib/mysql # 容器内的挂载点
      volumes:
        - name: mysql-storage # 上面挂载名字对应的存储定义
          persistentVolumeClaim:
            claimName: pvc-mysql-data # 使用之前申请的PVC
  5. Pod 运行: Kubernetes 调度 Pod 到某个 Node 上运行。该 Node 上的 kubelet 组件负责:

    • 根据 PVC 找到已绑定的 PV。

    • 根据 PV 的描述(如 Ceph RBD),联系对应的存储系统(Ceph 集群),获取访问权限(挂载)。

    • 将存储挂载到 Node 上的一个临时目录。

    • 将这个临时目录映射(挂载)到 Pod 中容器指定的路径 (/var/lib/mysql)。

    • 应用启动,读写 /var/lib/mysql 就是在读写持久化的 Ceph 存储。

动态供给流程 (中介按需快速建新房):

  1. 管理员找中介公司 (创建 StorageClass): 集群管理员提前 创建一个或多个 StorageClass (SC) 对象。这相当于引入了几家不同风格的房屋建造中介公司,每家公司专长不同(AWS EBS, GCP PD, Ceph RBD, NFS Provisioner 等)。

    • 例子: 创建一个负责快速建造 Ceph RBD "公寓"的中介公司:

      yaml

      复制代码
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: ceph-rbd-fast # 中介公司名:Ceph快速公寓建造
      provisioner: rbd.csi.ceph.com # 建造公司类型:Ceph RBD CSI 驱动 (现代标准)
      parameters: # 建造公司的默认配置
        clusterID: my-ceph-cluster # Ceph集群ID
        pool: kube-pool-fast # 用哪个池建房
        imageFeatures: layering,exclusive-lock # 房子特性
        csi.storage.k8s.io/provisioner-secret-name: ceph-csi-secret
        csi.storage.k8s.io/provisioner-secret-namespace: kube-system
      reclaimPolicy: Delete # 默认退租处理:拆掉房子 (可选 Retain)
      volumeBindingMode: WaitForFirstConsumer # 服务规则:等租客确定住哪再建房 (避免建错位置)
  2. 用户提交需求 (创建 PVC 并指定 SC): 开发者(用户)编写 PVC,这次明确指定要找哪家中介公司 (StorageClass) 来满足需求。

    • 例子: 应用需要 200GB 高速数据库存储,单节点读写,找 ceph-rbd-fast 公司建房。

      yaml

      复制代码
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: pvc-mongodb-data # 需求清单:MongoDB数据
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 200Gi # 要200平米
        storageClassName: ceph-rbd-fast # 必须指定:找Ceph快速公寓建造公司!
  3. 中介公司立刻建房 (动态创建 PV): Kubernetes 系统(平台)看到 PVC 指定了 ceph-rbd-fast 这个 StorageClass。

    • 系统会调用 ceph-rbd-fast 这个 SC 里定义的 provisioner (Ceph RBD CSI 驱动)。

    • CSI 驱动收到指令:"按 PVC 要求(200Gi, RWO)建一套新房!"

    • CSI 驱动联系 Ceph 集群后端

      • 在指定的 kube-pool-fast 池里创建一个新的 RBD 镜像 (image),大小 200GB。

      • 在 Kubernetes 里自动创建一个对应的 PersistentVolume (PV) 对象来描述这个新建的 RBD 镜像。

    • 新建的 PV 的 storageClassName 自动设置为 ceph-rbd-fast

    • 系统自动将这个新建的 PV 与发起请求的 PVC 绑定 (Bound) 。PVC 的状态直接变成 Bound

  4. 用户入住 (Pod 挂载 Volume): 和静态流程完全一样!用户创建 Pod,声明使用 PVC pvc-mongodb-data,并指定容器内的挂载点。Kubernetes 调度 Pod 并完成挂载。

核心区别总结:

特性 静态供给 (Static Provisioning) 动态供给 (Dynamic Provisioning)
PV 创建者 管理员手动创建 StorageClass (通过 Provisioner) 自动创建
创建时机 在 PVC 出现之前 预先创建好 PV 在 PVC 出现之后,响应 PVC 请求即时创建 PV
运维负担 。管理员需预估需求,提前创建、管理大量 PV。 。管理员只需配置好 StorageClass,PV 按需创建。
灵活性 。扩容麻烦(需手动操作 PV 和存储后端)。 。PVC 修改大小可能触发自动扩容(需存储后端和 SC 支持)。
适用场景 存储需求固定、明确;特殊存储配置;不支持动态供给的存储。 云环境、容器化平台主流方式;存储需求弹性大;追求自动化。
关键组件 PV, PVC StorageClass, PVC, (自动创建的 PV)
比喻 管理员提前建好一批毛坯房/精装房放在市场上。 引入中介公司,用户提交需求单,中介按需快速建好精装房交付。

为什么动态供给是趋势?

  1. 自动化: 省去了管理员手动管理 PV 的巨大工作量。

  2. 按需分配: 避免资源闲置浪费(静态供给往往需要预先分配较大的 PV)。

  3. 敏捷性: 开发者只需关心 PVC 需求,无需等待管理员操作,加速应用部署。

  4. 云原生: 完美契合 Kubernetes 声明式 API 和弹性伸缩的理念。

作为小白,记住关键点:

  • Pod 用 Volume 访问存储。

  • 持久化存储要用 PV 和 PVC。

  • PV 是"房子",PVC 是"租房需求单"。

  • 静态供给:管理员提前造好 PV (房子) 等 PVC (需求单) 来租。

  • 动态供给:PVC (需求单) 指定 StorageClass (中介公司),中介公司立刻造好 PV (房子) 并租给你。

  • 生产环境强烈推荐用动态供给!

相关推荐
IT成长日记1 小时前
【Docker基础】Dockerfile多阶段构建:Multi-stage Builds详解
运维·docker·容器·multi-stage·builds
BUTCHER57 小时前
Docker镜像使用
java·docker·容器
澜兮子7 小时前
k8s-高级调度(一)
云原生·容器·kubernetes
无敌糖果7 小时前
K8S的Helm包管理器
docker·容器·kubernetes·helm·helm安装包
筱小虾米8 小时前
Docker配置国内镜像源
运维·docker·容器
爱吃芝麻汤圆8 小时前
k8s之Snapshots 详解
云原生·容器·kubernetes
开挖掘机上班10 小时前
基于Alpine构建MySQL镜像
mysql·docker·容器
todoitbo11 小时前
docker搭建freeswitch实现点对点视频,多人视频
docker·容器·音视频·freeswitch·视频聊天
William一直在路上12 小时前
回顾一下Docker的基本操作
docker·容器·eureka