想象你在一家大型互联网公司的 AI 训练团队工作。每位同事都像“临时工”——工位不固定,电脑里的资料随时会被清空。今天你花 3 天时间训练了一个 20GB 的大模型,如果服务器一重启、工位一撤,所有进度瞬间归零,那种崩溃感谁能承受? 于是公司后勤部设计了“储物柜系统”:仓库里放着实体柜子(PV),员工填写申请单说明自己的需求(PVC),后勤根据申请单自动分配一个大小合适的柜子(StorageClass 动态供给)。有的柜子是个人专属抽屉(本地盘),有的柜子是部门共享文件柜(NFS),还有的是能自动扩容的智能仓储(Ceph)。用完柜子之后,还要决定是原样保留(Retain)、直接清空(Delete),还是重新粉刷给下一个人(Recycle)。 这套系统,就是 Kubernetes 中的持久化存储体系。它保证了 AI 训练任务在节点宕机、Pod 重建后依然能恢复数据,是云原生 AI 基础设施的地基。理解了它,就理解了有状态应用如何在 Kubernetes 上稳稳落地。

岗位关联

持久化存储是 AI 训练与推理落地的“保命符”,掌握 PV/PVC/StorageClass 是 Kubernetes 进阶工程师的必备技能,也是 AI 基础设施团队的核心职责之一。

目录
  1. 可视化演示
  2. 容器存储局限
  3. PV与PVC解耦
  4. StorageClass动态供给
  5. 访问模式选择
  6. 回收策略
  7. 存储后端选型
  8. AI实践与调优
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

容器存储局限

回到我们那个“全员临时工”的公司。你每天来上班,打开电脑,发现桌面上空空如也——因为你的账户在昨天下班时被重置了。容器就是这样一种“用完即弃”的运行环境。Kubernetes 中的 Pod 是调度的最小单元,它随时可能因节点故障、版本升级、资源不足而被删除或重建。只要问题一发生,Pod 内容器写入的文件系统数据就会跟着消失。

在这个背景下,AI 训练任务的痛点尤其明显:一份 20GB 的模型权重,训练了三天三夜,结果节点一重启,一切归零。Kubernetes 也不是没有临时存储方案,比如 emptyDir,它就像是工位抽屉里的一张便签纸——节点还在便签纸就在,Pod 一删便签纸就被保洁阿姨收走了。对无状态应用来说这没问题,但对需要保存训练进度、缓存数据集的 AI 任务来说,这远远不够。

于是 Kubernetes 设计了一套“数据搬家”机制:把数据从容器生命周期中剥离出来,放到独立的存储单元中。这个独立存储单元生命周期由管理员和存储系统管理,与 Pod 无关。这就像公司建立了固定的储物柜仓库——柜子不受你工位变动的影响,你离职了柜子还在,下一个人还能用。

所以,AI 基础工程的第一步,就是认识到容器存储的“临时工属性”,进而寻找真正持久的存储方案——这正是 PV 与 PVC 登场的理由。没有这个认知,后续一切存储设计都是空中楼阁。

Pod删除⟶数据丢失(emptyDir 临时卷)\displaystyle \text{Pod}_{\text{删除}} \longrightarrow \text{数据}_{\text{丢失}} \quad (\text{emptyDir 临时卷})
  1. Pod 删除Pod 被 kubectl delete 删除或节点驱逐导致重建,这是 Kubernetes 里的常态。
    Pod删除\text{Pod}_{\text{删除}}
  2. 数据丢失emptyDir 卷中的文件随 Pod 生命周期结束而被系统清理,没有任何备份。
    数据丢失\text{数据}_{\text{丢失}}
  3. 临时卷标注emptyDir 是典型的临时存储,只适合缓存、日志等可丢数据,绝对不能放模型权重。
    (emptyDir 临时卷)(\text{emptyDir 临时卷})

PV与PVC解耦

公司决定为临时工们配备固定储物柜,但没有让员工直接去仓库搬柜子,而是设计了一套“申请单制度”。这个制度有两个核心角色:PV(PersistentVolume) 是仓库里真实的实体柜,由管理员预先准备好,有明确的容量、访问权限和位置信息;PVC(PersistentVolumeClaim) 则是你填写的储物需求单,上面写着“我需要一个能装下 20GB 资料的柜子,要能同时让 4 个同事访问”。

为什么不直接把 PV 给用户用?因为需求方与资源方要解耦。业务团队不一定知道底层存储是什么型号、在哪个机架上,他们只关心自己的需求是否被满足。PV 与 PVC 分离后,开发者只需写 PVC,Kubernetes 会自动寻找满足条件的 PV 完成绑定。这就像你去行政部申请办公用品,不需要知道仓库在哪、供应商是谁,只要拿着审批单就能领到东西。

绑定关系不是胡乱配对的,它需要满足几个约束条件。首先,PV 的容量必须不小于 PVC 请求的容量;其次,PV 支持的访问模式必须覆盖 PVC 要求的访问模式;最后,如果 PVC 指定了 StorageClass,那 PV 的 StorageClass 也必须一致。三个条件同时满足,Kubernetes 才会在两者之间建立绑定关系。

这套“需求单与实体柜解耦”的设计,让存储的消费方(业务团队)和生产方(平台团队)各司其职。业务团队不再关心底层存储细节,平台团队也能统一管理存储资源。就像公司里行政部统一采购、统一分配,效率提升不止一个量级。

bind(PVC,PV)  ⟺  cap(PV)≥req(PVC)∧modes(PVC)⊆modes(PV)\displaystyle \text{bind}(\text{PVC}, \text{PV}) \iff \text{cap}(\text{PV}) \ge \text{req}(\text{PVC}) \wedge \text{modes}(\text{PVC}) \subseteq \text{modes}(\text{PV})
  1. 绑定成立条件 bind(PVC, PV)左右两侧同时成立,绑定关系才建立,缺一不可。
    bind(PVC,PV)  ⟺  \text{bind}(\text{PVC}, \text{PV}) \iff
  2. 容量约束 cap(PV) ≥ req(PVC)柜子至少要能装下申请单要求的容量,只能大不能小。
    cap(PV)≥req(PVC)\text{cap}(\text{PV}) \ge \text{req}(\text{PVC})
  3. 访问模式约束 modes(PVC) ⊆ modes(PV)PVC 请求的访问模式集合必须是 PV 支持集合的子集。
    modes(PVC)⊆modes(PV)\text{modes}(\text{PVC}) \subseteq \text{modes}(\text{PV})

StorageClass动态供给

有了 PV 和 PVC,新的问题来了:如果 PVC 提交时,仓库里没有正好满足条件的 PV 怎么办?传统做法是管理员预估未来的存储需求,提前把一批 PV 手动创建好。这就像后勤部提前买了 100 个柜子,结果发现大家申请的都是不同尺寸,要么装不满要么放不下,造成大量浪费。

Kubernetes 的解法是引入 StorageClass——一个“自动定做柜子”的智能系统。开发者使用 PVC 时,如果指定了 storageClassName,系统就会查看对应的 StorageClass 配置,在 StorageClass 中找到一个叫 provisioner 的存储插件,由它调用后端存储接口(如 NFS、云盘、Ceph),实时创建一个全新的 PV,然后自动与 PVC 完成绑定。整个过程不需要管理员提前准备任何实体柜。

一个 StorageClass 可以配置多个参数:后端类型(provisioner)、磁盘性能档位(如 SSD 或 HDD)、回收策略(reclaimPolicy)等。如果集群中有多个 StorageClass,管理员还可以设置一个 storageclass.kubernetes.io/is-default-class: "true" 标注的默认存储类,这样那些不指定 storageClassName 的 PVC 会自动使用默认类,就像公司默认给所有新员工配一台标准规格的电脑。

动态供给让存储资源真正变成了“按需付费”的云服务。你提交申请单,后台自动帮你定做一个尺寸刚好的新柜子,既不用等审批,也不会浪费空间。这也是云原生时代存储管理的核心范式。

PV动态=Provisioner(SC参数,PVC声明)\displaystyle \text{PV}_{\text{动态}} = \text{Provisioner}\left(\text{SC}_{\text{参数}}, \text{PVC}_{\text{声明}}\right)
  1. 动态 PV 结果等式左边是最终自动创建出来的持久化卷,专为本次申请生产。
    PV动态\text{PV}_{\text{动态}}
  2. Provisioner 工厂StorageClass 中配置的存储插件,负责与底层存储系统通信并创建资源。
    Provisioner\text{Provisioner}
  3. SC 参数StorageClass 中定义的磁盘类型、回收策略、挂载选项等配置。
    SC参数\text{SC}_{\text{参数}}
  4. PVC 声明用户提交的容量、访问模式等需求信息,作为定做柜子的输入依据。
    PVC声明\text{PVC}_{\text{声明}}

访问模式选择

柜子做好了,还得决定“谁能用、怎么用”。Kubernetes 的 PV 支持三种访问模式,对应生活中不同类型的柜子。ReadWriteOnce(RWO) 就像你工位旁的专属抽屉——只有一个员工能打开,既能读也能写,其他任何人碰不了。ReadOnlyMany(ROX) 就像公司前台的产品展示柜——很多人可以凑过来围观,但谁都不能往里放东西。ReadWriteMany(RWX) 则像部门公共的文件共享柜——大家都能打开,也都能往里投稿。

选择访问模式,直接决定了存储后端能否满足需求。比如云硬盘(阿里云盘、AWS EBS)通常只支持 RWO,因为云厂商的块存储技术不允许同时挂载到多台虚拟机;而 NFS 和 CephFS 这类文件系统天然支持 RWX,因为它们本身就是为多客户端共享设计的网络文件协议。如果你给模型推理服务选了只支持 RWO 的云盘,那就意味着所有副本只能串行挂载,根本无法水平扩展。

一个关键技巧是:PVC 请求的访问模式集合,必须是 PV 支持模式集合的子集——这一点我们之前讲绑定条件时也提到了。举个例子,一个支持 ["RWO", "RWX"] 的 NFS 卷,既能满足单节点读写型任务(RWO),也能满足多节点共享型任务(RWX),灵活度很高。

访问模式的选择直接决定了你的 AI 应用能怎样使用存储。训练任务通常希望独占读写(RWO)保证性能稳定,而分布式推理和数据分析则希望共享读写(RWX)。理解每把“锁”的规则,才能在申请单上填对需求。

MPVC⊆MPV\displaystyle M_{\text{PVC}} \subseteq M_{\text{PV}}
  1. MPVC 请求模式集合PVC 中声明的访问模式,如 {“RWO“} 或 {”RWX”}。
    MPVCM_{\text{PVC}}
  2. MPV 支持模式集合PV 实际支持的访问模式集合,由底层存储能力决定。
    MPVM_{\text{PV}}
  3. 子集关系请求的模式必须全部被 PV 支持,否则无法绑定。
    ⊆\subseteq

回收策略

柜子用完了,人走了,柜子怎么办?这就是回收策略要回答的问题。Kubernetes 中的 PV 有三种回收策略,对应三种不同的“善后流程”。Retain(保留) 是“原样保留”——PVC 删除后,PV 依然存在,里面的数据纹丝不动,等待管理员亲自处理。这就像重要员工离职后,他的柜子被贴上封条,等 HR 和行政逐项清点。

Delete(删除) 则是“自动销毁”——PVC 删除后,PV 连同底层存储资源一起被删除,数据立即释放。这像普通员工离职当天,行政直接清空柜子并回收再利用,高效但不可逆。Recycle(回收) 是 Kubernetes 早期版本中的另一种策略,运行 rm -rf 清空数据后把 PV 放回资源池供下一个人绑定。但由于安全性和效率问题,Recycle 已被标记为废弃,不再推荐使用。

如何选择回收策略?核心看数据价值。如果你的 PVC 里存的是训练中间产物,删了就删了,用 Delete 最省心;如果存的是需要审计的模型版本或者合规要求高的数据,一定要选 Retain,避免误删。实践中很多团队会把“数据管道临时存储”用 Delete,把“模型仓库”用 Retain,做到敏捷与安全兼得。

回收策略是数据安全的最后一道闸门。它决定了“柜子里的东西”在 PVC 删除后是留下、销毁还是翻新。对 AI 基础设施团队来说,为每类业务数据选择正确的回收策略,是一项必须写进部署规范的基本功。

回收结果={Retain⇒保留 PV 与底层数据Delete⇒删除 PV 与底层存储Recycle⇒清理数据后归还资源池\displaystyle \text{回收结果} = \begin{cases}\text{Retain} \Rightarrow \text{保留 PV 与底层数据} \\\text{Delete} \Rightarrow \text{删除 PV 与底层存储} \\\text{Recycle} \Rightarrow \text{清理数据后归还资源池}\end{cases}
  1. Retain 保留分支PV 存续,但不再自动绑定给其他 PVC,等待管理员下一步操作。
    Retain⇒保留 PV 与底层数据\text{Retain} \Rightarrow \text{保留 PV 与底层数据}
  2. Delete 删除分支PV 被删除,底层存储卷同步释放,数据彻底消失。
    Delete⇒删除 PV 与底层存储\text{Delete} \Rightarrow \text{删除 PV 与底层存储}
  3. Recycle 废弃分支历史上用于数据清理后复用,现已被 Kubernetes 官方废弃。
    Recycle⇒清理数据后归还资源池\text{Recycle} \Rightarrow \text{清理数据后归还资源池}

存储后端选型

柜子制度说清楚了,接下来看仓库里到底放哪些柜子。Kubernetes 本身不存储数据,它通过 CSI(容器存储接口)对接各种后端存储。常见的三大类分别是 NFS、Ceph 和本地盘/云盘,它们各有各的脾气。

NFS 是最简单的网络共享存储,像公司楼层的公共文件柜:配置简单、上手快,天然支持多节点同时读写(RWX),中小团队的文件共享、模型目录、checkpoint 存储都能胜任。但它的性能受限于单台 NFS 服务器,并发一高就可能成为瓶颈。

Ceph 则是分布式存储中的“大型智能仓库”:数据被切成多份分散存储在多个节点上,自带冗余与自动修复能力,可以横向扩展到 PB 级,也支持 RWO/RWX 多种模式。大规模 AI 生产环境常常选择 Ceph,因为它能同时支撑数百个 GPU 节点的并发读写。缺点是运维复杂度高,需要专门的存储团队维护。

本地盘 像是你工位旁的高速抽屉:性能极佳、延迟最低,但数据存储在本机磁盘上,节点一挂数据就没了,没有任何冗余。云盘(如阿里云 ESSD、AWS EBS)则是云厂商提供的虚拟块存储,可靠性比本地盘高,但通常只支持 RWO,无法多节点共享。

选型没有标准答案,只有“权衡”。AI 基础设施工程师的日常,就是在这三个维度之间做取舍:要性能选本地盘,要共享选 NFS,要规模和可靠选 Ceph。就像采购经理要根据预算、部门人数和重要程度来决定买哪种柜子一样。

Score=wp⋅Perf+wa⋅Avail+wc⋅Cost\displaystyle \text{Score} = w_p \cdot \text{Perf} + w_a \cdot \text{Avail} + w_c \cdot \text{Cost}
  1. Score 综合评分对存储后端进行选型打分的总分,用于量化对比。
    Score\text{Score}
  2. Perf 性能项吞吐量、IOPS、延迟等性能指标,训练场景权重最高。
    wp⋅Perfw_p \cdot \text{Perf}
  3. Avail 可用性数据冗余、故障自愈能力,生产环境的关键指标。
    wa⋅Availw_a \cdot \text{Avail}
  4. Cost 成本项每 GB 单价与运维人力成本,预算有限时权重上升。
    wc⋅Costw_c \cdot \text{Cost}

AI实践与调优

掌握了 PV/PVC/StorageClass 这套体系,再来看 AI 场景中的落地实践就会豁然开朗。

第一个典型场景是模型 checkpoint 保存。 大模型训练动辄数天甚至数周,必须周期性保存模型权重和优化器状态到持久化存储。推荐方案是使用 NFS 或 Ceph 的共享卷(RWX),让所有训练 Pod 都能写入同一个 checkpoint 目录。训练节点宕机后,新的 Pod 拉起时直接从共享卷加载最新 checkpoint 继续训练,损失最多一个保存间隔的进度。这也引出了一个性能公式:checkpoint 越大、存储带宽越低,恢复训练需要的时间就越长。

第二个场景是数据管道的临时存储。 数据清洗、预处理、格式转换这类 ETL 任务,产生的中间数据用完即弃。此时使用 StorageClass + 回收策略为 Delete 的 PVC,任务跑完删除 PVC 后底层存储自动释放,既不用人工清理,也不浪费存储成本。

第三个调优思路是容量与性能的预规划。 在 StorageClass 中,通过 parameters 指定云盘类型(如 SSD 或 ESSD),或为 Ceph 设置数据池与副本数,直接影响训练数据加载的速度。调优原则是:高吞吐数据集放高性能存储,低频访问的归档数据放低成本存储。

回到公司储物柜的比喻:AI 团队的柜子体系建好了——checkpoint 存在共享柜里,临时数据用一次性柜子,高价值版本锁在保留柜里。Kubernetes 的持久化存储,让“临时工”也能安心地做长期事业。

T恢复=ScheckpointB存储\displaystyle T_{\text{恢复}} = \frac{S_{\text{checkpoint}}}{B_{\text{存储}}}
  1. T 恢复时间从 checkpoint 恢复到可继续训练所需的总时间。
    T恢复T_{\text{恢复}}
  2. S checkpoint 大小模型权重、优化器状态等快照数据的总大小。
    ScheckpointS_{\text{checkpoint}}
  3. B 存储带宽存储系统提供的读取吞吐量,NFS 受单机网卡限制,Ceph 可横向扩展。
    B存储B_{\text{存储}}

AI 应用场景

大模型分布式训练 Checkpoint

阶段:模型训练与容错恢复

解决的问题:传统方式下,训练进程所在 Pod 崩溃后,数天算力成果全部丢失;使用共享持久化卷后,训练损失最多一个 checkpoint 保存周期,整体恢复时间可量化预估。

具体案例:一个 70B 参数的大语言模型训练集群,40 张 GPU 分布在多个节点上,每个训练进程每 5 分钟向 NFS 共享卷写入一次 checkpoint。某天一个节点因硬件故障下线,Kubernetes 自动在新的节点上拉起训练 Pod,Pod 启动时从共享卷读取最新 checkpoint,2 分钟内恢复训练,集群整体损失仅为 5 分钟算力。

数据管道与特征工程中间存储

阶段:数据准备与预处理

解决的问题:数据处理任务会产生大量中间文件,传统做法是留在本地磁盘,难以跨节点调度且占用大量节点空间;使用临时 PVC 后,任务输出自动写入持久化卷,任务结束即释放,存储成本精准可控。

具体案例:某公司的特征工程流水线每天处理 10TB 原始日志。平台组为该流水线配置了 StorageClass,回收策略为 Delete,storageClassName: data-pipeline-sc。每天凌晨任务启动时动态创建一个 2TB 的 PV,处理完成后删除 PVC,底层存储自动释放,次日重新动态创建,无需人工干预。

模型推理服务多副本共享模型

阶段:模型部署与在线推理

解决的问题:部署多个推理副本来水平扩容时,每个副本都需要加载同一个模型文件;若各自复制一份到本地,版本不一致且浪费空间;使用 ReadOnlyMany 共享卷后,所有副本读同一份模型文件,版本天然一致。

具体案例:在 Kubernetes 集群中部署一个推理服务,3 个 Pod 副本共同挂载一个 CephFS 的 PV,访问模式为 ReadOnlyMany,路径指向 /models/sentiment-v3/。模型更新时只需替换共享卷中的文件,无需逐一分发到每个副本。

Python 演示

python70 行
"""StorageClass 动态供给模拟器模拟 PV/PVC 绑定与 StorageClass 动态创建 PV 的完整流程""" PV_POOL = [    {"name": "nfs-001", "capacity": 500, "modes": {"RWO", "RWX"},     "sc": "slow", "status": "free"},    {"name": "local-002", "capacity": 100, "modes": {"RWO"},     "sc": "fast", "status": "free"},]  def try_bind(pvc, pool):    """尝试将 PVC 绑定到现有空闲 PV"""    for pv in pool:        if pv["status"] != "free":            continue        if pv["capacity"] < pvc["capacity"]:            continue        if not pvc["modes"].issubset(pv["modes"]):            continue        if pvc.get("sc") and pv["sc"] != pvc["sc"]:            continue        pv["status"] = "bound"        return pv, "静态绑定成功"    return None, "无匹配 PV, 转动态供给"  def dynamic_provision(pvc, sc_map):    """模拟 StorageClass 动态创建 PV"""    sc = sc_map.get(pvc.get("sc", ""))    if not sc:        return None, "未找到 StorageClass, 绑定失败"    new_pv = {        "name": pvc["name"] + "-pv",        "capacity": pvc["capacity"],        "modes": pvc["modes"],        "sc": pvc["sc"],        "status": "bound",    }    return (new_pv,            "动态创建成功, 使用 provisioner: " + sc["provisioner"])  def main():    sc_map = {        "fast": {"provisioner": "local.csi.k8s.io", "reclaim": "Delete"},        "slow": {"provisioner": "nfs.csi.k8s.io", "reclaim": "Retain"},    }    pvc_list = [        {"name": "ai-checkpoint", "capacity": 800,         "modes": {"RWX"}, "sc": "slow"},        {"name": "train-cache", "capacity": 80,         "modes": {"RWO"}, "sc": "fast"},        {"name": "extra-data", "capacity": 300,         "modes": {"RWO"}, "sc": "slow"},    ]    for pvc in pvc_list:        pv, msg = try_bind(pvc, PV_POOL)        if pv is None:            pv, msg = dynamic_provision(pvc, sc_map)        if pv:            PV_POOL.append(pv)        print(f"PVC {pvc['name']}: {msg}, 最终 PV 为 "              f"{pv['name']} 容量 {pv['capacity']}G")  if __name__ == "__main__":    main()
目的:用 60 行 Python 模拟 Kubernetes 中 PVC 先匹配现有 PV、匹配不到则由 StorageClass 动态创建新 PV 的完整流程,帮助理解存储供给的核心逻辑。
  1. PV_POOL模拟集群中已存在的 PV 资源池,每个 PV 记录容量、访问模式、所属 StorageClass 和绑定状态。
  2. try_bind(pvc, pool)模拟“静态供给”:遍历空闲 PV,检查容量、访问模式、存储类三个绑定约束。
  3. if not pvc["modes"].issubset(pv["modes"]):关键约束:PVC 请求的访问模式集合必须是 PV 支持集合的子集。
  4. pv, msg = try_bind(pvc, PV_POOL)先尝试复用现有 PV,找不到才转向动态供给。
  5. dynamic_provision(pvc, sc_map)模拟“动态供给”:从 sc_map 中查找 StorageClass,调用其 provisioner 创建新 PV。
  6. pv["status"] = "bound"PV 一旦与 PVC 绑定,即被标记为已占用,不会再分配给其他 PVC。

常见误区

误区我删除了 PVC 和 Pod,那 PV 应该也被自动删除,底层存储的数据也没了,不用再清理。

正解PVC 删除后 PV 的去向完全取决于 PV 的回收策略。只有 Delete 策略会在 PVC 删除时同步删除 PV 和底层存储;如果是 Retain,PV 会保留,数据原封不动,且 PV 变为 Released 状态,等待管理员手动处理。这就好比离职时柜子会不会被清空,要看行政部的“柜子善后规则”,而不是看你自己是否交了钥匙。

为何常见:很多容器平台的默认行为是“删除即释放”,加上初学者很少操作 Retain 策略,容易形成刻板印象。

误区每个 PVC 都必须指定 `storageClassName`,否则无法创建或绑定。

正解PVC 不指定 storageClassName 时,如果集群中存在带 is-default-class 标注的默认 StorageClass,则自动使用它;如果没有默认类,PVC 也能通过“静态供给”方式绑定到管理员预先创建的 PV 上。StorageClass 只是在没有现成 PV 时提供“自动定做柜子”的便利,并非必需品。

为何常见:云厂商的托管 Kubernetes 集群几乎都会配置默认 StorageClass,使用者的 PVC 总是不写类名也能动态创建,于是误以为这是必须的。

误区NFS 是一种网络块存储,和云硬盘一样,只能被一个节点挂载读写。

正解NFS 是网络文件系统(Network File System),提供的是文件级共享访问,天然支持多个节点同时挂载和读写,即 RWX 访问模式。它适合共享模型目录、多节点同时读写 checkpoint;而块存储(如云盘)才是 RWO 语义。两类存储就像“公共文件柜”和“个人专属抽屉”,共享能力完全不同。

为何常见:初学者容易把“网络存储”和“块存储”混为一谈,看到 CSI 插件就认为与云盘等同。

误区本地盘性能好、延迟低,所以把模型数据都放在本地盘 PV 上是最佳选择。

正解本地盘没有跨节点冗余,数据只存在于单个节点上。一旦节点宕机、磁盘损坏或云服务器被回收,数据不可恢复。它适合放可重建的缓存数据,或配合上层备份机制使用;不能作为唯一的数据存储方案。就像你工位旁的抽屉虽然用着顺手,但公司不会把唯一的合同原件只锁在里面。

为何常见:本地盘性能优势太明显,性能测试中极致数字容易让人忽视可靠性短板。

面试题

Q1. PVC 请求 RWX 访问模式,意味着什么?

单选题 · easy

  • A.只有一个节点可以读写
  • B.多个节点可以同时读写← 正确答案
  • C.多个节点可以同时只读
  • D.只能由创建者挂载使用

答案:B。RWX 即 ReadWriteMany,对应“公共共享柜”,允许多个节点同时挂载并进行读写操作。RWO 才是单节点读写,ROX 是多节点只读。

Q2. 使用 emptyDir 卷的 Pod 被删除后,容器中写入的数据会怎样?

单选题 · easy

  • A.保留在节点磁盘上可复用
  • B.随 Pod 一起被系统清理← 正确答案
  • C.自动迁移到其他存储卷
  • D.自动生成快照备份保存

答案:B。emptyDir 的生命周期与 Pod 一致,Pod 被删除后系统会清空该卷,“便签纸”随之消失。这正是需要 PV/PVC 持久化存储的根本原因。

Q3. StorageClass 的核心作用是什么?

单选题 · easy

  • A.为容器动态分配 CPU 资源
  • B.根据 PVC 声明自动创建底层存储← 正确答案
  • C.管理 Kubernetes 集群的登录凭证
  • D.为容器分配固定的公网 IP

答案:B。StorageClass 定义了 storage provisioner 插件,当 PVC 被创建时根据参数自动调用后端存储创建 PV,即“自动定做柜子”的机制。

Q4. PVC 被删除后,PV 的最终去向取决于什么?

单选题 · mid

  • A.创建该 PV 时使用的节点
  • B.PV 上配置的回收策略← 正确答案
  • C.Pod 副本数的多少
  • D.PVC 所在命名空间的权限

答案:B。回收策略决定善后流程:Retain 保留 PV 等待管理员,Delete 同步删除 PV 与底层存储,Recycle 已废弃。与节点、副本数、权限均无关。

Q5. PVC 绑定 PV 需要满足哪些条件?

多选题 · mid

  • A.PV 容量不小于 PVC 请求容量← 正确答案
  • B.PV 支持 PVC 声明的访问模式← 正确答案
  • C.PVC 指定 StorageClass 时需与 PV 匹配← 正确答案
  • D.PVC 与 PV 必须位于同一命名空间

答案:ABC。PV 是集群级资源,不存在命名空间的概念,D 错误。容量、访问模式子集、StorageClass 匹配是绑定三大约束,缺一不可。

Q6. NFS 作为存储后端时,通常支持哪种访问模式?

单选题 · mid

  • A.仅支持单节点独占读写
  • B.支持多节点同时读写← 正确答案
  • C.仅支持多节点同时只读
  • D.不支持任何共享访问

答案:B。NFS 是网络文件系统,天然具备多客户端共享能力,支持 RWX 多节点同时读写,适合 AI 训练多 Pod 共享 checkpoint 目录的场景。

Q7. 关于静态供给与动态供给的区别,下列说法正确的是?

多选题 · mid

  • A.静态供给需要管理员预先创建 PV← 正确答案
  • B.动态供给通过 StorageClass 自动创建 PV← 正确答案
  • C.动态供给无需手动管理底层存储卷← 正确答案
  • D.静态供给不需要任何管理员介入

答案:ABC。静态供给需要管理员手动创建底层存储和 PV;动态供给只需定义 StorageClass,系统自动完成创建与绑定。静态供给与动态供给两者都需要管理员参与 initial 配置,D 错误。

Q8. 在节点上挂载本地盘作为 PV,最需要警惕的风险是什么?

单选题 · hard

  • A.本地盘无法设置任何访问模式
  • B.节点故障会导致数据永久丢失← 正确答案
  • C.本地盘不能配置删除回收策略
  • D.本地盘无法格式化写入数据

答案:B。本地盘没有跨节点冗余,节点宕机或磁盘损坏即数据丢失。本地盘可作为高速缓存,但不应作为唯一数据存储,必须搭配备份或上层容错机制。

Q9. AI 训练任务频繁保存 checkpoint,以下哪些存储实践是合理的?

多选题 · hard

  • A.挂载网络附加的共享存储卷← 正确答案
  • B.每个训练副本各自存本地盘
  • C.使用多副本的分布式存储系统← 正确答案
  • D.只在内存中保存临时快照

答案:AC。共享存储(NFS/Ceph)能让新 Pod 从任意节点恢复进度,分布式存储提供冗余与扩展性。B 方案数据分散且无冗余,D 方案断电或崩溃即丢失,都不可靠。

Q10. 关于 Recycle 回收策略,下列说法正确的是?

单选题 · extreme

  • A.是当前 Kubernetes 推荐的默认策略
  • B.会清理卷内数据后交还资源池复用← 正确答案
  • C.与 Retain 策略的执行效果完全相同
  • D.只适用于 Ceph 分布式存储后端

答案:B。Recycle 会执行卷内数据清理(类似 rm -rf),然后让 PV 回到可用池供后续 PVC 绑定。但它因安全性和效率问题已被官方废弃,推荐使用动态供给的 Delete 策略。